Spark-RDD介绍

2018-06-05  本文已影响0人  edwin1993

RDD

1 RDD介绍
RDD的创建方法

把存在的集合传递给SparkContext的parallelize()方法,一般测试使用。

val rdd = sc.parallelize(Array(1,2,3,4),4)
//参数1:待处理集合
//参数2:分区个数

需要注意rdd的操作都在worker机上,因此输出rdd的元素将在worker机的标准输出上进行,驱动节点上不会运行,故直接在程序print是没有输出的。需要先对各个worker上的内容进行collect

另一种是加载外部文件

val rddText = sc.textFile("filepath")
Scala基础语法
2 RDD的基本操作Transformation

Transformation意思是转换。
从之前的RDD构建一个新的RDD,如map()和filter()。

逐元素运算
\\读入文件
scala> val input = sc.textFile("edwintest/inputfile2.txt")

scala> input.collect().foreach(print)
one two threefour five sixseven eight nightten 
                    
\\通过map转为(元素,1)格式             
scala> val mapInput = input.map(word=>(word,1))
scala> mapInput.collect().foreach(print)
(one two three,1)(four five six,1)(seven eight night,1)(ten,1)              

 \\通过flatMap将split后的元素压缩
scala> val inputSplit = input.flatMap(line=>line.split(" "))
scala> inputSplit.collect.foreach(print)
onetwothreefourfivesixseveneightnightten  

集合运算

RDDs支持数学的集合计算,如并集交集等。

scala> val rdd1 = sc.parallelize(Array("1","2","3","1","4","3"))

scala> val rdd2 = sc.parallelize(Array("1","2","5","6"))

\\去重
scala> val rdd_distinct = rdd1.distinct()
scala> rdd_distinct.collect().foreach(print)
4231              

\\并
scala> val rdd_union = rdd1.union(rdd2)
scala> rdd_union.collect().foreach(println)
1231431256 

\\交
scala> val rdd_inter = rdd1.intersection(rdd2)
scala> rdd_inter.collect().foreach(print)
21

\\rdd1独有
scala> val rdd_sub = rdd1.subtract(rdd2)
scala> rdd_sub.collect().foreach(print)
433  

3 RDD的基本操作Action

Action在RDD上计算出一个结果,并将结果返回给Driver program,如count(),save

scala>  val rdd = sc.parallelize(Array(1,2,3,3))
rdd: org.apache.spark.rdd.RDD[Int] = ParallelCollectionRDD[6] at parallelize at <console>:27

scala> rdd.collect()
res3: Array[Int] = Array(1, 2, 3, 3)

scala> rdd.reduce((x,y)=>x+y)
res4: Int = 9

scala> rdd.take(2)
res5: Array[Int] = Array(1, 2)

scala> rdd.take(3)
res6: Array[Int] = Array(1, 2, 3)

scala> rdd.top(1)
res7: Array[Int] = Array(3)                                                     

scala> rdd.top(3)
res8: Array[Int] = Array(3, 3, 2)

4 RDD的特性

参数决定优先度。

6 KeyValue对RDDs
scala> input.collect().foreach(print)
one two threefour five sixseven eight nightten                                  
scala> val rdd1 = input.map(line=>(line.split(" ")(0),line))
scala> rdd1.collect().foreach(println)
(one,one two three)                                                             
(four,four five six)
(seven,seven eight night)
(ten,ten)

现在keys和values已经变为属性,不需要加()

scala> val rdd = sc.parallelize(Array((1,2),(3,4),(3,6)))
scala> val rdd2 = rdd.reduceByKey((x,y)=>x+y)
scala> rdd2.collect().foreach(println)
(1,2)                                                                           
(3,10)

scala> val rdd3 = rdd.groupByKey()
scala> rdd3.collect().foreach(println)
(1,CompactBuffer(2))                                                            
(3,CompactBuffer(4, 6))

combineByKey()
遍历partition中的元素,元素的key。如果是新元素,则使用我们在参数中提供的createCombiner()函数,如果是这个partition中已经存在的key,就会使用mergeValue()函数。
最后合集每个partition的时候,使用mergeCombiner()函数

scala> val scores = sc.parallelize(Array(("jack",80.0),("jack",90.0),("jack",85.0),("mike",80.0),("mike",92.0),("mike",90.0)))
scala> scores.collect().foreach(print)

(jack,80.0)(jack,90.0)(jack,85.0)(mike,80.0)(mike,92.0)(mike,90.0) 

val result = scores.combineByKey(score=>(1,score),(c1:(Int,Double),newScore)=>(c1._1+1,c1._2+newScore),(c1:(Int,Double),c2:(Int,Double))=>(c1._1+c2._1,c1._2+c2._2))

scala> result.collect().foreach(print)
(mike,(3,262.0))(jack,(3,255.0))  

//计算平均数
scala> val aver = result.map{case(name,(num,score))=>(name,score/num)}

scala> aver.collect().foreach(print)
(mike,87.33333333333333)(jack,85.0) 

createCombiner()中定义的匿名函数,
第一个参数:createCombiner
score=>(1,score)
score为分数,因为ByKey相关的函数传进的参数都是key后面的内容。

第二个参数:mergeValue
(c1:(Int,Double),newScore)=>(c1._1+1,c1._2+newScore)
c1中Int为出现次数,Double为分数累加。c1为key-value形式,是createCombiner的结果。

第三个参数:mergeCombiner
(c1:(Int,Double),c2:(Int,Double))=>(c1._1+c2._1,c1._2+c2._2)
将各个partition的mergeValue进行组合。

上一篇下一篇

猜你喜欢

热点阅读