Apache spark 有可能合并火花隔板吗;均匀地;?

Apache spark 有可能合并火花隔板吗;均匀地;?,apache-spark,pyspark,partitioning,Apache Spark,Pyspark,Partitioning,假设我们有一个PySpark数据帧,数据均匀分布在2048个分区上,我们希望合并到32个分区,将数据写回HDFS。使用coalesce很好,因为它不需要昂贵的洗牌 但是,coalesce的一个缺点是,它通常会导致数据在新分区之间分布不均匀。我假设这是因为原始分区ID被散列到新的分区ID空间,并且冲突的数量是随机的 但是,原则上应该可以均匀地合并,以便将原始数据帧的前64个分区发送到新数据帧的第一个分区,将下64个分区发送到第二个分区,然后结束,从而导致分区的均匀分布。生成的数据帧通常更适合于进一

假设我们有一个PySpark数据帧,数据均匀分布在2048个分区上,我们希望合并到32个分区,将数据写回HDFS。使用
coalesce
很好,因为它不需要昂贵的洗牌

但是,
coalesce
的一个缺点是,它通常会导致数据在新分区之间分布不均匀。我假设这是因为原始分区ID被散列到新的分区ID空间,并且冲突的数量是随机的

但是,原则上应该可以均匀地合并,以便将原始数据帧的前64个分区发送到新数据帧的第一个分区,将下64个分区发送到第二个分区,然后结束,从而导致分区的均匀分布。生成的数据帧通常更适合于进一步的计算

这是否可能,同时防止洗牌


我可以使用类似于中的技巧强制初始分区和最终分区之间的关系,但是Spark不知道从每个原始分区到特定的新分区的所有内容。因此,它无法优化洗牌,并且运行速度比coalesce慢得多。在您的情况下,您可以安全地将2048个分区合并为32个分区,并假设Spark将把上游分区平均分配给合并的分区(在您的情况下,每个分区64个)

这是:

这导致了一个狭隘的依赖关系,例如,如果从1000个分区到100个分区,则不会出现无序排列,而是100个新分区中的每一个都会占用当前分区中的10个

还要考虑分区在集群中的物理分布方式会影响合并的发生方式。以下内容摘自:

如果父级中没有位置信息(没有preferredLocations),则合并非常简单:在块中数组中靠近的块父级。 如果存在位置信息,则继续按照以下四个目标对其进行打包:

(1) 平衡这些组,使它们具有大致相同数量的父分区

(2) 实现每个分区的局部性,即找到大多数父分区更喜欢的一台机器

(3) 高效,即n个父分区的O(n)算法(问题可能是NP难的)

(4) 平衡首选机器,即尽可能避免选择相同的首选机器


感谢您编辑答案,并为误解感到抱歉。为什么您认为合并会使数据分布不均匀?如果当前的分区数是所需分区数的倍数,我希望每个新分区在合并分区的沿袭中具有偶数个上游分区。这对你有意义吗?无论如何,我都会检查代码。检查并添加了一个新的答案,您可以安全地合并,并且在保持均匀性的同时,可以安全地避免混乱。:)不幸的是,从经验上看,我的数据在分区之间的分布是均匀的,而在分区之间的分布是不均匀的。这些数字与post中的略有不同,但原始数据帧有768个分区,每个分区平均有294k记录,差异非常小。合并后的最终数据帧有48个分区——其中一些分区有来自13个原始分区的数据,另一些分区有来自19个原始分区的数据,记录的数量也有相应的变化。如果有关系的话,我使用的是PySpark,我的sparkContext.version报告的是2.2.0。听起来像是一个bug,记录的行为是不同的。我会为此开一张票。另外,分区如何分布在集群中?也许合并还考虑了分区的物理位置,并试图为此进行优化。我编辑了我的答案:似乎我的直觉可以为您指明正确的方向。检查分区在不同机器中的分布情况,位置信息可能会影响新分区如何从旧分区派生。非常感谢您的回答,但我不清楚如何进一步挖掘,因为我不知道如何找到分区的首选位置。我在这里问了一个问题:。