了解火花中巨大的洗牌溢出量

时间:2018-12-04 22:45:17

标签: apache-spark

在Spark 2.3中,我正在运行以下代码:

rdd
.persist(DISK_ONLY) // this is 3GB according to storage tab
.groupBy(_.key)
.mapValues(iter => iter.map(x => CaseClass(x._1, x._2)))
.mapValues(iter => func(iter))
  • 我有一个300M行的sql数据框
  • 我将其转换为RDD,然后将其保留:存储标签表明它为3GB
  • 我分组。我的关键之一是要接收1亿个项目,如果按RDD大小计算,则大约为1GB
  • 我将洗牌后的每个项目映射到一个案例类。这个案例类别只有2个“ double”字段
  • 我要将包含分区所有数据的完整迭代器发送到将处理此流的函数

我观察到的是,处理100M案例类的任务总是在处理1h +之后失败。在用户界面的“按执行者汇总的指标”标签中,我看到“随机溢出”列的巨大值,大约10 GB,是完整RDD大小的3倍。。 当我执行慢速执行程序的线程转储时,它似乎卡在了对磁盘操作的写入/读取中。

有人可以告诉我怎么回事吗?我了解100M的案例类实例可能太大而无法容纳单个执行者的RAM,但我不理解以下内容:

1)Spark不应该将所有实例“流式传输”到我的func函数中吗?为什么要尝试在接收执行程序节点时存储所有内容?

2)内存爆炸从何而来?我不明白为什么序列化1亿个案例类实例应该占用10GB左右的空间,每项大约100个字节(假设泄漏到磁盘上的数据是CaseClass实例,我不确定从该点开始数据洒了)

0 个答案:

没有答案