RDD创建
- Spark采用textFile()方法来从文件系统中加载数据创建RDD
- 从文件系统中加载数据创建RDD。该方法把文件的URI作为参数,这个URI可以是:本地文件系统的地址;分布式文件系统HDFS的地址;Amazon S3的地址等等
通过并行集合(数组)创建RDD
调用SparkContext的parallelize方法,在Drive中一个已经存在的集合(数组)上创建。
scala> val array = Array(1,2,3,4,5)
scala> val red = sc.parallelize(array) //得到RDD
或者通过列表中创建
scala> val list = List(1,2,3,4,5)
scala> val red = sc.parallelize(list) // 得到RDD
RDD操作
- 转换操作
对于RDD而言,每一次转换操作都会产生不同的RDD,供一个操作使用。
转换得到的RDD是惰性求值的,也就是说,整个转换过程只是记录了转换的轨迹,并不会发生真正的计算,只有遇到行动操作时,才会发生真正的计算,从DAG图的源头开始进行“从头到尾”的计算操作。
常见的转换操作(Transformation API)
- filter(func): 筛选出满足函数func的元素,并返回一个新的数据集
- map(func): 将每个元素传递到函数func中,并将结果返回一个新的数据集
- flatMap(func): 与map()相似,但每个输入元素都可以映射到0或多个输出结果
- groupByKey():应用于(K, V)键值对的数据集时,返回一个新的(K,Iterable)形式的数据集
- reduceByKey(func): 应用于(K,V)键值对的数据集时,返回一个新的(K,V)形式的数据集,其中的每个值是将每个key传递到函数func中进行聚合。
- 行动操作
常见的行动操作(Action API)
- count(): 返回数据集中的元素个数
- collect(): 以数组的形式返回数据集中的所有元素
- first(): 返回数据集中的第一个元素
- take(n): 以数组的形式返回数据集中的前n个元素
- reduce(func): 通过函数func(输入两个参数并返回一个值)聚合数据集中的元素
- foreach(func): 将数据集中的每个元素传递到函数func中运行
实例一:关于filter()操作的实例
scala> val lines = sc.textFile("pathToFiles.txt")
scala> lines.filter(line => line.contains("Spark")).count()
实例二:找出文本文件中单行文本所包含的单词数量的最大值
scala> val lines = sc.textFile("file///usr/local/spark/mycode/rdd/word.txt")
scala> lines.map(line => line.split("").size).reduce((a,b) => if(a>b) a else b) // 匿名函数中的控制结构写法
- 持久化
在Spark中,RDD采用惰性求值的机制,每次遇到行动操作时,都会从头开始执行计算。每次调用行动操作,都会触发一次从头开始的计算。这对于迭代计算而言,代价是很大的,迭代计算经常需要多次重复使用同一组数据。
可以通过持久化(缓存)机制避免这种重复计算的开销,可以使用persist()方法对一个RDD标记为持久化。
之所以说“标记为持久化”,是因为出现persist()语句的地方,并不会马上计算生成RDD并把它持久化,而是要等到第一个行动操作触发真正计算以后,才会把计算结果进行持久化。(一般是保留在内存当中)
使用unpersist()方法手动地把持久化的RDD从缓存中移除。
scala> val list = List("Hadoop","Spark","Hive")
scala> val red = sc.parallelize(list)
scala> rdd.cache()
scala> println(rdd.count()) // 第一次行动操作,触发一次真正从头到尾的计算
scala> println(rdd.collect().mkString(",")) // 第二次行动操作,不需要出发从头到尾的计算,只需要重复使用上面缓存中的rdd
Hadoop,Spark,Hive