Apache spark Spark:洗牌写入、洗牌溢出(内存)、洗牌溢出(磁盘)之间的区别?

Apache spark Spark:洗牌写入、洗牌溢出(内存)、洗牌溢出(磁盘)之间的区别?,apache-spark,shuffle,rdd,persist,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) }.pers

我有以下的工作,试图把所有的东西都留在记忆中:

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)

然而,当我查看工作跟踪器时,我仍然有大量的随机写入和随机溢出到磁盘

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

然后作业失败,因为
“设备上没有剩余空间”
。。。我想知道这里的532.9GB随机写入是写入磁盘还是内存

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


谢谢

如果不多次访问RDD,代码中的
persist
调用将完全被浪费。如果你从未访问过某个东西,那么存储它又有什么意义呢?缓存对洗牌行为没有任何影响,只是可以通过缓存输出来避免重新洗牌

洗牌溢出由配置参数控制。如果启用了
溢出
(默认情况下),则如果洗牌文件开始使用超过
memoryFraction
(默认情况下为20%)给出的值,则洗牌文件将溢出到磁盘

这些指标非常混乱。我对的理解是,“Shuffle spill(memory)”是指在内容溢出到磁盘时释放的内存量。“洗牌溢出(磁盘)”的值看起来是实际写入磁盘的量。对于“随机写入”,我认为是直接写入磁盘的量,而不是从分拣机溢出的量。


Shuffle write是指在临时缓存位置写入本地文件系统的数据。在纱线簇模式下,您可以使用纱线-site.xml中的属性“纱线.节点管理器.本地目录”设置此属性。因此,“随机写入”是指写入临时位置的数据大小;“洗牌溢出”更可能是你洗牌阶段的结果。无论如何,这些数字是累积的。

关于如何防止洗牌溢出,还有一点需要注意,因为我认为这是性能方面问题中最重要的部分(如上所述,洗牌写入是洗牌的一个必要部分)

溢出发生在at shuffle读取时,任何reducer都无法将分配给它的所有记录放入该执行器的shuffle空间中的内存中。如果您的洗牌是不平衡的(例如,一些输出分区比一些输入分区大得多),那么即使在洗牌之前分区“适合内存”,也可能发生洗牌溢出。控制这种情况的最好方法是 A) 平衡洗牌。。。e、 g在洗牌之前或通过在不同的键上洗牌来更改代码以减少错误 或 B) 如上所述更改随机播放内存设置
考虑到溢出到磁盘的程度,您可能需要执行A而不是B。

我执行了“.flatMap{…}.persist(StorageLevel.MEMORY_ONLY)”操作,因为我希望洗牌保留在内存中。当我设置spark.shuffle.spill=false时,工作跟踪器中的shuffle spill(内存)和shuffle spill(磁盘)将消失,但我仍然有shuffle write。洗牌写得真大!有没有办法最小化“随机写入”的输出?谢谢我现在无法检查-也许你是对的,
persist
确实会影响随机播放输出的保留时间。我认为它们一直保存到RDD被垃圾回收为止。为了减小洗牌文件的大小,您可以使用Kryo(带注册),当然,在洗牌之前,您可以尝试使数据变小,例如通过过滤。