我正在使用“学习星火”这本书学习火花。碰到这个词(第54页)
We can disable map-side aggregation in combineByKey() if we know that our data won’t benefit from it
我很困惑这里的地图边聚合是什么意思?我想到的唯一的事情是Hadoop MapReduce中的Mapper和Reducer ......但是我认为这与Spark没有任何关系。
我正在使用“学习星火”这本书学习火花。碰到这个词(第54页)
We can disable map-side aggregation in combineByKey() if we know that our data won’t benefit from it
我很困惑这里的地图边聚合是什么意思?我想到的唯一的事情是Hadoop MapReduce中的Mapper和Reducer ......但是我认为这与Spark没有任何关系。
使用地图端聚合背后的想法与Hadoop组合器几乎相同。如果单个映射器可以为同一个键生成多个值,则可以通过在本地减少值来减少混洗。
可以从映射端聚合中受益的一个操作示例是为每个键创建一组值,尤其是在组合之前对RDD进行分区时:
首先让我们创建一些虚拟数据:
val pairs = sc.parallelize(
("foo", 1) :: ("foo", 1) :: ("foo", 2) ::
("bar", 3) :: ("bar", 4) :: ("bar", 5) :: Nil
)
并使用合并数据 combineByKey
:
import collection.mutable.{Set => MSet}
val combined = partitionedPairs.combineByKey(
(v: Int) => MSet[Int](v),
(set: MSet[Int], v: Int) => set += v,
(set1: MSet[Int], set2: MSet[Int]) => set1 ++= set2
)
根据数据分布,这可以显着减少网络流量。总体
reduceByKey
,combineByKey
同 mapSideCombine
设置 true
aggregateByKey
foldByKey
将使用地图侧聚合 groupByKey
和 combineByKey
同 mapSideCombine
设置 false
惯于。
然而,在应用地图侧聚合之间的选择并不总是显而易见的。在许多情况下,维护所需数据结构和随后的垃圾收集的成本可能超过洗牌成本。
例如,如果按键对值进行分组(groupByKey操作不使用组合器),则不能使用映射端聚合(组合器)。原因是在groupByKey操作完成后,每个键的所有值都应该存在。因此,不可能局部减少值(组合器)。
你是对的,术语map-side reduce确实来自Map / Reduce,而Apache Spark方面的想法有点复杂。如果我们可以在对组件进行混洗之前组合分区内的多个元素(并且组合元素占用较少的空间) - 那么在对数据进行混洗之前执行每分区缩减将是有用的。
地图侧减少的一种情况是 残 在Spark中 groupByKey
即使我们可以在同一个分区中组合一些元素,它们也会占用相同数量的空间,因此网络/序列化工作没有相应的减少。
希望有帮助,很高兴你正在阅读学习Spark :)