rdd算子

 

 

 

 

 

 

 

 

 

1.RDD是一个基本的抽象,操作RDD就像操作一个本地集合一样,降低了编程的复杂度

RDD的算子分为两类,一类是Transformation(lazy),一类是Action(触发任务执行)
RDD不存真正要计算的数据,而是记录了RDD的转换关系(调用了什么方法,传入什么函数)


创建RDD有哪些中方式呢?
1.通过外部的存储系统创建RDD
2.将Driver的Scala集合通过并行化的方式编程RDD(试验、测验)
3.调用一个已经存在了的RDD的Transformation,会生成一个新的RDD

RDD的Transformation的特点
1.lazy
2.生成新的RDD


RDD分区的数据取决于哪些因素?
1.如果是将Driver端的Scala集合并行化创建RDD,并且没有指定RDD的分区,RDD的分区就是为该app分配的中的和核数
2.如果是重hdfs中读取数据创建RDD,并且设置了最新分区数量是1,那么RDD的分区数据即使输入切片的数据,如果不设置最小分区的数量,即spark调用textFile时会默认传入2,那么RDD的分区数量会打于等于输入切片的数量

-------------------------------------------
RDD的map方法,是Executor中执行时,是一条一条的将数据拿出来处理


mapPartitionsWithIndex 一次拿出一个分区(分区中并没有数据,而是记录要读取哪些数据,真正生成的Task会读取多条数据),并且可以将分区的编号取出来

功能:取分区中对应的数据时,还可以将分区的编号取出来,这样就可以知道数据是属于哪个分区的(哪个区分对应的Task的数据)

//该函数的功能是将对应分区中的数据取出来,并且带上分区编号
val func = (index: Int, it: Iterator[Int]) => {
it.map(e => s"part: $index, ele: $e")
}

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

aggregateByKey 是Transformation
reduceByKey 是Transformation
filter 是Transformation
flatMap 是Transformation
map 是ransformation
mapPartition 是ransformation
mapPartitionWithIndex 是ransformation


collect 是Action
aggregate 是Action
saveAsTextFile 是Action
foreach 是Action
foreachPartition 是Action

-------------------------------------------
作业,求最受欢迎的老师
1.在所有的老师中求出最受欢迎的老师Top3
2.求每个学科中最受欢迎老师的top3(至少用2到三种方式实现)

作业,把你以前用mapReduce实现的案例,全部用spark实现


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

* - A list of partitions (一系列分区,分区有编号,有顺序的)
* - A function for computing each split (每一个切片都会有一个函数作业在上面用于对数据进行处理)
* - A list of dependencies on other RDDs (RDD和RDD之间存在依赖关系)
* - Optionally, a Partitioner for key-value RDDs (e.g. to say that the RDD is hash-partitioned)
(可选,key value类型的RDD才有RDD[(K,V)])如果是kv类型的RDD,会一个分区器,默认是hash-partitioned
* - Optionally, a list of preferred locations to compute each split on (e.g. block locations for
* an HDFS file)
(可以,如果是从HDFS中读取数据,会得到数据的最优位置(向Namenode请求元数据))

 

#常用Transformation(即转换,延迟加载)
#通过并行化scala集合创建RDD
val rdd1 = sc.parallelize(Array(1,2,3,4,5,6,7,8))
#查看该rdd的分区数量
rdd1.partitions.length


val rdd1 = sc.parallelize(List(5,6,4,7,3,8,2,9,1,10))
val rdd2 = sc.parallelize(List(5,6,4,7,3,8,2,9,1,10)).map(_*2).sortBy(x=>x,true)
val rdd3 = rdd2.filter(_>10)
val rdd2 = sc.parallelize(List(5,6,4,7,3,8,2,9,1,10)).map(_*2).sortBy(x=>x+"",true)
val rdd2 = sc.parallelize(List(5,6,4,7,3,8,2,9,1,10)).map(_*2).sortBy(x=>x.toString,true)


val rdd4 = sc.parallelize(Array("a b c", "d e f", "h i j"))
rdd4.flatMap(_.split(' ')).collect

val rdd5 = sc.parallelize(List(List("a b c", "a b b"),List("e f g", "a f g"), List("h i j", "a a b")))


List("a b c", "a b b") =List("a","b",))

rdd5.flatMap(_.flatMap(_.split(" "))).collect

#union求并集,注意类型要一致
val rdd6 = sc.parallelize(List(5,6,4,7))
val rdd7 = sc.parallelize(List(1,2,3,4))
val rdd8 = rdd6.union(rdd7)
rdd8.distinct.sortBy(x=>x).collect

#intersection求交集
val rdd9 = rdd6.intersection(rdd7)


