RDD Programming Foundation

废话不多说,首先上个图:
在这里插入图片描述
下面我们开始进入Spark RDD的部分学习。

1、RDD创建

首先我们要学会从哪里创建一个RDD,前面的我的文章已经说了,RDD是弹性分布式数据集,本质上是一个只读的分区记录集合,每个RDD又被分成了若干个分区,并且不同的分区存在不同的节点上,从而可以进行分布式并行计算,提高程序的执行效率。

RDD提供了一种高度受限的共享内存模型,即RDD是只读的记录分区的集合,不能直接修改,只能基于稳定的物理存储中的数据集来创建RDD或者通过在其他的RDD上执行确定的转换操作(map、join、groupBy)而创建的得到新的RDD。

RDD有两种数据运算形式:”行动“算子 和 “转换”算子,其中“转换”算子用于构建RDD之间的依赖关系,“行动”算子用于执行计算并指定输出的形式。
RDD典型的执行过程如下:

  • RDD从外部文件读取数据,或者通过内存中已经有的集合进行创建
  • RDD经过一系列的转换操作,每一次操作都会产生新的RDD,构建了依赖关系,并不会执行。
  • RDD的执行操作需要Action算子去触发从头到尾的运算,结果输出或者保存至文件。
    在这里插入图片描述
    First: 一般在linux打开spark-shell交互环境,已经创建了SparkContext上下文对象 sc
    在SparkContext类中定义了一个textFile方法,看看下面的源码:


/**
   * Read a text file from HDFS, a local file system (available on all nodes), or any
   * Hadoop-supported file system URI, and return it as an RDD of Strings.
   */
  def textFile(
      path: String,
      minPartitions: Int = defaultMinPartitions): RDD[String] = withScope {
   
   
    assertNotStopped()
    hadoopFile(path, classOf[TextInputFormat], classOf[LongWritable], classOf[Text],
      minPartitions).map(pair => pair._2.toString).setName(path)
  }

explain: 从HDFS文件系统,本地文件系统读取一个文件形成一个RDD,里面的RDD类型是一行一行的字符串类型的元素。首先我们看第一个参数 path:String 毫无疑问这是指定文件的路径,第二个参数是最小分区数,等会进行分析。
比如从HDFS文件系统有个文件people.txt,我们可以这样写:

object Spark02_Oper1 {
   
   
  def main(args: Array[String]): Unit = {
   
   
    //这里是创建sparkconf对象,传入SparkContext构造方法中
    val config: SparkConf = new SparkConf().setMaster("local[*]").setAppName("WordCount")
    //创建sc
    val sc = new SparkContext(config)
    //从外部文件中加载数据创建RDD
    val wordRDD: RDD[String] = sc.textFile("/in/word.txt")
  }
}

还可以通过数组、集合创建RDD,sc.parallzlize(数组或者列表)
Second: 下面介绍RDD转换算子常用的操作API,文件word.txt内容如下:
在这里插入图片描述

2、转换算子

  • filter(function)
val wordRDD: RDD[String] = sc.textFile("in/word.txt")

val linesRDD: RDD[String] = wordRDD.filter(line => line.contains("kafka"))

textFile方法会把word.txt这个文件加载并且形成一个RDD,这个RDD中有很多元素,每个元素的类型都是String类型,每个RDD元素是一行文本内容。line=>line.contains(“kafka”)这是一个表达式,这代码的意思就是依次取出RDD的每一个元素,过滤掉不包含"kafka"这个单词的元素,把包含的加入到新的RDD中,最终形成了一个新的RDD。
在这里插入图片描述

  • map(function)
val lines: RDD[String] = sc.textFile("in/word.txt")

val lineRDD: RDD[Array[String]] = lines.map(line => line.split(" "))

line => line.split(" ")是一个表达式,含义是:依次取出RDD中的每个元素,赋给line这个变量,然后对这个变量进行分割按照空格,作为函数的的返回值,并作为一个元素放到新的RDD中。
在这里插入图片描述

  • flatMap(function) `
val lines: RDD[String] = sc.textFile("in/word.txt")
val wordsRDD: RDD[String] = lines.flatMap(line=>line.split(" "))

在上一步map()的基础上将Array中的元素"拍扁"形成多个元素,最终被“拍扁”后的元素形成一个RDD,例如linesRDD中的第一个元素是Array(spark,kafka,is),拍扁之后会形成三个元即"spark",“kafka”,“is”,
所以就形成了9个String元素的RDD。
在这里插入图片描述

  • groupByKey()
    groupByKey()应用于(K,V)键值对的数据集时,返回一个新的(K,Iterable)形式的数据集。首先将每个元素转换成(_,1)的形式,然后将相同Key的value归并到一起,value形成一个Iterable。
val lines: RDD[String] = sc.textFile("in/word.txt")
val wordsRDD: RDD[String] = lines.flatMap(line=>line.split(" "))
val mapRDD: RDD[(String, Int)] = wordsRDD.map((_,1))
val groupwords: RDD[(String, Iterable[Int])] = mapRDD.groupByKey()
groupwords.collect().foreach(println)

直接结果如下:

(is,CompactBuffer(1, 1))
(better,CompactBuffer(1))
(kafka,CompactBuffer(1))
(cool,CompactBuffer(1))
(spark,CompactBuffer(1, 1))
(good,CompactBuffer(1))
(hbase,CompactBuffer(1))

在这里插入图片描述

  • reduceByKey(function)
    reduceByKey(function)应用于(K,V)键值对的数据集时,返回一个新的(K,V)形式的数据集。
val lines: RDD[String] = sc.textFile("in/word.txt")
val wordsRDD: RDD[String] = lines.flatMap(line=>line.split(" "))
val mapRDD: RDD[(String, Int)] = wordsRDD.map((_,1))
val resultRDD: RDD[(String, Int)] = mapRDD.reduceByKey((a,b) => a + b)
resultRDD.collect().foreach(println)

执行结果如下:

(is,2)
(better,1)
(kafka,1)
(cool,1)
(spark,2)
(good,1)
(hbase,1)

mapRDD.reduceByKey((a,b) => a + b)操作执行以后,所有key相同的键值对,他们的value就会被归并到一起,value是一个value-list,通过表达式聚合到一起(a,b) => a + b的含义是:取出的value第一个值赋值给a,第二个value赋值给b,然后相加的结果赋值给参数a,再把第三个value赋值给b,依次执行下去,最后聚合的结果就是这个单词出现个数的键值对类型。
在这里插入图片描述

3、行动算子

常用的RDD行动操作API
在这里插入图片描述
行动是真正触发计算的地方,Spark应用程序只有执行到行动操作的时候,才会执行真正的计算,从文件中加载读取数据,完成一次又一次的转换操作,最终,完成行动操作得到结果。
到这里一般的算子就结束了,画了这么久的流程图,会使自己更熟悉算子的各种功能,加深自己的印象,大家在学习框架的过程中,应该要多画流程图,加深自己的印象。
大家点个👍吧!
在这里插入图片描述




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章