由于内存不足,Spark Join 失败
Spark Join failed due to Out-Of-Memory
我的集群:
9 个从机,每个从机具有 100GB 内存和 320GB 硬盘驱动器。每个主机有 16 个核心。我在每台主机上启动了 15 个 spark 执行器,因此每个执行器的可用内存为 6GB。
我的申请:
val rdd1 = sc.textFile("a big file in S3. about 200GB" with 14M rows)
val rdd2 = sc.textFile("another big file in S3. about 200GB" with 14M rows)
val par = new HashPartitioner(150)
val rdd1Paired = rdd1.map(regular expression to get one string from each row).filter(non matched rows).partitionBy(par)
val rdd2Paired = rdd2.mpa(regular expression to get one string from each row).filter(non matched rows).partitionBy(par)
val rdd3 = rdd1.join(rdd2, par)
rdd3.count()
我从 spark UI 中得知该作业分三个阶段安排。过滤rdd1,过滤rdd2,计数。虽然 filtering1 和 filtering2 成功但计数总是由于 OOM 而失败。奇怪的是,工作总是挂在计数阶段 (149/150)。我检查了分配了 TID150 的执行程序,发现 Shuffle 读取显着增加。由于OOM,它在一段时间后崩溃了。我还看到 GC 在该执行程序上经常发生。
这里有问题:
为什么只有一个执行者正在获取所有数据(我检查了执行者正在做的最后一个操作是开始获取工作)?据我了解,一旦我对两个 RDD 使用相同的分区程序,它们将被共同分区。并在同一作业中启动它们可确保数据的协同定位。所以加入应该发生在每个执行者身上。前 149 个任务很快退出,似乎什么也没做。看起来最后一个任务正在尝试所有工作。
我猜你从数据中生成的键的分布是倾斜的,所以很多键最终都在同一个分区中。
事实上它是最后一个失败的任务,因为它是最大的,所以它执行的时间最长,因此成为最后一个。
要解决这个问题,请增加分区数量 and/or 加强您的服务器
按键分布不均匀。检查以确保 none 您的过滤器功能具有导致某些键更加集中的附带效果。
我的集群: 9 个从机,每个从机具有 100GB 内存和 320GB 硬盘驱动器。每个主机有 16 个核心。我在每台主机上启动了 15 个 spark 执行器,因此每个执行器的可用内存为 6GB。 我的申请:
val rdd1 = sc.textFile("a big file in S3. about 200GB" with 14M rows)
val rdd2 = sc.textFile("another big file in S3. about 200GB" with 14M rows)
val par = new HashPartitioner(150)
val rdd1Paired = rdd1.map(regular expression to get one string from each row).filter(non matched rows).partitionBy(par)
val rdd2Paired = rdd2.mpa(regular expression to get one string from each row).filter(non matched rows).partitionBy(par)
val rdd3 = rdd1.join(rdd2, par)
rdd3.count()
我从 spark UI 中得知该作业分三个阶段安排。过滤rdd1,过滤rdd2,计数。虽然 filtering1 和 filtering2 成功但计数总是由于 OOM 而失败。奇怪的是,工作总是挂在计数阶段 (149/150)。我检查了分配了 TID150 的执行程序,发现 Shuffle 读取显着增加。由于OOM,它在一段时间后崩溃了。我还看到 GC 在该执行程序上经常发生。
这里有问题: 为什么只有一个执行者正在获取所有数据(我检查了执行者正在做的最后一个操作是开始获取工作)?据我了解,一旦我对两个 RDD 使用相同的分区程序,它们将被共同分区。并在同一作业中启动它们可确保数据的协同定位。所以加入应该发生在每个执行者身上。前 149 个任务很快退出,似乎什么也没做。看起来最后一个任务正在尝试所有工作。
我猜你从数据中生成的键的分布是倾斜的,所以很多键最终都在同一个分区中。
事实上它是最后一个失败的任务,因为它是最大的,所以它执行的时间最长,因此成为最后一个。
要解决这个问题,请增加分区数量 and/or 加强您的服务器
按键分布不均匀。检查以确保 none 您的过滤器功能具有导致某些键更加集中的附带效果。