val rdd1 = sc.parallelize(List(("tom", 1), ("jerry", 2), ("kitty", 3)))
val rdd2 = sc.parallelize(List(("jerry", 9), ("tom", 8), ("shuke", 7), ("tom", 2)))

#join(连接)
val rdd3 = rdd1.join(rdd2)
val rdd3 = rdd1.leftOuterJoin(rdd2)
val rdd3 = rdd1.rightOuterJoin(rdd2)


#groupByKey
val rdd3 = rdd1 union rdd2
rdd3.groupByKey
//(tom,CompactBuffer(1, 8, 2))
rdd3.groupByKey.map(x=>(x._1,x._2.sum))
groupByKey.mapValues(_.sum).collect
Array((tom,CompactBuffer(1, 8, 2)), (jerry,CompactBuffer(9, 2)), (shuke,CompactBuffer(7)), (kitty,CompactBuffer(3)))


#WordCount
sc.textFile("/root/words.txt").flatMap(x=>x.split(" ")).map((_,1)).reduceByKey(_+_).sortBy(_._2,false).collect
sc.textFile("/root/words.txt").flatMap(x=>x.split(" ")).map((_,1)).groupByKey.map(t=>(t._1, t._2.sum)).collect

#cogroup
val rdd1 = sc.parallelize(List(("tom", 1), ("tom", 2), ("jerry", 3), ("kitty", 2)))
val rdd2 = sc.parallelize(List(("jerry", 2), ("tom", 1), ("shuke", 2)))
val rdd3 = rdd1.cogroup(rdd2)
val rdd4 = rdd3.map(t=>(t._1, t._2._1.sum + t._2._2.sum))

#cartesian笛卡尔积
val rdd1 = sc.parallelize(List("tom", "jerry"))
val rdd2 = sc.parallelize(List("tom", "kitty", "shuke"))
val rdd3 = rdd1.cartesian(rdd2)

###################################################################################################

#spark action
val rdd1 = sc.parallelize(List(1,2,3,4,5), 2)

#collect
rdd1.collect

#reduce
val r = rdd1.reduce(_+_)

#count
rdd1.count

#top
rdd1.top(2)

#take
rdd1.take(2)

#first(similer to take(1))
rdd1.first

#takeOrdered
rdd1.takeOrdered(3)

1.RDD 与 普通的集合有哪些区别

RDD里面计入的是描述信息(从哪里读数据、以后对数据如何进行计算)、RDD的方法分为两类Transformation(lazy)、Action(生成Task,并发送到Executor中执行)
Scala存储的是真正要计算的数据、执行方法后立即回返回结果

RDD的特点:
1.一系列分区(一个RDD里面有多个分区,分区是有编号的)
2.每一个输入切片会有一个函数作用在上面
3.RDD和RDD之间存储依赖关系(是父RDD调用什么方法,传入哪些函数得到的)
4.(可选)RDD中如果存储的是KV,shuffle是会有一个分区器,模式hash partitioner
5.(可选)如果是读取HDFS中的数据,那么会有一个最优位置

一个分区对应一个Task(在同一个Stage),一个分区对应的Task只能在一台机器里面(在Executor),一台机器上可以有多个分区对应的Task


分组TopN
1.聚合后按学科进行分组,然后在每个分组中进行排序(调用的是Scala集合的排序)
2.先按学科进行过滤,然后调用RDD的方法进行排序(多台机器+内存+磁盘),需要将任务提交多次
3.自定义分区,然后在每个分区中进行排序(patitionBy、mapPartitions)
4.在聚合是就用于自定义的分区,可以减少shuffle
5.自定义分区,mapPartitions,在调用mapPartitions方法里面定义一个可排序的集合(6)


WordCount的执行流程
6个RDD
2个Stage


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

什么是后进行cache
1.要求的计算速度快
2.集群的资源要足够大
3.重要:cache的数据会多次的触发Action
4.先进行过滤,然后将缩小范围的数据在cache到内存

//第一个参数,放到磁盘
//第二个参数,放到内存
//第三个参数,磁盘中的数据,不是以java对象的方式保存
//第四个参数,内存中的数据,以java对象的方式保存
val MEMORY_AND_DISK = new StorageLevel(true, true, false, true)

OFF_HEAP:堆外内存 (Tachyon,分布式内存存储系统)
Alluxio - Open Source Memory Speed Virtual Distributed Storage

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

什么时候做checkpoint
1.迭代计算,要求保证数据安全
2.对速度要求不高(跟cache到内存进行对比)
3.将中间结果保存到hdfs

//设置checkpoint目录(分布式文件系统的目录hdfs目录)
//经过复杂进行,得到中间结果
//将中间结果checkpoint到指定的hdfs目录
//后续的计算,就可以使用前面ck的数据了

 

posted @ 2021-05-26 15:46  每天都要进步啊  阅读(314)  评论(0编辑  收藏  举报