如何确定Spark应用程序的shuffle分区?

3

我对Spark比较陌生,所以我在遵循sparkbyexamples.com上的这篇精彩教程时,发现了以下部分:

Shuffle分区大小和性能

根据您的数据集大小、核心数和内存使用情况,PySpark的洗牌操作可能会对作业产生利益或损害。当您处理少量数据时,通常应该减少shuffle分区的数量,否则您将得到许多分区文件,每个分区中的记录数量较少,这会导致运行许多任务来处理较少的数据。

另一方面,当您有过多的数据并且分区数量较少时,会导致任务执行时间较长,有时还可能出现内存错误。

确定适当的shuffle分区大小总是棘手的,需要使用不同的值进行多次运行以实现优化的数量。当您在PySpark作业中遇到性能问题时,这是要查看的关键属性之一。

有人可以帮我理解如何确定作业所需的shuffle分区数量吗?

1个回答

3
正如你所引用的,这很棘手,但这是我的策略:
如果你使用“静态分配”,也就是告诉Spark你想为作业分配多少执行器,那么就很容易计算分区数目,分区数=执行器数×每个执行器的内核数×因子。其中,因子 = 1表示每个执行器将处理1个作业,因子 = 2表示每个执行器将处理2个作业,以此类推。
如果你使用“动态分配”,那么情况就更加复杂了。你可以在这里阅读详细的描述:https://databricks.com/blog/2021/03/17/advertising-fraud-detection-at-scale-at-t-mobile.html。总体思路是需要回答许多问题,比如你的数据有多大(以吉字节为单位),其结构是什么样的(有多少个文件,多少个文件夹,多少行等等),你会从哪里读取它(从HDFS、Hive还是JDBC),你有多少资源可用(内核、执行器、内存)等等。然后你需要反复运行和基准测试,找到适合你情况的最佳点。
更新#1:
一般行业做法是,公司会简单地使用第一个策略并分配更多的硬件,还是会使用动态分配?
通常,如果你有一个本地Hadoop环境,可以在静态(默认模式)和动态分配(高级模式)之间选择。此外,通常我会从动态开始,因为我不知道数据及其转换的规模有多大,所以坚持使用动态分配可以为我提供灵活性,扩展我的工作而无需过多考虑Spark配置。但是如果你愿意,也可以从静态开始。最终,在生产过程中,你也可以在静态(非常稳定但消耗更多资源)和动态(不太稳定,即由于资源分配失败而有时失败,但可以节省资源)之间进行选择。
最后,大多数Hadoop云解决方案(如Databricks)默认使用动态分配,这样成本较低。

谢谢您的回答。那么,一般行业惯例是什么,公司会简单地使用第一种策略并分配更多硬件,还是他们会使用动态分配?此外,当您说“工作”时,这实际上意味着什么?像一个完整的项目还是其中的一部分块? - axiomatic
我所说的“job”是指Spark作业,它可以是完整的项目,也可以是项目的一部分或ETL管道的一部分。 - pltc
通常情况下,如果您拥有一个本地 Hadoop 环境,您可以在静态模式(默认模式)和动态分配(高级模式)之间进行选择。此外,我经常从动态开始,因为我不知道数据及其转换的大小,所以坚持使用动态模式可以让我灵活扩展我的工作,而不必过多考虑 Spark 配置。但是,如果您愿意,您也可以从静态开始,没有任何阻止您这样做的东西。 - pltc
最终,当进入生产过程时,您也可以在静态(非常稳定但消耗更多资源)和动态(不太稳定,即由于资源分配而有时会失败,但节省资源)之间进行选择。 - pltc
最后,大多数Hadoop云解决方案(如Databricks)默认情况下都带有动态分配功能,这是成本较低的。 - pltc

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接