pairRDD的CombineByKey

RDD的CombineByKey使用方法

這是一個很抽象化的方法,一開始看得一頭霧水。但是大部分的聚合函數都基於這個方法去實現的,比如常用的reduceByKey,所以這個方法很重要。

方法參數

def combineByKey[C](
      //在找到給定分區中第一次碰到的key(在RDD元素中)時被調用。此方法爲這個key初始化一個累加器。
      createCombiner: V => C,
      //當累加器已經存在的時候(也就是上面那個key的累加器)調用。
      mergeValue: (C, V) => C,
      // 如果哪個key跨多個分區,該參數就會被調用。
      mergeCombiners: (C, C) => C,
      partitioner: Partitioner,
      mapSideCombine: Boolean = true,
      serializer: Serializer = null
): RDD[(K, C)] = { //實現略 }

原理

由於combineByKey()會遍歷分區中的所有元素,因此每個元素的鍵要麼還沒有遇到過,要麼就和之前的某個元素的鍵相同。

  • 如果這是一個新的元素,combineByKey()會使用一個叫作createCombiner()的函數來創建那個鍵對應的累加器的初始值。需要注意的是,這一過程會在每個分區中第一次出現各個鍵時發生,而不是在整個RDD中第一次出現一個鍵時發生。
  • 如果這是一個在處理當前分區之前已經遇到的鍵,它會使用mergeValue()方法將該鍵的累加器對應的當前值與這個新的值進行合併。
  • 由於每個分區都是獨立處理的,因此對於同一個鍵可以有多個累加器。如果有兩個或者更多的分區都有對應同一個鍵的累加器,就需要使用用戶提供的mergeCombiners()方法將各個分區的結果進行合併。

舉例

根據原理,粗略講一下大概的流程

  1. 第一個方法參數createCombiner,會去遍歷某個分區第一個出現的key所對應的value,然後賦值成元祖格式,這裏牢記是第一個。例:(50,1)
  2. 假設(maths,50)和(maths,60)在一個分區裏面,那麼會調用第二個方法參數mergeValue。 也就是(maths,50)-->(maths,(50,1)),而(maths,60)不變,然後調用第二個方法參數-->(50+60,1+1)
  3. 假設(maths,50)和(maths,60)不在同一個分區裏面,那麼會調用第三個方法參數mergeCombiners,也就是maths,50)-->(maths,(50,1)),(maths,60)-->(maths,(60,1)),接着調用第三個參數-->(50+60,1+1)

可以手動調整分區數,來看它不同的表現。

test("combine by key "){
    val inputrdd = spark.sparkContext.parallelize(Seq(
      ("maths", 50), ("maths", 60),
      ("english", 65),
      ("physics", 66), ("physics", 61), ("physics", 87)),
      3)

    val reduced = inputrdd.combineByKey(
      (mark) => {
        println(s"Create combiner -> ${mark}")
        (mark, 1)
      },
      (acc: (Int, Int), v) => {
        println(s"""Merge value : (${acc._1} + ${v}, ${acc._2} + 1)""")
        (acc._1 + v, acc._2 + 1)
      },
      (acc1: (Int, Int), acc2: (Int, Int)) => {
        println(s"""Merge Combiner : (${acc1._1} + ${acc2._1}, ${acc1._2} + ${acc2._2})""")
        (acc1._1 + acc2._1, acc1._2 + acc2._2)
      }
    )
    reduced.collect().foreach(println)
  }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章