apache-spark - Spark 如何处理部分缓存/持久化结果?
问题描述
如果您缓存一个无法全部存储在内存或磁盘中的非常大的数据集,Spark 如何处理部分缓存?当您再次使用该数据框时,它如何知道需要重新计算哪些数据?
例子:
- 将 100 GB 数据集读入内存
df1
df2
基于计算新的数据帧df1
- 缓存
df2
如果 spark 只能容纳 50GB 的缓存,df2
那么如果您要重用df2
后续步骤会发生什么?spark如何知道哪些数据不需要重新计算,哪些需要重新计算?它是否需要再次重新读取无法持久的数据?
更新
如果您有 5GB 内存和 5GB 磁盘并尝试缓存 20GB 数据集会怎样?无法缓存的其他 10GB 数据会发生什么情况,Spark 如何知道哪些数据需要重新计算,哪些不需要?
解决方案
Spark为 DF 和 DS提供了这个默认选项:
MEMORY_AND_DISK – 这是 DataFrame 或 Dataset 的默认行为。在这个 Storage Level 中,DataFrame 将作为反序列化对象存储在 JVM 内存中。当所需存储空间大于可用内存时,它将一些多余的分区存储到本地磁盘中,并在需要时从本地磁盘读取数据。由于涉及 I/O,因此速度较慢。
但是,更具体地说:
Spark 的处理单元是一个 partition = 1 个任务。所以讨论更多的是关于适合内存和/或本地磁盘的分区。
如果在使用 StorageLevel.MEMORY_AND_DISK 时 DF 的一个分区不适合内存和磁盘,那么操作系统将失败,也就是杀死 Executor / Worker。可能会驱逐除您自己的 DF 之外的其他分区,但不会针对您自己的 DF。无论成功与否,在这种
.cache
情况下都没有重读。我基于这样一个事实,即属于同一底层 RDD 的分区不会发生分区驱逐。没有很好地解释所有这些东西,但请参阅此处:Spark 如何驱逐缓存的分区?. 最后,其他 RDD 分区可能会被驱逐并重新计算,但最后你还需要足够的本地磁盘和内存。
一个很好的阅读是:https ://sparkbyexamples.com/spark/spark-difference-between-cache-and-persist/
推荐阅读
- sql-server - Invoke-SqlServerQuery 使用错误的域和用户名
- javascript - Redux 使用扩展存储形状
- java - 只异步运行一个方法10秒android
- react-native - 在反应原生类函数中处理这个关键字
- r - 从格式为 JSON 的 csv 列中提取信息
- r - 在 For 循环中使用 quantmod 函数 getSymbols 时下载失败
- vb.net - 标签不包含位置属性
- ios - 使用 NSLayoutAnchor 不好吗?
- python - 使用映射创建新的 ElasticSearch 索引
- android - 弹出片段后,所有 Editexts 都将替换为相同的值