在groupByKey
的文档中有一些令人担忧的语言,警告它可能非常昂贵,并建议尽可能使用aggregateByKey
代替。
我想知道成本差异是否源于某些聚合不需要将整个组收集并加载到同一节点,或者实现上还有其他差异。
基本上,问题是rdd.groupByKey()
是否等价于rdd.aggregateByKey(Nil)(_ :+ _, _ ++ _)
,还是说它仍然更昂贵。
在groupByKey
的文档中有一些令人担忧的语言,警告它可能非常昂贵,并建议尽可能使用aggregateByKey
代替。
我想知道成本差异是否源于某些聚合不需要将整个组收集并加载到同一节点,或者实现上还有其他差异。
基本上,问题是rdd.groupByKey()
是否等价于rdd.aggregateByKey(Nil)(_ :+ _, _ ++ _)
,还是说它仍然更昂贵。
combineByKey
来有效地实现这一点,而不是使用groupByKey and take 10。
让我来帮助解释为什么groupByKey操作会导致更高的成本
通过理解这个特定操作的语义,reduce任务需要做的是将与单个唯一键相关联的所有值分组。
简而言之,让我们看一下它的签名
def groupByKey(): RDD[(K, Iterable[V])]
由于"groupby"操作,与此键相关联的所有值被分区到不同的节点上,无法进行预合并。大量数据通过网络传输,导致高网络IO负载。
但是,aggregateByKey与之不同。让我澄清一下签名:
def aggregateByKey[U](zeroValue: U)(seqOp: (U, V) ⇒ U, combOp: (U, U) ⇒ U)(implicit arg0: ClassTag[U]): RDD[(K, U)]
Spark引擎实现操作的语义如下:
在分区中,它将具有预合并操作,这意味着“特定的Reducer”只需要获取洗牌映射的所有预合并中间结果。
这将使网络IO显着减轻。
rdd.aggregateByKey(Nil)(_ :+ _, _ ++ _)
确实等同于rdd.groupByKey
。对吗? - Dima
rdd.groupByKey()
的成本显著低于rdd.aggregateByKey(Nil)(_ :+ _, _ ++ _)
。我在这里提出了这一点(链接)并与@eliasah在这里进行了讨论(外部链接)。 - zero323