Apache spark 了解spark中巨大的洗牌溢出大小

Apache spark 了解spark中巨大的洗牌溢出大小,apache-spark,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)) 我有一个3亿行的sql数据帧 我将其转换为RDD,然后将其持久化:存储选项卡指示其为3GB 我做群比

使用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))
  • 我有一个3亿行的sql数据帧
  • 我将其转换为RDD,然后将其持久化:存储选项卡指示其为3GB
  • 我做群比。我的一个关键是减少100万个项目,因此如果按RDD大小计算,大约1GB
  • 我将洗牌后的每个项目映射到一个case类。这个case类只有2个“double”字段
  • 我将包含分区所有数据的完整迭代器发送给处理该流的函数
我观察到,处理100米案例类的任务在处理1小时以上后总是失败。在UI中的“执行者聚合度量”选项卡中,我看到“随机溢出”列的巨大值,约为10GB,比完整RDD的大小大3倍。。 当我对慢速执行器执行线程转储时,它似乎陷入了磁盘写/读操作

谁能告诉我发生了什么事?我知道100万个案例类实例可能太大,无法放入单个执行器的RAM中,但我不明白以下几点:

1) Spark不是应该将所有实例“流”到我的
func
函数中吗?为什么它试图在接收executor节点时存储所有内容

2) 记忆爆炸是从哪里来的?我不明白为什么序列化100M case类实例需要大约10GB,即每项大约100字节(假设溢出到磁盘的数据是case类实例,我无法确定数据溢出的位置)