Spark:Shuffle Write,Shuffle spill(内存),Shuffle spill(磁盘)之间的区别?

时间:2015-08-25 17:05:58

标签: apache-spark shuffle rdd persist

我有以下火花工作,试图将所有内容保存在记忆中:

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 Shuffle write ,是写入磁盘还是内存?

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

谢谢!

4 个答案:

答案 0 :(得分:10)

随机播放(内存)是我们溢出时内存中数据的反序列化形式的大小,而随机播放(磁盘)是我们溢出后磁盘上数据序列化形式的大小。这就是后者往往比前者小得多的原因。请注意,两个指标都是在整个任务期间聚合的(即在每个任务中可以多次溢出)。

答案 1 :(得分:8)

如果您多次访问RDD,代码中的persist次调用将完全被浪费掉。如果你从未访问它,存储的东西有什么意义?缓存与洗牌行为无关,除了可以通过保持其输出缓存来避免重新进行洗牌。

随机播放由spark.shuffle.spill and spark.shuffle.memoryFraction配置参数控制。如果启用了spill(默认情况下是这样),则如果shuffle文件的使用时间超过memoryFraction(默认为20%),则会将其溢出到磁盘。

指标非常混乱。我对code的解读是“Shuffle spill(memory)”是当事物溢出到磁盘时释放的内存量。 “Shuffle spill(disk)”code看起来就像是实际写入磁盘的数量。通过code for “Shuffle write”我认为这是直接写入磁盘的数量 - 而不是分拣机的溢出。

答案 2 :(得分:4)

关于如何防止随机泄漏的另一个注意事项,因为我认为这是性能方面问题中最重要的部分(如上所述,随机写入是改组的必要部分)。

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

答案 3 :(得分:1)

shuffle data

随机写入表示已在临时缓存位置写入本地文件系统的数据。在纱线群集模式下,您可以在yarn-site.xml中使用属性“yarn.nodemanager.local-dirs”设置此属性。因此,“随机写入”表示您已写入临时位置的数据大小; “Shuffle spill”更有可能是你的洗牌阶段结果。无论如何,这些数字是积累的。