首页 > 解决方案 > reduceByKey 的分区方面

问题描述

尽管 RDD 是遗留问题 - 并且在下一次分配之前还有一点时间 - 我想知道:

对我来说不是那么明显。在实际情况下,我怀疑它不经常使用,通常已经重新分区(基于我自己的观察)。

标签: apache-spark

解决方案


根据RDD 编程指南

reduceByKey(func, [numPartitions]):在 (K, V) 对的数据集上调用时,返回 (K, V) 对的数据集,其中每个键的值使用给定的 reduce 函数 func 聚合,必须是(V,V) => V 类型。就像在 groupByKey 中一样,reduce 任务的数量可以通过可选的第二个参数进行配置。

所以第二个参数控制并行化的数量,类似于groupByKey

groupByKey([numPartitions]):在 (K, V) 对的数据集上调用时,返回 (K, Iterable) 对的数据集。注意:如果您正在分组以便对每个键执行聚合(例如求和或平均),则使用 reduceByKey 或 aggregateByKey 将产生更好的性能。注意:默认情况下,输出中的并行度取决于父 RDD 的分区数。您可以传递一个可选的 numPartitions 参数来设置不同数量的任务。

引用如何在 Apache Spark 中决定 RDD 分区的数量?| 服务器故障

这个数字是如何确定的?上一篇文章中描述了 Spark 将 RDD 分组为阶段的方式。(快速提醒一下,像 repartition 和 reduceByKey 这样的转换会导致阶段边界。)阶段中的任务数与阶段中最后一个 RDD 中的分区数相同。RDD 中的分区数与其所依赖的 RDD 中的分区数相同,但有几个例外:coalesce 转换允许创建一个分区数少于其父 RDD 的 RDD,union 转换创建一个具有其父母的分区数的总和,笛卡尔用他们的产品创建一个RDD。

问题更新后

来自:优化 Spark 作业以获得最佳性能(强调我的)

[..]分区特征经常在洗牌边界上发生变化。 因此,暗示 shuffle 的操作提供了一个 numPartitions 参数来指定新的分区计数(默认情况下,分区计数与原始 RDD 中的相同)。

由于 Spark (RDD API) 本身不进行优化(与许多新的 Spark 程序员来自的 SQL 不同),程序员必须自己优化操作的流程和并行性(来自同一篇文章)。

[..]这可能源于许多用户对 SQL 查询语言的熟悉以及他们对查询优化的依赖。重要的是要意识到 RDD API 不应用任何此类优化。

此外,repartitioning通常使用但通常成本很高,并且在各种情况下可以避免或与其他操作合并以提高整体性能(请参阅链接的帖子)


推荐阅读