4.3.1 聚合操作
Spark 有一组类似的操作,可以组合具有相同键的值。
这些操作返回 RDD,因此它们是转化操作而不是行动操作。
- reduceByKey() 与 reduce() 相当类似;它们都接收一个函数,并使用该函数对值进行合并。
reduceByKey() 会为数据集中的每个键进行并行的归约操作,每个归约操作会将键相同的值合并起来。
它会返回一个由各键和对应键归约出来的结果值组成的新的 RDD。 - foldByKey() 则与 fold() 相当类似;它们都使用一个与 RDD 和合并函数中的数据类型相同的零值作为初始值。
与 fold() 一样, foldByKey() 操作所使用的合并函数对零值与另一个元素进行合并,结果仍为该元素。 - combineByKey() 是最为常用的基于键进行聚合的函数。
大多数基于键聚合的函数都是用它实现的。
和 aggregate() 一样, combineByKey() 可以让用户返回与输入数据的类型不同的返回值。并行度调优
每个 RDD 都有固定数目的分区,分区数决定了在 RDD 上执行操作时的并行度。
在执行聚合或分组操作时,可以要求 Spark 使用给定的分区数。
Spark 始终尝试根据集群的大小推断出一个有意义的默认值,但是有时候你可能要对并行度进行调优来获取更好的性能表现。
本章讨论的大多数操作符都能接收第二个参数,这个参数用来指定分组结果或聚合结果的 RDD 的分区数。
在 Python 中自定义 reduceByKey() 的并行度:
data = [("a", 3), ("b", 4), ("a", 1)]
sc.parallelize(data).reduceByKey(lambda x, y: x + y) # 默认并行度
sc.parallelize(data).reduceByKey(lambda x, y: x + y, 10) # 自定义并行度
在 Scala 中自定义 reduceByKey() 的并行度:
val data = Seq(("a", 3), ("b", 4), ("a", 1))
sc.parallelize(data).reduceByKey((x, y) => x + y) // 默认并行度
sc.parallelize(data).reduceByKey((x, y) => x + y) // 自定义并行度