如果我理解正确,当reduce任务开始收集其输入shuffle块(来自不同map任务的输出)时,它首先将它们保存在内存中(Q1)。当执行器的shuffle-reserved内存量(在内存管理(Q2)更改之前)耗尽时,内存中数据被溢出"到磁盘。如果spark.shuffle.spill.compress为true,那么内存中的数据将以压缩方式写入磁盘。
我的问题:
问:问:我的理解是否正确?Q1:reduce任务中收集的数据是否始终未压缩?
Q2:如何估算可用于收集随机块的执行程序内存量?
问题3:我已经看到了声明"当您的数据集无法容纳在内存中时,会发生随机播放溢出"但是只要shuffle-reserved执行器内存大到足以包含所有内容所有ACTIVE任务的(未压缩的)shuffle输入块,那么不会发生溢出,这是正确的吗?
如果是这样,为了避免溢出,需要确保在所有并行的还原端任务中结束的(未压缩的)数据小于执行者的shuffle-reserved内存部分?
答案 0 :(得分:4)
1.6之前和之后的内存管理存在差异。在这两种情况下,都有执行内存和存储内存的概念。区别在于1.6之前它是静态的。意味着有一个配置参数指定执行和存储的内存量。当任何一个还不够时,就会发生泄漏。
Apache Spark解决方法的一个问题是并发执行:
我会说你的理解是正确的。
内存中的内容是未压缩的,否则无法处理。执行内存以块的形式溢出到磁盘,正如您所提到的那样可以压缩。
那么,从1.3.1开始你可以配置它,然后你知道它的大小。至于在任何时候剩下的东西,你可以通过jstat -gcutil <pid> <period>
之类的东西来看待执行者过程。它可能会让你知道那里有多少内存空闲。知道为存储和执行配置了多少内存,尽可能少default.parallelism
可能会给你一个线索。
这是真的,但很难推理;数据可能存在偏差,例如某些键具有比其他键更多的值,有许多并行执行等等。