【发布时间】:2021-09-24 19:36:16
【问题描述】:
我看到很多答案和 blob 帖子表明:
df.repartition('category').write().partitionBy('category')
将为每个类别输出一个文件,但如果 df 中唯一“类别”值的数量小于默认分区的数量(通常为 200),则这似乎不是真的。
当我在具有 100 个类别的文件上使用上述代码时,我最终会得到 100 个文件夹,每个文件夹包含 1 到 3 个“部分”文件,而不是在同一个“部分”中包含具有给定“类别”值的所有行”。 https://stackoverflow.com/a/42780452/529618 的答案似乎可以解释这一点。
每个分区值只获取一个文件的最快方法是什么?
我尝试过的事情
我见过很多这样的说法
df.repartition(1, 'category').write().partitionBy('category')
df.repartition(2, 'category').write().partitionBy('category')
将分别创建“每个类别恰好一个文件”和“每个类别恰好两个文件”,但这似乎不是此参数的工作方式。 documentation 清楚地表明numPartitions 参数是要创建的分区总数,而不是每列值的分区数。根据该文档,将此参数指定为 1 应该(意外地)在写入文件时为每个分区输出一个文件,但可能只是因为它删除了所有并行性并强制您的整个 RDD 在单个节点上进行混洗/重新计算。
required_partitions = df.select('category').distinct().count()
df.repartition(required_partitions, 'category').write().partitionBy('category')
以上似乎是一种基于记录行为的解决方法,但由于多种原因,这种方法代价高昂。一方面,如果 df 昂贵且未缓存(和/或太大以至于仅为此目的缓存将是浪费的),则单独计数,并且数据帧的任何重新分区都可能导致多阶段工作流程中不必要的改组一路上有各种数据帧输出。
【问题讨论】:
标签: apache-spark pyspark partitioning