考虑一个示例:
我有一个包含5个节点的群集,每个节点具有64个核心,并具有244 GB内存。
我决定在每个节点上运行3个执行程序,并将执行程序核心数设置为21,执行程序内存为80GB,以便每个执行程序可以并行执行21个任务。现在考虑315(63 * 5)个数据分区,其中314个分区的大小为3GB,但其中一个分区为30GB(由于数据偏斜)。
接收到3GB分区的所有执行器都具有63GB(21 * 3 =,因为每个执行器可以并行运行21个任务,每个任务占用3GB的内存空间)。
但是接收到30GB分区的一位执行者将需要90GB(20 * 3 + 30)内存。那么,这个执行器会先执行20个3GB的任务,然后再加载30GB的任务,还是只是尝试加载21个任务并发现它不得不溢出到磁盘上呢?如果我将executor-cores设置为15,那么接收30 GB分区的executor将只需要14 * 3 + 30 = 72 gb,因此不会溢出到磁盘上。
那么在这种情况下,并行度的降低是否会导致无随机播放溢出?
答案 0 :(得分:0)
@Venkat Dabri,
您能用合适的回车/空格格式化问题吗?
这里有几个指针
Spark(随机播放)映射阶段 ==>每个分区的大小取决于文件系统的块大小。例如。如果从HDFS读取数据,则每个分区将尝试使数据接近 128MB ,因此对于输入数据,分区数=楼层(文件数*块大小/ 128(实际上是122.07,因为使用兆字节) )
现在您描述的场景是针对Reducer中的随机数据(结果阶段)
在这里,由reducer任务处理的 block 被称为 Shuffled Blocks ,默认情况下,Spark(用于SQL / Core API)将启动 200 reducer任务
现在要记住的重要事情是,Spark可以容纳最大 2GB ,因此,如果您的分区很少,而其中一个分区可以进行远程抓取一个大于2GB的随机播放块,您会看到类似Size exceeds Integer.MAX_VALUE
为缓解这种情况,Spark在默认限制内采用了许多优化措施(压缩/钨-排序-随机播放等),但作为开发人员,我们可以尝试智能地重新分区偏斜数据并调整默认并行度