apache-spark - reduceByKey 的分区方面
问题描述
尽管 RDD 是遗留问题 - 并且在下一次分配之前还有一点时间 - 我想知道:
为什么可以
reduceByKey
用numPartitions调用?鉴于它的工作原理类似于 Map Reduce 中的 combineByKey,那么真正的意义何在?
对我来说不是那么明显。在实际情况下,我怀疑它不经常使用,通常已经重新分区(基于我自己的观察)。
解决方案
根据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
通常使用但通常成本很高,并且在各种情况下可以避免或与其他操作合并以提高整体性能(请参阅链接的帖子)
推荐阅读
- jquery - Ajax 表单偶尔会将数据添加到 URL 而不是 POST 然后重定向
- matlab - 如何签署已编译的 matlab 程序的已安装可执行文件?
- c# - 是否有任何预定义的异常类型用作异常列表的容器?
- java - JLabel鼠标事件一键生效两次
- docker - Ansible Docker:使用容器执行 shell 文件
- javascript - 带有输入的位置固定容器超出了边界
- c - 为什么使用 exec 调用时没有将 argv[0] 设置为程序名称?
- scripting - 如何使用 KEY_pre_write 方法从 Zapier(脚本)中的操作字段更改“键”名称?
- java - 方法参考没有懒惰地评估?
- emacs - emacs 在特定窗口中更改文件