当Shuffle写入很大并且spark任务变得超慢时优化

时间:2017-10-09 18:18:21

标签: 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.version = 2.1.0
  • spark.executor.instances = 20
  • spark.executor.memory =6克
  • spark.yarn.executor.memoryOverhead =5克

1 个答案:

答案 0 :(得分:0)

您需要对数据进行分区以正确并行化作业,确保在Spark UI分区中正确分配数据。

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

  • 两个RDD都有一个已知的分区程序。

  • 其中一个数据集足够小以适应内存,在这种情况下我们可以进行广播散列连接

最简单的优化是,如果其中一个数据集足够小以适应内存,则应将其广播到每个计算节点。此用例非常常见,因为数据需要始终与边数据(如字典)结合使用。

由于网络上的数据过多,因此大多数联接都很慢。使用广播连接,较小的数据集将复制到所有工作节点,以便维护较大的DataFrame的原始并行性。

https://spark.apache.org/docs/latest/tuning.html