累加器用於在executors中做變量更改。
官方文檔: 官方文檔地址
基於spark 2.3.3版本編寫的示例demo :
package pers.nebo.sparkcore
import org.apache.spark.rdd.RDD
import org.apache.spark.sql.SparkSession
import org.apache.spark.util.LongAccumulator
/**
* @ author fnb
* @ email [email protected]
* @ date 2019/12/1
* @ des : 累加器的使用
*
*(1) 如果沒觸發到action , 由於 lazy 不會觸發,累加器的值也不會發生變化。
*(2)一個action 操作,會觸發一次累加器,所以如果多個action操作的話,中間使用cache() ,
* 這樣下一個aciton會使用cache的內容,則不會多計算累加器
*/
object AccumulatorTest {
def main(args: Array[String]): Unit = {
val spark=SparkSession.builder().appName("test").master("local").getOrCreate()
val sc=spark.sparkContext
val accumulator:LongAccumulator =sc.longAccumulator
val rdd1:RDD[String] =sc.textFile("/DATA/topN.txt")
var i=0
val rdd2=rdd1.map(line=>{
// i+=1
accumulator.add(1)
// 1.6 不能直接使用accumulator.value 獲取值,只能打印對象, 2.x 可以
println(s"Exector accumulator= ${accumulator}")
line
})
rdd2.collect()
println(s"i= ${accumulator.value}")
//下面爲需要注意的使用點,多個action 會導致累加器,重複計算,需要處理一下。
val accumulator2:LongAccumulator =sc.longAccumulator
val rdd3:RDD[String] =sc.textFile("/DATA/topN.txt",2)
println("rdd3 partition length==="+rdd3.getNumPartitions)
val rdd4=rdd3.map(line=>{
// i+=1
accumulator2.add(1)
// 1.6 不能直接使用accumulator.value 獲取值,只能打印對象, 2.x 可以
println(s"Exector accumulator= ${accumulator}")
line
})
//使用cache 這樣下一次就不會再觸發累加器了。註釋掉下面這行累加器則會翻倍。
// rdd4.cache()
// 這裏的sortby 沒有任何意思只是爲了使用sort 函數
val rdd5= rdd4.sortBy(line=>{})
// sort by key 當你的分區大於1的時候,它會有一個抽樣 ,觸發rdd的action
rdd5.collect()
println(s"i= ${accumulator2.value}")
}
}
源碼: github源碼
問題:
rdd轉化的時候((val rdd5= rdd4.sortBy(line=>{})))報錯
java.lang.NoSuchMethodError:net.jpountz.lz4.LZ4BlockInputStream
參考:解決博客