Hadoop 洗牌写入较大且spark任务超慢时的优化

Hadoop 洗牌写入较大且spark任务超慢时的优化,hadoop,apache-spark,hive,Hadoop,Apache Spark,Hive,有一个SparkSQL,它将连接4个大表(前3个表为5000万,最后一个表为2亿),并执行一些分组操作,这将消耗60天的数据。这个SQL需要2个小时才能运行,在此期间,我检查了Shuffle Write正在急剧增加,可能会超过200GB 相比之下,当我将消费日期从60天减少到45天时,只需6.3分钟即可运行。我查看了DAG图,对于45天的数据,它在最后一次sortMergeJoin之后输出了10亿个数据 有谁能告诉我优化这个场景的方向吗?谢谢 p.S. 可能的相关信息: Spark.versi

有一个SparkSQL,它将连接4个大表(前3个表为5000万,最后一个表为2亿),并执行一些分组操作,这将消耗60天的数据。这个SQL需要2个小时才能运行,在此期间,我检查了
Shuffle Write
正在急剧增加,可能会超过200GB

相比之下,当我将消费日期从60天减少到45天时,只需6.3分钟即可运行。我查看了DAG图,对于45天的数据,它在最后一次sortMergeJoin之后输出了10亿个数据

有谁能告诉我优化这个场景的方向吗?谢谢

p.S.

可能的相关信息:

  • Spark.version=2.1.0
  • spark.executor.instances=20
  • spark.executor.memory=6g
  • 火花、纱线、执行器、存储器磁头=5g

您需要对数据进行分区以正确并行作业,确保Spark UI分区中的数据分布正确

Spark中联接的默认实现是无序散列联接。无序散列联接通过使用与第一个数据集相同的默认分区器对第二个数据集进行分区,确保每个分区上的数据将包含相同的键,从而使来自两个数据集的具有相同散列值的键位于同一分区中。虽然这种方法总是有效的,但它可能比必要的成本更高,因为它需要一次洗牌。如果出现以下情况,则可以避免混洗:

  • 两个RDD都有一个已知的分区器

  • 其中一个数据集足够小,可以放入内存中,在这种情况下,我们可以进行广播哈希连接

最简单的优化是,如果其中一个数据集足够小,可以放入内存,那么它应该广播到每个计算节点。这个用例非常常见,因为数据需要始终与辅助数据(如字典)相结合

由于在网络上洗牌的数据太多,大部分连接都很慢。通过广播联接,较小的数据集被复制到所有工作节点,从而保持较大数据帧的原始并行性


嘿,伙计,谢谢你的详细回答。实际上,所有前3个表都有分区(60天分区大小为5000万),而最后一个表(60天大小为2亿)没有分区支持。还有一些小表格,我可以从DAG图中看到,它们是
BroadCastJoin
,正如预期的那样。但是,在计算期间,这些大表上有多个(6/7)
SortMergeJoin
。这就是现象。还有什么建议吗?您使用的是什么类型的分区?在
day=yyyy-MM-dd
上分区,所以我只检索最近60天的数据,总共有5000万个数据。请检查您是否使用groupBy键,以避免ReduceKey等其他性能问题。我正在编写SparkSQL,所以它应该在默认情况下优化这个。