Spark计算模型之熟练使用RDD的算子完成计算 ----tranfoemation

Spark计算模型之熟练使用RDD的算子完成计算  ----tranfoemation

1.弹性分布式数据集RDD   

1.1什么是RDD   RDD(Rsedilient Distributed Dataaset)叫做分布式数据集,是Spark中最基本的数据抽象,它代表一个不可变、可分区、里面的元素可并行计算的集合。RDD具有数据模型的特点:自动容错、位置感知性调度和可伸缩性。RDD允许用户在执行多个查询时显示德将工作集缓存在内存中,后续的查询能够重用工作集,这极大的提升了查询速度。 

1.2RDD的属性   

 1)、一组分片(Partition),即数据集的基本组成单位,对于RDD来说,每个分片都会一个计算任务处理,并决定并行计算的颗粒度。用户可以在创建RDD时指定RDD的分片个数,如果没有指定,那么就会采用计算的粒度。用户可以在创建RDD时指定RDD的分片个数,如果没有指定,那么就会采用默认值。默认值就是程序所分配的CPU  Core的数目。

2)、一个计算每个分区的函数。Spark中的RDD的计算是以分片为单位,每个RDD都会实现compute函数以达到这个目的。compute函数会对迭代器进行复合,不需要保存每次计算的结果。

3)、RDD之间的依赖关系。RDD的每次转换都会生成一个新的RDD,所以RDD之间就会形成类似流水线一样的前后依赖关系,再部分分区数据丢失时,Spark可以通过这个依赖关系重新计算丢失的分区数据,而不是对RDD的所有分区进行重新计算。

4)、一个Partitioner,即RDD的分片函数,当前Spark中实现了两种的分片函数,一个是基于哈希的HashPartitioner,另外一个是基于范围的RangPartitioner,只有对于Key-value的RDD,才会有Partitioner,非Key-value的RDD的Partitioner的值是None.Partitioner函数不但决定了RDD本身的分片数量,也决定了Partent RDD  shuffle输出时的分片数量。

5)、一个列表,存储存取每个Partitioner的优先位置(Preferred location)。对于一个HDFS文件来说,这个列表保存的就是每个Partition所在的位置,按照“移动数据不如移动计算”的理念,Spark在进行任务调度的时候,会尽可能地将计算任务分配到其所要数据块的存储位置。

3.1创建RDD 

1、启动shell, 定义master 、executor-memory 执行内存 

 total-executior-cores 全部行的核数

./spark-shell --master spark://root1:7077 --executor-memory 512m --total-executor-cores 1

2)、由一个已经存在的Scala集合创建

val rdd1=sc.parallelize(Array(1,2,3,4,5,6))

3)、由外部存储系统的数据集创建,包括本地的文件系统,还有所有Hadoop支持的数据集,比如HDFS,Cassandra、HBase等

scala> val rdd2=sc.textFile("hdfs://root1:9000/words.txt")

----------------------------------------------------------------------------------------------------------------------------------------------------------------

scala> val rdd2=sc.textFile("hdfs://root1:9000/words.txt").flatMap(_.split(" ")).map((_,1)).collect

3.2  RDD编程API

3.2.1  Tranformation  

RDD中的所有转换都是延迟加载的,也就是说,它们并不会直接计算结果。相反的,它们只是记住这些应用到基础数据集(例如一个文件)上的转换动作。只有当发生一个要求返回结果给Driver的动作时,这些转换才会真正运行。这种设计让Spark更加有效率地运行。

常用的Transformation:

    

     

3.2.2 Action

   

 

4.练习

4.1 parallelize   类似于Map,但独立地在RDD的每一个分片上运行,因此在类型为T的RDD上运行时,func的函数类型必须是Iteratior[T] =>Iteratior[U]

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

4.2 map(func)  

每个元素都乘以10


scala> val rdd2=rdd1.map(_*10)
rdd2: org.apache.spark.rdd.RDD[Int] = MapPartitionsRDD[12] at map at <console>:29

