Apache spark createCombiner、mergeValue、mergeCombiner如何在Spark中的CombineByKey中工作(使用Scala)

Apache spark createCombiner、mergeValue、mergeCombiner如何在Spark中的CombineByKey中工作(使用Scala),apache-spark,Apache Spark,我试图了解combineByKeys中的每个步骤是如何工作的 有人能帮我理解下面的RDD吗 val rdd = sc.parallelize(List( ("A", 3), ("A", 9), ("A", 12), ("A", 0), ("A", 5),("B", 4), ("B", 10), ("B", 11), ("B", 20), ("B", 25),("C", 32), ("C", 91), ("C", 122), ("C", 3), ("C", 55)), 2) rd

我试图了解
combineByKeys
中的每个步骤是如何工作的

有人能帮我理解下面的RDD吗

val rdd = sc.parallelize(List(
  ("A", 3), ("A", 9), ("A", 12), ("A", 0), ("A", 5),("B", 4), 
  ("B", 10), ("B", 11), ("B", 20), ("B", 25),("C", 32), ("C", 91),
   ("C", 122), ("C", 3), ("C", 55)), 2)

rdd.combineByKey(
    (x:Int) => (x, 1),
    (acc:(Int, Int), x) => (acc._1 + x, acc._2 + 1),
    (acc1:(Int, Int), acc2:(Int, Int)) => (acc1._1 + acc2._1, acc1._2 + acc2._2))

首先,让我们将流程分解为:

首先,
createCombiner
为一个键在分区上的第一次相遇创建初始值(combiner),如果没有找到该值
-->
(firstvaluecombined,1)
。因此,这只是初始化一个元组,第一个值和一个键计数器为1

然后,
mergeValue
仅当已经为此分区上找到的键创建了组合器(在本例中为元组)
(existingTuple.\u 1+后续值,existingTuple.\u 2+1)
。这会将现有元组的值(在第一个插槽中)与新遇到的值相加,并获取现有元组的计数器(在第二个插槽中)并将其递增。所以,我们是

然后,
mergeCombiner
获取在每个分区上创建的组合器(元组),并将它们合并在一起
-->
(tupleFromPartition.\u 1+tupleFromPartition2.\u 1,tupleFromPartition1.\u 2+tupleFromPartition2.\u 2)
。这只是将每个元组中的值和计数器一起添加到一个元组中

然后,让我们将数据的一个子集拆分为多个分区,并查看它的运行情况:

("A", 3), ("A", 9), ("A", 12),("B", 4), ("B", 10), ("B", 11)
分区1 分区2 合并分区 因此,您应该返回一个数组,如下所示:

Array((A, (24, 3)), (B, (25, 3)))

为什么在分区1中需要(B,11)而不是(A,12),我假设是一个随机分区器。如果它是一个分类的分区,那么它应该是你所期望的,贾斯汀。。!
A=12 --> createCombiner(12) ==> accum[A] = (12, 1)
B=4 --> createCombiner(4) ==> accum[B] = (4, 1)
B=10 --> mergeValue(accum[B], 10) ==> accum[B] = (4 + 10, 1 + 1)
A ==> mergeCombiner((12, 2), (12, 1)) ==> (12 + 12, 2 + 1)
B ==> mergeCombiner((11, 1), (14, 2)) ==> (11 + 14, 1 + 2)
Array((A, (24, 3)), (B, (25, 3)))