spark RDD中foreachPartition和foreach說明

主題:RDD的foreachPartition/foreach的操作


說明:這兩個action主要用於對每個partition中的iterator時行迭代的處理.通過用戶傳入的functioniterator進行內容的處理.

一、foreach的操作:

foreach,傳入一個function,這個函數的傳入參數就是每個partition,每次的foreach得到的一個rddkv實例,也就是具體的內容,

這種處理你並不知道這個iteratorforeach什麼時候結果,只能是foreach的過程中,你得到一條數據,就處理一條數據.

由下面的紅色部分可以看出,foreach操作是直接調用了partition中數據的foreach操作


def foreach(f: T => Unit): Unit = withScope {
  val cleanF = sc.clean(f)
  sc.runJob(this, (iter: Iterator[T]) => iter.foreach(cleanF))
}


示例說明:

val list = new ArrayBuffer()

Rdd.foreach(record => {

  list += record

  If (list.size >= 10000) {

    list.flush

  }

})


上面這段示例代碼中,如果會存在一個問題,迭代的最後,list的結果可能還沒有達到10000條,這個時候,

你在內部的處理的flush部分就不會執行,也就是迭代的最後如果沒有達到10000的數據就會丟失.

所以在foreach中,一般就是拿到一條數據進行下處理Rdd.foreach(record => {record._1 == a return})


二、foreachPartition操作:

這個函數也是根據傳入的function進行處理,但不同之處在於,這裏function的傳入參數是一個partition對應數據的iterator.

而不是直接使用iteratorforeach,這種情況下,如果是上面foreach的示例代碼中list這個片段在這個action中就能夠正常的去處理.

def foreachPartition(f: Iterator[T] => Unit): Unit = withScope {
  val cleanF = sc.clean(f)
  sc.runJob(this, (iter: Iterator[T]) => cleanF(iter))
}


示例代碼:

Val list = new ArrayBuffer

rdd.foreachPartition(it => {

  It.foreach(r => {

List += r

If (list.size > 10000) flush

  })

  If (list.size > 0) flush

})


最後說下這兩個action的區別:

ForeachForeachPartition都是在每個partition中對iterator進行操作,

不同的是,foreach是直接在每個partition中直接對iterator執行foreach操作,而傳入的function只是在foreach內部使用,

foreachPartition是在每個partition中把iterator給傳入的function,function自己對iterator進行處理(可以避免內存溢出).


發佈了294 篇原創文章 · 獲贊 57 · 訪問量 43萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章