RDD,全称Resilient Distributed
Datasets(弹性分布式数据集),是Spark最为核心的概念,是Spark对数据的抽象。RDD是分布式的元素集合,每个RDD只支持读操作,且每个RDD都被分为多个分区存储到集群的不同节点上。除此之外,RDD还允许用户显示的指定数据存储到内存和磁盘中,掌握了RDD编程是SPARK开发的第一步。
1.RDD读取数据
文件读取
scala> val lines = sc.textFile("README.md")
scala> lines.collect()
并行化读取
scala> var lines = sc.parallelize(List("i love you"))
scala> lines.collect()
2.RDD操作之transformation
RDD的操作可分两种:
1 转化操作(transformation) : 由一个RDD生成一个新的RDD
2 行动操作(action) : 对RDD中的元素进行计算,并把结果返回
参考api: org.apache.spark.rdd.RDD
3.下划线用法
//以下两句等同
_.split(" ")
line => line.split(" ")
//等同
_ + _
(left, right) => left + right
2.1.map()
返回:一个新的RDD
scala> val rdd = sc.parallelize(List(1,2,3,3))
scala> val rrr=rdd.map(x => x +1 )
scala> rrr.collect()
Array[Int] = Array(2, 3, 4, 4)
scala> rrr.foreach(println)
2
4
4
3
2.2.flatmap()
返回:迭代器的所有元素组成一个新的RDD
val rdd1 = sc.parallelize(List(1,2,3,3))
scala> rdd1.map(x=>x+1).collect
Array[Int] = Array(2, 3, 4, 4)
scala> rdd1.flatMap(x=>x.to(3)).collect
Array[Int] = Array(1, 2, 3, 2, 3, 3, 3)
从上面可以看出flatMap先map然后再flat
2.3.filter()
对每个元素进行筛选,返回符合条件的元素组成的一个新RDD
scala> val rdd = sc.parallelize(List(1,2,3,3))
scala> rdd.filter(x => x != 1).collect()
Array[Int] = Array(2, 3, 3)
两变量过滤操作
scala> val rdd = sc.parallelize(List((1,2),(3,4),(3,6)))
对value做控制,key不加限制条件
scala> val result = rdd.filter{case(x,y)=>y%3==0}
scala> result.foreach(println)
(3,6)
scala> val result = rdd.filter{case(x,y)=>y<=4}
scala> result.foreach(println)
(1,2)
(3,4)
对key做控制,value不控制
scala> val result = rdd.filter{case(x,y)=>x<3}
scala> result.foreach(println)
(1,2)
2.4 distinct()
distinct() : 去掉重复元素
scala> rdd.distinct().collect()
Array[Int] = Array(1, 2, 3)
2.5 sample(withReplacement,fration,[seed])
sample():对RDD采样
- 第一个参数如果为true,可能会有重复的元素,如果为false,不会有重复的元素;
- 第二个参数取值为[0,1],最后的数据个数大约等于第二个参数乘总数;
- 第三个参数为随机因子。
scala> rdd.sample(false,0.5).collect()
Array[Int] = Array(3, 3)
scala> rdd.sample(false,0.5).collect()
Array[Int] = Array(1, 2)
scala> rdd.sample(false,0.5,10).collect()
Array[Int] = Array(2, 3)
2.6排序
rdd.sortByKey():返回一个根据键排序的RDD
数据排序,可以通过接受ascending的参数表示我们是否想要结果按升序排序(默认是true)
scala> val result = rdd.sortByKey().collect()
Array[(Int, Int)] = Array((1,2), (3,4), (3,6))
2.7reduce
rdd.reduceByKey(func):合并具有相同key的value值
scala> val rdd = sc.parallelize(List((1,2),(3,4),(3,6)))
scala> val result = rdd.reduceByKey((x,y)=>x+y)
scala> result.foreach(println)
(1,2)
(3,10)
2.8group
rdd.groupByKey():对具有相同键的进行分组 [数据分组]
scala> val result = rdd.groupByKey()
scala> result.foreach(println)
(3,CompactBuffer(4, 6))
(1,CompactBuffer(2))
2.9 mapValues
rdd.mapValues(func):对pairRDD中的每个值应用func 键不改变
scala> val rdd = sc.parallelize(List((1,2),(3,4),(3,6)))
scala> val result = rdd.mapValues(x=>x+1)
scala> result.foreach(println)
(1,3)
(3,5)
(3,7)
3.针对两个pair RDD 的转化操作
3.1 rdd.subtractByKey( other )
删除掉RDD中与other RDD中键相同的元素
scala> val rdd = sc.parallelize(List((1,2),(3,4),(3,6)))
scala> val other = sc.parallelize(List((3,9)))
scala> val result = rdd.subtractByKey(other)
scala> result.foreach(println)
(1,2)
3.2 join内连接
rdd,other是3.1的变量
scala> val result = rdd.join(other)
scala> result.foreach(println)
(3,(4,9))
(3,(6,9))
3.3 右外连接
rdd,other是3.1的变量
scala> val result = rdd.rightOuterJoin(other)
scala> result.foreach(println)
(3,(Some(4),9))
(3,(Some(6),9))
3.4 左外连接
scala> val result = rdd.leftOuterJoin(other)
scala> result.foreach(println)
(3,(4,Some(9)))
(3,(6,Some(9)))
(1,(2,None))
3.5按相同键分组
scala> val result = rdd.cogroup(other)
scala> result.foreach(println)
(1,(CompactBuffer(2),CompactBuffer()))
(3,(CompactBuffer(4, 6),CompactBuffer(9)))
3.6 使用reduceByKey()和mapValues()计算每个键对应累加值
x._1表示取元组的第一个值
scala> val rdd = sc.parallelize(List(Tuple2("panda",0),Tuple2("pink",3),Tuple2("pirate",3),Tuple2("panda",1),Tuple2("pink",4)))
scala> val result = rdd.mapValues(x=>(x,1)).reduceByKey((x,y)=>(x._1+y._1,x._2+y._2))
scala> result.foreach(println)
(pirate,(3,1))
(panda,(1,2))
(pink,(7,2))
3.7计单词(wordcount)
用map reduce实现:
scala> val rdd = sc.parallelize(List("i am thinkgamer, i love cyan"))
scala> val words = rdd.flatMap(line => line.split(" "))
scala> val result = words.map(x=>(x,1)).reduceByKey((x,y) => x+y)
scala> result.foreach(println)
(cyan,1)
(love,1)
(thinkgamer,,1)
(am,1)
(i,2)
用countByValue实现:
scala> val rdd = sc.parallelize(List("i am thinkgamer, i love cyan"))
scala> val result = rdd.flatMap(x=>x.split(" ")).countByValue()
scala> result.foreach(println)
(am,1)
(thinkgamer,,1)
(i,2)
(love,1)
(cyan,1)
4.RDD操作之action
下面例子以 val rdd = sc.parallelize(List(1,2,3,3))为输入
4.1 collect()返回所有元素
scala> rdd.collect()
Array[Int] = Array(1, 2, 3, 3)
4.2 count() :返回元素个数
scala> rdd.count()
Long = 4
4.3 countByValue() : 各个元素出现的次数
scala> rdd.countByValue()
scala.collection.Map[Int,Long] = Map(1 -> 1, 2 -> 1, 3 -> 2)
4.4 take(num) : 返回num个元素
scala> rdd.take(2)
Array[Int] = Array(1, 2)
4.5 top(num) : 返回前num个元素
scala> rdd.top(2)
Array[Int] = Array(3, 3)
4.6 foreach(func):对每个元素使用func
scala> rdd.foreach(x => println(x*2))