创建RDD
(1)从集合(内存)中创建RDD
//第一种
var rdd: RDD[Int] = sc.makeRDD(List(1,2,3,4,5,6))
//第二种
val rdd1: RDD[Int] = sc.parallelize(List(7,8,9,10,12,13))
(2)从外部存储(文件)创建RDD textFile
val rdd2: RDD[String] = sc.textFile(" ")
(3)通过其他RDD转换得到RDD
var rdd: RDD[Int] = sc.makeRDD(List(1,2,3,4,5,6))
val rdd3: RDD[Int] = rdd.map(x=> x * 10)
RDD 并行度与分区
Spark可以将一个job作业切分为多个task任务后,发送给Executor 节点并行计算,而能够并行计算的任务数量我们称之为并行度。这个数量可以在构建RDD时指定。先有分区,分区对应task,task给Executo执行,有几个Executor在执行则有多少并行度;RDD在分区内有序执行! 不同分区并行执行!
map方法
将处理的数据逐条进行映射转换,这里的转换可以是类型的转换,也可以是值的转换。
//map方法表示RDD中的数据会逐一映射
val rdd: RDD[Int] = sc.makeRDD(List(1, 2, 3, 56, 33, 25, 88, 4, 7, 10, 49, 28,1,65,99))
val rdd1:RDD[Int] =rdd.map(x=>{
println("*******************")
x*10
})
//如果map中的数据有10万,需要从外部设备中查询数据,需要连接外部设备10万次
mapPartitions方法
将待处理的数据一分区为单位发送到计算节点进行处理(分区内计算,而分区之间并不能计算),这里的处理是指可以进项任意的处理,可以是过滤数据;
map类似于IO中的流,效率不高,而mapPartitions类似于缓冲流,效率更高;
缺点:将整个分区的数据加载到内存进行引用,处理完的数据不会被释放掉,因为存在对象的引用,只有全部处理完才会释放数据;
val rdd2: RDD[Int] = rdd.mapPartitions(x => {
println("*********")
val maps:Iterator[Int] = x.map(x=>{
x * 10
})
maps
})
//每个分区执行一次
//如果map中的分区有5个,需要从外部设备中查询数据,需要连接外部设备5次
map和mapPartitions的区别?
功能角度:Map算子是【分区内】一个数据一个数据的执行,类似于串行操作;MapPartitions算子是以分区为单位进行分批处理操作;
性能角度:Map性能低,MapPartitions性能高。但是MapPartitions算子会长时间占用内存,那么这样可能会导致内存不够用,出现内存溢出错误。
mappartitionswithindex 方法.
val mpwi: RDD[String] = rdd.mapPartitionsWithIndex((index,x) =>{
var list = List[String]()
list.::=(index+"|"+x.toBuffer)
list.iterator
})
运行结果:2|ArrayBuffer(88, 4, 7)
1|ArrayBuffer(56, 33, 25)
4|ArrayBuffer(1, 65, 99)
0|ArrayBuffer(1, 2, 3)
3|ArrayBuffer(10, 49, 28)