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