原文:https://www.edureka.co/blog/apache-spark-combinebykey-explained
供稿人:Prithviraj Bose
这是Spark中强大的API,它是 combineByKey。
Scala API: org.apache.spark.PairRDDFunctions.combineByKey。
Python API: pyspark.RDD.combineByKey。
该API需要三个函数(如 Python中的lambda表达式 或 Scala中的匿名函数),即
- 创建组合函数:x
- 合并值函数:y
- 合并组合函数:z
API格式是 combineByKey(x,y,z)。
我们来看一个例子(在Scala中)。完整的Scala源代码可以在这里找到。
我们的目标是找到每个学生的平均分数。
这是一个占位符类 ScoreDetail, 用于存储学生姓名以及主题的分数。
生成一些测试数据并将其转换为**对值,其中 key = Students name 和 value = ScoreDetail 实例。
然后我们创建一个Pair RDD,如下面的代码片段所示。为了进行实验,我创建了一个大小为3的散列分区器,因此这三个分区将分别包含2个,2个和4个键值对。这在我们探索每个分区的部分中突出显示。
现在我们可以探索每个分区。第一行打印每个分区的长度(每个分区的键值对的数量),第二行打印每个分区的内容。
这里是最后的转换,我们计算每个学生的平均分数,然后在分区中合并分数。
上面的代码流程如下:
首先,我们需要创建一个组合器函数,对于每个分区中遇到的每个Key,本质上都是一个元组= =(value,1)。在此阶段之后,分区中每个(key,value)的输出都是(key,(value,1))。
然后在下一次迭代中,每个分区的组合函数被合并使用每个键的合并值函数。在这个阶段之后,每个分区的输出(key,(value,1))是(key,(total,count))。
最后,合并组合器函数合并执行器中分区的所有值,并将数据发送回驱动程序。在此阶段之后,每个分区的每个(key,(总数,计数))的输出是
(key,(totalAcrossAllPartitions,countAcrossAllPartitions))。
该map 转换将
(key,tuple)=(key,(totalAcrossAllPartitions,countAcrossAllPartitions))
转换为(key,tuple._1 / tuple._2)计算每个键的平均值。
最后一行输出driver结束时所有学生的平均分数。
参考:
1、Spark RDD操作 :http://homepage.cs.latrobe.edu.au/zhe/ZhenHeSparkRDDAPIExamples.html#combineByKey
2、GitHub举例: https://github.com/prithvirajbose/spark-dev/blob/master/src/main/scala/examples/TestCombineByKey.scala
3、Python api举例: http://spark.apache.org/docs/latest/api/python/pyspark.html#pyspark.RDD
4、Scala api举例: http://spark.apache.org/docs/latest/api/scala/index.html#org.apache.spark.rdd.PairRDDFunctions