Spark SQL在资源空闲时执行缓慢

问题描述 投票:2回答:1

我有一个Spark SQL,用于执行<10分钟,现在在群集迁移后3小时运行,需要深入了解它实际执行的操作。我是新手,请不要介意我问一些无关的东西。

增加spark.executor.memory但没有运气。

环境:Azure存储上的Azure HDInsight Spark 2.4

SQL:读取并加入一些数据,最后将结果写入Hive Metastore。

spark.sql脚本以下面的代码结尾:.write.mode("overwrite").saveAsTable("default.mikemiketable")

应用行为:在前15分钟内,它加载并完成大多数任务(199/200);只剩下1个执行程序进程,并且不断地重新读取/写入数据。因为现在它只留下1个执行者,我们需要等待3个小时才能完成此应用程序。 enter image description here

留下只有1个执行者活着enter image description here

不确定遗嘱执行人在做什么:enter image description here

不时,我们可以告诉shuffle阅读增加:enter image description here

因此我将spark.executor.memory增加到20g,但没有任何改变。从Ambari和YARN我可以看出群集还剩下很多资源。 enter image description here

释放几乎所有遗嘱执行人enter image description here

非常感谢任何指导。

apache-spark pyspark-sql hdinsight
1个回答
0
投票

我想从你的案例的一些观察开始:

  1. 从任务列表中可以看到Shuffle Spill(磁盘)和Shuffle Spill(Memory)具有非常高的值。在交换数据should not exceed 2GB期间每个分区的最大块大小因此您应该知道将混洗数据的大小保持尽可能低。根据经验,你需要记住每个分区的大小应该是~200-500MB。例如,如果总数据为100GB,则需要至少250-500个分区才能使分区大小保持在上述限制范围内。
  2. 之前两个共存它也意味着执行程序内存不足,并且Spark被迫将数据溢出到磁盘。
  3. 任务的持续时间太长。一个normal task应该持续50-200ms。
  4. 太多杀死执行者是另一个迹象,表明你正面临着OOM问题。
  5. Locality是RACK_LOCAL,它被认为是集群中可以实现的最低值之一。简而言之,这意味着任务正在与存储数据不同的节点中执行。

作为解决方案,我会尝试接下来的几件事:

  • 使用repartition()或使用spark.sql.shuffle.partitions的Spark设置增加分区数,使其符合上述要求,即1000或更多。
  • 更改存储数据的方式并使用partitionBy引入分区数据,即日/月/年
© www.soinside.com 2019 - 2024. All rights reserved.