RDD转换算子
value类型
1.map
将处理的数据逐条进行映射转换,可以是类型的转换也可以是值的转换。如
val rdd = sc.makeRDD(List(1,2,3,4),2)
val mapRdd = rdd.map(
num => {
println("num = " + num)
num
}
)
val mapRdd1: RDD[(Int, Int)] = mapRdd.map(
num => {
println("num1 = " + num)
(num, 1)
}
)
2.mapPartitions
以分区为单位对数据转换操作,会将整个分区的数据加载到内存中进行引用,map算子是类似串行的操作,性能比较低,mapPartitions算子是类似批处理,性能比较高,但是mapPartitions算子会长时间占用内存,在内存较小数据较大的情况下,可能会出现内存溢出的情况。
// TODO算子 -mapPartitions
val rdd = sc.makeRDD(List(1,2,3,4),2)
val mapRdd = rdd.mapPartitions(
iter => {
println("-------------")
iter.map(_ * 2)
}
)
mapPartitions算子需要传递一个迭代器,返回一个迭代器,没有要求元素的个数不变,所以可以增加或是减少数据。
// TODO算子 -mapPartitions
val rdd = sc.makeRDD(List(1,2,3,4),2)
val mpRdd = rdd.mapPartitions(
iter => {
List(iter.max).iterator//求出分区的最大值并转换为新的迭代器
}
)
mpRdd.collect().foreach(println)
println(mpRdd.getClass) //获取mpRdd的类
sc.stop()
3.mapPartitionsWithIndex
将待处理的数据以分区为代为发送到计算节点进行处理,在处理的同时可以获得当前分区索引
// TODO算子 -mapPartitionsWithIndex
val rdd = sc.makeRDD(List(1,2,3,4))
var mpiRDD = rdd.mapPartitionsWithIndex(
(index, iter) =>{
iter.map(
num => {
(num, index)
}
)
}
)
mpiRDD.collect().foreach(println)
4.flatMap
将处理的数据进行扁平化后再进行映射处理
val dataRDD = sparkContext.makeRDD(List(
List(1,2),List(3,4)
),1)
val dataRDD1 = dataRDD.flatMap(
list => list
)
print("---------------------------------")
val rdd = sc.makeRDD(
List("hello scala","hello spark")
)
val flatRDD: RDD[String] = rdd.flatMap(
s => {
s.split(" ")
}
)
5.glom
将同一个分区的数据直接转换为相同类型的内存数组进行处理,分区不变
val rdd: RDD[Int] = sc.parallelize(List(1, 2, 3, 4), 2)
val glomRDD: RDD[Array[Int]] = rdd.glom()
//结果:ArrayBuffer(Array(1, 2), Array(3, 4))
val maxRDD: RDD[Int] = glomRDD.map(
array => {
array.max
}
)
println(maxRDD.collect().sum)
6.groupBy
根据指定规则进行分组,根据分组的key进行分组,相同的key的数据会放在一个组中,分区规则默认不变,数据会打乱重新组合,存在shuffer过程
val rdd = sc.makeRDD(List("hello","spark","scala","hadoop"),1)
val groupRDD: RDD[(Char, Iterable[String])] = rdd.groupBy(_.charAt(0))
groupRDD.saveAsTextFile("output")
7.filter
根据指定的规则进行筛选过滤,符合规则的数据保留否则丢弃,数据过滤后分区不变,但是分区的数据可能不均衡,可能会出现数据倾斜
// TODO算子 -filter
val rdd = sc.makeRDD(List(1,22,3,4))
val filterRDD: RDD[Int] = rdd.filter(_ % 2 == 0)
filterRDD.collect().foreach(println)
sc.stop()
8.sample
根据指定的规则从数据集中抽取数据。需要传递三个参数,第一个参数表示抽取后是否放回,true(放回),false(不放回),第二个参数表示数据源中每条数据被抽取的概率,第三个参数表示,抽取数据时随机算法的种子
val rdd = sc.makeRDD(List(1,2,3,4,5,6,7,8))
// sample需要传递三个参数
// 第一个参数表示抽取数据后是否放回,true(放回),false(不放回)
// 第二个参数表示数据源中每条数据被抽取的概率
// 第三个参数表示,抽取数据时随机算法的种子
println(rdd.sample(
false,
0.4
// 1
).collect().mkString(","))
sc.stop()
9.distinct
很简单,将数据集中重复的数据去重
// TODO算子 -distinct
val rdd = sc.makeRDD(List(1,2,3,4,2,4,6))
val rdd1: RDD[Int] = rdd.distinct(2)
rdd1.collect().foreach(s => println(s*2))
10.coalesce
缩减分区,根据数据量缩减分区,用于大数据集过滤,提高小数据集的执行效率,在spark中存在过多小任务的时候可以使用coalesce方法,收缩合并分区,减少分区个数,减小任务调度成本
// TODO算子 -coalesce
val rdd = sc.makeRDD(List(1,2,3,4,5,6),3)
// val newRDD: RDD[Int] = rdd.coalesce(2)
val newRDD: RDD[Int] = rdd.coalesce(2,true)
newRDD.saveAsTextFile("output11")