Spark中的RDD基本操作
前言
RDD是spark特有的数据模型,谈到RDD就会提到什么弹性分布式数据集,什么有向无环图。这些知识点在别的地方介绍得非常多,本文就不去讲这些了。
在阅读本文时候,大家可以就把RDD当作一个数组,或者一个Scala的collection对象,这样的理解对我们学习RDD的API是非常有帮助的。
RDD的创建
Spark里的计算都是操作RDD进行,那么学习RDD的第一个问题就是如何构建RDD,构建RDD从数据来源角度分为两类:第一类是从内存里直接读取数据,第二类就是从文件系统里读取,当然这里的文件系统种类很多常见的就是HDFS以及本地文件系统了。
从内存中创建
第一类方式从内存里构造RDD,使用的方法:makeRDD
和parallelize
方法,如下代码所示:
import org.apache.log4j.Level
import org.apache.log4j.Logger
import org.apache.spark.SparkConf
import org.apache.spark._
import scala.collection.immutable.ListMap
object Demo {
/* 使用makeRDD创建RDD */
def main(args: Array[String]) {
Logger.getLogger("org").setLevel(Level.ERROR)
val conf = new SparkConf().setAppName("Demo").setMaster("local[*]")
val sc = new SparkContext(conf)
/* List */
val rdd01 = sc.makeRDD(List(1, 2, 3, 4, 5, 6))
val r01 = rdd01.map { x => x * x }
println(r01.collect().mkString(","))
/* Array */
val rdd02 = sc.makeRDD(Array(1, 2, 3, 4, 5, 6))
val r02 = rdd02.filter { x => x < 5 }
println(r02.collect().mkString(","))
val rdd03 = sc.parallelize(List(1, 2, 3, 4, 5, 6), 1)
val r03 = rdd03.map { x => x + 1 }
println(r03.collect().mkString(","))
/* Array */
val rdd04 = sc.parallelize(List(1, 2, 3, 4, 5, 6), 1)
val r04 = rdd04.filter { x => x > 3 }
println(r04.collect().mkString(","))
}
}
从文件系统构造
代码如下所示:
import org.apache.log4j.Level
import org.apache.log4j.Logger
import org.apache.spark.SparkConf
import org.apache.spark._
import scala.collection.immutable.ListMap
object WordCount {
def main(args: Array[String]) {
Logger.getLogger("org").setLevel(Level.ERROR)
val conf = new SparkConf().setAppName("wordCounts").setMaster("local[*]")
val sc = new SparkContext(conf)
val lines = sc.textFile("in/word_count.text")
//val lines = sc.textFile("file:///Users/Phoebe/Documents/example/scala-spark-tutorial/in/word_count.text")
val words = lines.flatMap(line => line.split(" "))
val wordCounts = words.countByValue()
val resultValue = ListMap(wordCounts.toSeq.sortBy(_._1):_*)
println(resultValue.getClass)
for ((word, count) <- resultValue) println(word + " : " + count)
}
}
基础操作
和Scala中集合的操作非常类似,RDD的操作分为转化操作(transformation)和行为操作(action)。
RDD之所以将操作分成这两类这是和RDD惰性运算有关,当RDD执行转化操作时候,实际计算并没有被执行,只有当RDD执行行动操作时候才会促发计算任务提交,执行相应的计算操作。
区别转化操作和行动操作也非常简单,转化操作就是从一个RDD产生一个新的RDD操作,而行动操作就是进行实际的计算。
操作类型 |
函数名 |
作用 |
转化操作 |
map() |
参数是函数,函数应用于RDD每一个元素,返回值是新的RDD |
flatMap() |
参数是函数,函数应用于RDD每一个元素,将元素数据进行拆分,变成迭代器,返回值是新的RDD |
|
filter() |
参数是函数,函数会过滤掉不符合条件的元素,返回值是新的RDD |
|
distinct() |
没有参数,将RDD里的元素进行去重操作 |
|
union() |
参数是RDD,生成包含两个RDD所有元素的新RDD |
|
intersection() |