如何在Apache Spark应用程序中优化shuffle溢出

Vij*_*uri 39 apache-spark spark-streaming apache-spark-1.4

我正在运行带有2名工作人员的Spark流应用程序.应用程序具有联接和联合操作.

所有批次都已成功完成,但注意到随机溢出指标与输入数据大小或输出数据大小不一致(溢出内存超过20次).

请在下图中找到火花阶段的详细信息: 在此输入图像描述

经过对此的研究,发现了

当没有足够的内存用于随机数据时,会发生随机溢出.

Shuffle spill (memory) - 溢出时内存中数据的反序列化形式的大小

shuffle spill (disk) - 溢出后磁盘上数据序列化形式的大小

由于反序列化数据比序列化数据占用更多空间.所以,Shuffle溢出(内存)更多.

注意到这个溢出内存大小非常大,输入数据很大.

我的疑问是:

这种溢出是否会对性能产生很大影响?

如何优化内存和磁盘的溢出?

是否有可以减少/控制这种巨大溢出的Spark Properties?

Ali*_*Lee 49

学习表演 - 调整Spark需要相当多的调查和学习.有一些很好的资源,包括这个视频.Spark 1.4在界面中有一些更好的诊断和可视化功能,可以帮助您.

总之,当阶段结束时RDD分区的大小超过可用于shuffle缓冲区的内存量时,会溢出.

您可以:

  1. 手动执行repartition()您的前一阶段,以便您从输入中获得较小的分区.
  2. 通过增加执行程序进程中的内存来增加shuffle缓冲区(spark.executor.memory)
  3. 通过增加spark.shuffle.memoryFraction从默认值0.2 分配给它()的执行程序内存的分数来增加shuffle缓冲区.你需要回馈spark.storage.memoryFraction.
  4. 通过减少worker threads(SPARK_WORKER_CORES)与执行程序内存的比率来增加每个线程的shuffle缓冲区

如果有专家倾听,我很想知道更多关于memoryFraction设置如何交互以及它们的合理范围.

  • @VenuAPositive我认为他建议重新分区更多分区而不是更少.如果他要减少分区,那么合并将是有意义的. (6认同)
  • 自 Spark 1.5 以来,spark.shuffle.memoryFraction 不再使用,除非您启用旧模式。请参阅:https://spark.apache.org/docs/latest/configuration.html (4认同)
  • 这个答案(虽然有用)并没有真正解决为什么洗牌溢出比洗牌读取大得多的问题。 (3认同)

Pra*_*lad 7

为了补充上述答案,您还可以考虑将分区的默认数量(spark.sql.shuffle.partitions)从 200(发生随机播放时)增加到一个数字,该数字将导致分区大小接近 hdfs 块大小(即 128mb 至 256mb)

如果您的数据存在偏差,请尝试使用诸如对键加盐之类的技巧来增加并行性。

阅读本文以了解 Spark 内存管理:

https://0x0fff.com/spark-memory-management/

https://www.tutorialdocs.com/article/spark-memory-management.html