所有RDD行動算子如下:
aggregate、collect、count、first、foreach、reduce、take、takeOrdered、takeSample、saveAsObjectFile、saveAsTextFile
具體解釋和例子
1. aggregate
概念
1.將每個分區裏面的元素進行聚合,然後用combine函數將每個分區的結果和初始值(zeroValue)進行combine操作。這個函數最終返回的類型不需要和RDD中元素類型一致。
2.在seq中每個值和初始值輪流比較,每個分區返回一個滿足條件的值
3.在comb中將初始值和每個分區返回值聚合,得到最終結果
例子解釋
1.將初始值和第一個分區中的第一個元素傳遞給seq函數進行計算,然後將計算結果和第二個元素傳遞給seq函數,直到計算到最後一個值。第二個分區中也是同理操作。最後將初始值、所有分區的結果經過combine函數進行計算(先將前兩個結果進行計算,將返回結果和下一個結果傳給combine函數,以此類推)
,並返回最終結果。
2.從上面的代碼的輸出結果可以看出,1,2,3被分到一個分區中,4,5,6被分到一個分區中。3先和第一個元素1傳給seq函數,返回最小值1,然後將1和第二個元素2傳給seq函數,返回1,以此類推,最後返回第一個分區中的最小值1。第二個分區一樣道理,最後結果返回最小值3.最後將初始值3和兩個分區的結果經過combine函數進行計算,先將初始值3和第一個分區的結果1傳給combine函數,返回4,然後將4和第二個分區結果3傳給combine函數,返回最終結果7。
object Aggregate {
def main(args: Array[String]): Unit = {
val sparkConf = new SparkConf().setAppName("transformations examples").setMaster("local[*]")
val sc = new SparkContext(sparkConf)
val rdd = sc.parallelize(Seq(1, 2, 3, 4, 5, 6), 2)
def seq(a: Int, b: Int): Int = {
println("seq: " + a + "\t " + b)
math.min(a, b)
}
def comb(a: Int, b: Int): Int = {
println("comb: " + a + "\t " + b)
a + b
}
val aggRDD = rdd.aggregate(3)(seq, comb)
println(aggRDD)
sc.stop()
}
}
2. collect
獲取整個RDD中的數據,只有當整個數據集能在單臺機器的內存中放得下時,才能使用collect(),因此,collect()不能用在大規模數據集上。
object Collect {
def main(args: Array[String]): Unit = {
val sparkConf = new SparkConf().setAppName("transformations examples").setMaster("local[*]")
val sc = new SparkContext(sparkConf)
val rdd = sc.parallelize(List(1, 2, 3))
rdd.collect().foreach(println)
sc.stop()
}
}
3. count
返回數據集元素個數
object Count {
def main(args: Array[String]): Unit = {
val sparkConf = new SparkConf().setAppName("transformations examples").setMaster("local[*]")
val sc = new SparkContext(sparkConf)
val rdd = sc.parallelize(List(1, 2, 3))
val count = rdd.count()
println(count)
sc.stop()
}
}
4. first
返回數據集的第一個元素
object First {
def main(args: Array[String]): Unit = {
val sparkConf = new SparkConf().setAppName("transformations examples").setMaster("local[*]")
val sc = new SparkContext(sparkConf)
val rdd = sc.parallelize(List(1, 2, 3))
println(rdd.first())
sc.stop()
}
}
5. foreach
對RDD中的每個元素使用給定的函數 ,相當於java for循環
object Foreach {
def main(args: Array[String]): Unit = {
val sparkConf = new SparkConf().setAppName("transformations examples").setMaster("local[*]")
val sc = new SparkContext(sparkConf)
val rdd = sc.parallelize(List(1, 2, 3))
rdd.foreach(x => {
val y=x+1
println(y)
})
sc.stop()
}
}
6. reduce
reduce(func):通過函數func先聚集各分區的數據集,再聚集分區之間的數據,func接收兩個參數,返回一個新值,新值再做爲參數繼續傳遞給函數func,直到最後一個元素
object Reduce {
def main(args: Array[String]): Unit = {
val sparkConf = new SparkConf().setAppName("transformations examples").setMaster("local[*]")
val sc = new SparkContext(sparkConf)
val rdd = sc.parallelize(List(1, 2, 3))
print(rdd.reduce(_+_))
sc.stop()
}
}
7. take
從RDD返回num個元素
object Take {
def main(args: Array[String]): Unit = {
val sparkConf = new SparkConf().setAppName("transformations examples").setMaster("local[*]")
val sc = new SparkContext(sparkConf)
val rdd = sc.parallelize(List("zhangsan", "lisi", "wangwu"))
rdd.take(2).foreach(println)
sc.stop()
}
}
8. takeOrdered
使用它們的自然順序或自定義比較器返回RDD的前n個元素
object TakeOrdered {
def main(args: Array[String]): Unit = {
val sparkConf = new SparkConf().setAppName("transformations examples").setMaster("local[*]")
val sc = new SparkContext(sparkConf)
val rdd = sc.parallelize(List("zhangsan", "lisi", "wangwu", "zhaoliu"))
// TODO: 添加比較器
rdd.takeOrdered(2).foreach(println)
sc.stop()
}
}
9. takeSample
takeSample(withReplacement, num, [seed]) 返回一個包含數據集的num元素的隨機抽樣的數組,其中包含或不替換,可選地預先指定一個隨機數生成器種子。
object TakeSample {
def main(args: Array[String]): Unit = {
val sparkConf = new SparkConf().setAppName("transformations examples").setMaster("local[*]")
val sc = new SparkContext(sparkConf)
val rdd = sc.parallelize(1 to 10)
val value = rdd.takeSample(false, 5, 5)
value.foreach(x => print(x + " "))
sc.stop()
}
}
10. saveAsObjectFile
將此RDD保存爲序列化對象的序列文件。
object SaveAsObjectFile {
def main(args: Array[String]): Unit = {
val sparkConf = new SparkConf().setAppName("transformations examples").setMaster("local[*]")
val sc = new SparkContext(sparkConf)
val rdd = sc.parallelize(List("zhangsan", "lisi", "wangwu"),1)
rdd.saveAsObjectFile("file:///gitRepositories/SparkLearnExample/save_data/")
sc.stop()
}
}
11. saveAsTextFile
將數據集的元素作爲文本文件(或一組文本文件)寫入本地文件系統、HDFS或任何其他hadoop支持的文件系統的給定目錄中。
Spark將在每個元素上調用toString,將其轉換爲文件中的一行文本。
saveAsTextFile要求保存的目錄之前是沒有的,否則會報錯。所以,最好程序中保存前先判斷一下目錄是否存在。
一般而言,saveAsTextFile會按照執行task的多少生成多少個文件,比如part-00一直到part-0n,n自然就是task的個數
在路徑前面加上hdfs://表示hdfs文件系統,不加默認hdfs
在路徑前面加上file://表示本地文件系統
object SaveAsTextFile {
def main(args: Array[String]): Unit = {
val sparkConf = new SparkConf().setAppName("transformations examples").setMaster("local[*]")
val sc = new SparkContext(sparkConf)
val rdd = sc.parallelize(List("zhangsan", "lisi", "wangwu"),1)
rdd.saveAsTextFile("file:///gitRepositories/SparkLearnExample/save_data/")
sc.stop()
}
}