【问题标题】:How spark distributes partitions to executorsspark如何将分区分配给执行者
【发布时间】:2021-07-11 22:46:51
【问题描述】:

我遇到了性能问题,在分析 Spark Web UI 后,我发现它似乎是数据偏斜:

最初我认为分区不是均匀分布的,所以我对每个分区的行数进行了分析,但看起来很正常(没有异常值): how to manually run pyspark's partitioning function for debugging

但问题仍然存在,我看到有一个执行程序处理大部分数据:

所以现在的假设是分区不是均匀分布在执行者之间,问题是:spark如何将分区分配给执行者?我怎样才能改变它解决我的偏斜问题?

代码很简单:

hive_query = """SELECT ... FROM <multiple joined hive tables>"""
df = sqlContext.sql(hive_query).cache()
print(df.count())

更新 发布此问题后,我进行了进一步分析,发现有 3 个表导致此问题,如果将它们删除,则数据均匀分布在执行器中并且性能提高,所以我添加了 spark sql hint /*+ BROADCASTJOIN() */ 成功了,现在性能好多了,但问题仍然存在:

为什么这个表(包括一个小的 6 行表)在添加到查询时会导致执行器之间的这种不均匀分布?

【问题讨论】:

  • 您能分享一个您尝试执行的代码示例吗?似乎只创建了 4 个分区,而您想要更多,因此可以更均匀地分配工作负载。
  • 您确实需要发布截屏时正在运行的代码,以便人们帮助回答您的问题。

标签: python apache-spark pyspark


【解决方案1】:

repartition() 不会让您均匀分布数据集,因为 Spark 内部使用 HashPartitioner。要将您的数据均匀地放在所有分区中,那么在我看来,自定义分区器是一种方式。

在这种情况下,您需要扩展org.apache.spark.Partitioner 类并使用您自己的逻辑而不是HashPartition。为此,我们需要将RDD 转换为PairRDD

在下面的博客文章中找到,这将对您的情况有所帮助: https://blog.clairvoyantsoft.com/custom-partitioning-spark-datasets-25cbd4e2d818

谢谢

【讨论】:

    【解决方案2】:

    当您从 HDFS 读取数据时,分区数取决于您正在读取的块数。从附加的图像来看,您的数据似乎没有在集群中均匀分布。尝试重新分区您的数据并增加调整核心和执行程序的数量。

    如果您要对数据进行重新分区,散列分区器会返回一个比其他值更常见的值,这会导致数据倾斜。

    如果这是在执行连接之后,那么您的数据是倾斜的。

    【讨论】:

    • 确实,是在执行连接后,我确定了连接中的表导致了这种情况,是否可以通过火花代码解决?还是使用 hdfs 平衡器来解决该表的问题?
    • 结帐广播加入和密钥加盐。这两种技术可以解决数据偏斜问题。
    猜你喜欢
    • 1970-01-01
    • 2019-07-19
    • 1970-01-01
    • 2014-06-25
    • 2017-04-21
    • 2020-02-05
    • 1970-01-01
    • 2017-02-10
    • 1970-01-01
    相关资源
    最近更新 更多