Spark误差的解释与消除

5sxhfpxr  于 2021-05-27  发布在  Spark
关注(0)|答案(1)|浏览(494)

有时,会出现outofmemoryerror,这不是因为RDD不适合内存,而是因为某个任务的工作集(例如groupbykey中的某个reduce任务)太大。spark的shuffle操作(sortbykey、groupbykey、reducebykey、join等)在每个任务中构建一个哈希表来执行分组,这个哈希表通常可能很大。这里最简单的解决方法是提高并行度,这样每个任务的输入集就更小了。
我是这样想的,如果我错了,请纠正我。
假设有2个数据节点来处理数据集,这两个节点总共有32gb的内存(每个数据节点16GB)。数据集大小为100gb,假设spark读取的数据被划分为10个10gb的分区。很明显,100gb文件不能一次装入32gbram。因此分区必须加载到内存中,并以迭代的方式进行处理。所以我假设如下。
第一次迭代,将2个分区(每个分区10gb)加载到每个数据节点的内存中。第二次迭代,2个分区,每个10gb被加载到每个数据节点的内存中。。。。第五次迭代,将2个分区(每个分区10gb)加载到每个数据节点的内存中。
如果spark就是这样处理的,那么在每次迭代中,只有2个分区被加载到内存中。这是否意味着,无法容纳在内存中的其他分区已被读取,但已溢出到磁盘,它们正在等待释放内存?或者这些分区根本不被读取,当资源可用时它们将被只读。哪个是真的?
在处理过程中,如果需要groupby/reduceby/join,那么它将强制执行洗牌。因此,如果其中一个洗牌分区大于ram大小,那么作业将失败并出现oom错误。例如,10个分区被处理和洗牌。现在洗牌分区只有4个分区,每个分区25gb(默认洗牌分区是200,但只有4个分区有剩余的总数据是空的。)由于洗牌分区大小大于16mb ram,spark作业会失败吗?我的理解正确吗?
我明白,你并不真的需要你的数据适合内存。spark在分区的基础上处理数据。但我的问题是如果分区本身不适合内存怎么办。它仍然会将数据溢出到磁盘并开始处理,还是会因oom错误而失败?
我的第二个问题是,如果在执行上述spark job(job1)的过程中触发了另一个spark job(job2),并且假设这还有100gb的文件要处理,每个文件有10个10gb的分区。因此,在执行job1 iteration1时,内存中只有6MB的可用插槽。无法将作业2的10gb分区加载到内存中以处理作业2。那么job2会等到内存被释放吗?或者这项工作也会因为错误而失败吗?

u4dcyp6a

u4dcyp6a1#

这个解释(粗体)是正确的。
关于您的评论:
除非显式地重新分区,否则分区将与hdfs块大小、128mb大小以及构成该文件的大小相关。
然后每个worker/data节点有2个执行者。在任何给定的时间,最多有4个任务/分区处于活动状态。
如果您最多只能为4个分区提供服务,那么将所有分区加载到内存有什么意义?你会阻塞系统,损害其他spark应用程序。这就像一个普通的操作系统。
当然,它有点复杂,例如,如果您有10个数据节点,而分配只有2个执行器,那么就需要移动数据流。保持简单。
只有当分区超过最大分区大小时,才会发生oom错误。其余的磁盘空间需要溢出。

相关问题