scala> val rdd2=rdd1.map(_*10).collect
rdd2: Array[Int] = Array(10, 20, 30, 40, 50, 60)

选出 >30 的元素

scala> val rdd3=rdd2.filter(_>30)
rdd3: Array[Int] = Array(40, 50, 60)

4.3  设置分区的长度

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

读取分区的长度

scala> rdd4.partitions.length
res1: Int = 5

4.4 数组的每个元素都+2,并正排序  

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

scala> val rdd6=rdd5.map(_+2).sortBy(x=>x,true)
rdd6: org.apache.spark.rdd.RDD[Int] = MapPartitionsRDD[21] at sortBy at <console>:29

scala> val rdd6=rdd5.map(_+2).sortBy(x=>x,true).collect
rdd6: Array[Int] = Array(2, 3, 5, 6, 7, 11)

4.5 筛选数组rdd5中大于10的元素

scala> val rdd7=rdd6.filter(_>10)
rdd7: Array[Int] = Array(11)

4.6  进行联系,创建一个数组,每个元素都*2,按照正排序进行排序

scala> val rdd8=sc.parallelize(List(15,12,1,3,6)).map(_*2).sortBy(x=>x,true).collect
rdd8: Array[Int] = Array(2, 6, 12, 24, 30)

4.7 创建String的数组,进行统计相同单词的个数

scala> val rrd9=sc.parallelize(Array("a b c","c d a"))
rrd9: org.apache.spark.rdd.RDD[String] = ParallelCollectionRDD[35] at parallelize at <console>:27

scala> rrd9.flatMap(_.split(" ")).map((_,1)).groupBy(_._1).map(t=>(t._1,t._2.size)).collect
res12: Array[(String, Int)] = Array((d,1), (b,1), (a,2), (c,2))

4.8 

scala> val rdd10=sc.parallelize(List(1,3,4,5))
rdd10: org.apache.spark.rdd.RDD[Int] = ParallelCollectionRDD[64] at parallelize at <console>:27

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

scala> val rdd12=rdd10.union(rdd11).collect
rdd12: Array[Int] = Array(1, 3, 4, 5, 2, 3, 4, 6)

4.9   distinct  去除数组中重复的数字

scala> rdd12.distinct.sortBy(x=>x).collect
res17: Array[Int] = Array(1, 2, 3, 4, 5, 6)

4.10 交集    intersection

scala> val rdd13=rdd11.intersection(rdd10).collect
rdd13: Array[Int] = Array(4, 3)

4.11   string数组求交集

scala> val rdd14=sc.parallelize(List(("tom",1),("kack",2),("rose",1)))
rdd14: org.apache.spark.rdd.RDD[(String, Int)] = ParallelCollectionRDD[99] at parallelize at <console>:27

scala> val rdd15=sc.parallelize(List(("tom",2),("jeery",2),("lishua",1)))
rdd15: org.apache.spark.rdd.RDD[(String, Int)] = ParallelCollectionRDD[100] at parallelize at <console>:27

scala> rdd14.intersection(rdd15)
res18: org.apache.spark.rdd.RDD[(String, Int)] = MapPartitionsRDD[106] at intersection at <console>:32

scala> rdd14.intersection(rdd15).collect
res19: Array[(String, Int)] = Array()

4.12  求两个string数组中相同的Key

scala> rdd14.join(rdd15).collect
res20: Array[(String, (Int, Int))] = Array((tom,(1,2)))

4.13  利用leftOutJoin 求两个string数组中相同的Key

scala> val rdd16=rdd14.leftOuterJoin(rdd15).collect
rdd16: Array[(String, (Int, Option[Int]))] = Array((tom,(1,Some(2))), (kack,(2,None)), (rose,(1,None)))

猜你喜欢

转载自blog.csdn.net/abcdefghwelcome/article/details/86250639