Spark學習04——RDD行動算子

所有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()
  }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章