请教Spark 中 combinebyKey 和 reduceByKey的传入函数参数的区别?

本文详细解析了Spark中combineByKey与reduceByKey的区别,特别是它们在传入函数参数方面的不同。通过具体示例,解释了为何combineByKey需要显式指定类型参数,而reduceByKey则不需要。
摘要由CSDN通过智能技术生成



请教Spark 中 combinebyKey 和 reduceByKey的传入函数参数的区别?

代码如下
val testData = sc.parallelize(Seq(("t1", 1), ("t1", 2), ("t1", 3), ("t2", 2), ("t2", 5)))
val testDataCombine = testData.combineByKey(x=>x,(x:Int,y:Int)=>x+y,(x:Int,y:Int)=>x+y)
val testDataReduce = testData.reduceByKey((x,y)=>x+y)

这两个函数 在combineByKey 传入函数参数的时候 
为什么一定要指定x ,y的Int类型,如果不指定会报错没发识别"+"这个方法符, 
而reduceByKey的时候可以不用指定而进行系统推断。


作者:连城
链接:https://www.zhihu.com/question/45420080/answer/99044117
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

题主示例代码中 testData 这个 RDD 的类型是已经确定为 RDD[(String, Int)],然后通过 RDD.rddToRDDPairFunctions 这个隐式类型转换转为 PairRDDFunctions[String, Int],从而获得 reduceByKey 和 combineByKey 这两个 methods。

然后来对比下二者的函数签名:
class PairRDDFunctions[K, V](...) {
  def reduceByKey(func: (V, V) => V): RDD[(K, V)]

  def combineByKey[C](
      createCombiner: V => C,
      mergeValue: (C, V) => C,
      mergeCombiners: (C, C) => C): RDD[(K, C)]
}

可以看到 reduceByKey 的 func 参数的类型只依赖于 PairRDDFunction 的类型参数 V,在这个例子里也就是 Int。于是 func 的类型已经确定为 (Int, Int) => Int,所以就不需要额外标识类型了。

而 combineByKey 比 reduceByKey 更加通用,它允许各个 partition 在 shuffle 前先做 local reduce 得到一个类型为 C 的中间值,待 shuffle 后再做合并得到各个 key 对应的 C。

以求均值为例,我们可以让每个 partiton 先求出单个 partition 内各个 key 对应的所有整数的和 sum 以及个数 count,然后返回一个 pair (sum, count)。在 shuffle 后累加各个 key 对应的所有 sum 和 count,再相除得到均值:
val sumCountPairs: RDD[(String, (Int, Long))] = testData.combineByKey(
  (_: Int) => (0, 0L),

  (pair: (Int, Long), value: Int) =>
    (pair._1 + value, pair._2 + 1L),

  (pair1: (Int, Long), pair2: (Int, Long)) =>
    (pair1._1 + part2._1, pair2._2 + pair2._2)
)

val averages: RDD[String, Double] = sumCountPairs.mapValues {
  case (sum, 0L) => 0D
  case (sum, count) => sum.toDouble / count
}
由于 C 这个 类型参数是任意的,并不能从 testData 的类型直接推导出来,所以必须明确指定。只不过题主的例子是最简单的用 reduceByKey 就可以搞定的情况,也就是 V 和 C 完全相同,于是就看不出区别了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值