Spark:随机写入、随机溢出(内存)、随机溢出(磁盘)之间的区别?

Posted

技术标签:

【中文标题】Spark:随机写入、随机溢出(内存)、随机溢出(磁盘)之间的区别?【英文标题】:Spark: Difference between Shuffle Write, Shuffle spill (memory), Shuffle spill (disk)? 【发布时间】:2015-11-19 12:17:44 【问题描述】:

我有以下 spark 工作,试图将所有内容都保存在内存中:

val myOutRDD = myInRDD.flatMap  fp =>
  val tuple2List: ListBuffer[(String, myClass)] = ListBuffer()
        :

  tuple2List
.persist(StorageLevel.MEMORY_ONLY).reduceByKey  (p1, p2) =>
   myMergeFunction(p1,p2)
.persist(StorageLevel.MEMORY_ONLY)

但是,当我查看作业跟踪器时,我仍然有很多 Shuffle Write 和 Shuffle 溢出到磁盘......

Total task time across all tasks: 49.1 h
Input Size / Records: 21.6 GB / 102123058
Shuffle write: 532.9 GB / 182440290
Shuffle spill (memory): 370.7 GB
Shuffle spill (disk): 15.4 GB

然后作业失败了,因为"no space left on device" ...我想知道这里的 532.9 GB 随机写入,它是写入磁盘还是内存?

另外,为什么还有15.4G的数据溢出到磁盘,而我特意要求将它们保留在内存中?

谢谢!

【问题讨论】:

【参考方案1】:

如果您不多次访问 RDD,代码中的 persist 调用将完全被浪费。如果您从不访问它,那么存储它有什么意义?缓存与 shuffle 行为无关,但您可以通过保持输出缓存来避免重新执行 shuffle。

Shuffle 溢出由spark.shuffle.spill and spark.shuffle.memoryFraction 配置参数控制。如果启用了spill(默认情况下),那么如果随机文件开始使用超过memoryFraction(默认情况下为20%)给出的值,它们将溢出到磁盘。

指标非常混乱。我对code 的解读是,“随机溢出(内存)” 是在溢出到磁盘时释放的内存量。 “随机溢出(磁盘)” 的code 看起来像是实际写入磁盘的数量。 code 表示 “随机写入”,我认为这是直接写入磁盘的数量——而不是从排序器溢出。

【讨论】:

我做了 ".flatMap....persist(StorageLevel.MEMORY_ONLY)" 因为我希望随机播放留在内存中。当我设置 spark.shuffle.spill = false 时,随机溢出(内存)和随机溢出(磁盘)从作业跟踪器中消失,但我仍然有随机写入。 shuffle write 真的很大!有没有办法最小化“随机写入”的输出?谢谢! 我现在无法检查——也许你是对的,persist 确实会影响随机输出的保留时间。我认为它们会一直保留到 RDD 被垃圾回收为止。要减少 shuffle 文件的大小,您可以使用 Kryo(带有注册),当然还要尝试在 shuffle 之前使数据更小,例如通过过滤。【参考方案2】:

shuffle data

随机写入是指那些已写入本地文件系统的临时缓存位置的数据。在 yarn 集群模式下,您可以在 yarn-site.xml 中使用属性“yarn.nodemanager.local-dirs”设置此属性。因此,“随机写入”是指您写入临时位置的数据大小; “洗牌溢出”更有可能是你的洗牌阶段结果。反正这些数字是积累起来的。

【讨论】:

【参考方案3】:

关于如何防止 shuffle 溢出的另一个注意事项,因为我认为从性能方面来看这是问题中最重要的部分(如上所述,shuffle write 是 shuffle 的必需部分)。

当 at shuffle 读取时会发生溢出,任何 reducer 都无法将分配给它的所有记录放入该执行程序的 shuffle 空间中的内存中。如果您的 shuffle 不平衡(例如,某些输出分区比某些输入分区大得多),即使分区在 shuffle 之前“适合内存”,您也可能会出现 shuffle 溢出。控制这种情况的最佳方法是 A)平衡洗牌......例如,在洗牌之前改变你的代码以减少或通过在不同的键上洗牌 要么 B)按照上面的建议更改随机播放内存设置 鉴于溢出到磁盘的程度,您可能需要执行 A 而不是 B。

【讨论】:

以上是关于Spark:随机写入、随机溢出(内存)、随机溢出(磁盘)之间的区别?的主要内容,如果未能解决你的问题,请参考以下文章

在一个范围内生成一个随机数。无溢出。在 Java 中

20165337缓冲区溢出漏洞实验

20165303缓冲区溢出漏洞实验 博客

ODBC 调用失败 - 从 32 位 ODBC 5.1 移动到 64 位 5.3 后出现随机日期溢出错误

2018-2019-1 20165322《信息安全系统设计基础》缓冲区溢出漏洞实验

随机内存写入比随机内存读取慢?