1)、map:映射,将RDD的数据进行转换,比如对数据乘2、把数据转换为元组
2)、mapPartition:对分区内数据进行map,入参是可迭代的集合,对入参进行map操作
3)、mapPartitionWithIndex:带分区号的map操作,入参是分区号和可迭代的集合
map和mapPartition的区别:
4)、flatMap:把RDD中是数据扁平化处理
5)、glom:与flatMap对应,把分区内的数据转为一个集合
6)、groupBy:根据一定的规则进行分组
7)、filter:根据规则进行过滤,剔除返回false的数据
8)、sample:采样函数,入参withReplacement(是否放回)、fraction(因子,如果放回传抽取次数,不放回传抽取概率0到1)、seed(随机数生成器种子)
9)、distinct:去重,可以指定去重后的分区个数
10)、coalesce:重新分区(常用于缩减分区),可以指定是否进行shuffe
11)、repartition:重新分区(常用于增加分区),底层调用的是带shuffe的coalesce函数
12)、sortBy:排序,入参为排序字段,升降序排序(默认升序)
13)、pipe:执行脚本,保证脚本是正确的
//建立配置文件对象
val conf = new SparkConf().setMaster("local[*]").setAppName("MY")
//创建sc对象
val sc = new SparkContext(conf)
val rdd: RDD[Int] = sc.makeRDD(1 to 4,2)
//map 映射
val mapRdd: RDD[Int] = rdd.map(_*2)
//mapPartitions 分区内执行map
val mpRdd: RDD[Int] = rdd.mapPartitions(data => data.map(_*2))
//mapPartitionsWithIndex 带分区号的映射
val mpiRdd: RDD[(Int, Int)] = rdd.mapPartitionsWithIndex((index, datas) => {
datas.map((index, _))
})
//filter 过滤
val filter: RDD[Int] = rdd.filter(_%2 == 0)
val listRDD=sc.makeRDD(List(List(1,2),List(3,4),List(5,6),List(7)), 2)
//flatMap 扁平化
val flatMapRdd: RDD[Int] = listRDD.flatMap(data=>data)
//golm 将分区内的数据合并成一个数组
val glomRdd: RDD[Array[List[Int]]] = listRDD.glom()
//groupBy 分组
val groupByKeyRdd: RDD[(Int, Iterable[Int])] = flatMapRdd.groupBy(_%2)
val rdd: RDD[Int] = sc.makeRDD(1 to 20,2)
//sample 抽样函数 返回的是RDD
val sampleRdd: RDD[Int] = rdd.sample(false,0.3)
//takeSample 抽取指定个数 返回的是集合
val sampleRDD1: Array[Int] = rdd.takeSample(false,2)
//distinct 去重,可以指定去重后的分区个数
val distinctRdd: RDD[Int] = rdd.distinct()
//coalesce 重新分区 缩减分区
val coalRdd: RDD[Int] = rdd.coalesce(1)
//repartition 重新分区 增加分区
val repartitionRdd: RDD[Int] = rdd.repartition(3)
//sortBy 排序 入参:排序字段 排序规则 默认升序
val sortRdd: RDD[Int] = rdd.sortBy(ele=>ele,false)
//pipe 执行脚本
val pipeRdd: RDD[String] = rdd.pipe("/1.sh")
wordCount简单版本和复炸版本:
//建立配置文件对象
val conf = new SparkConf().setMaster("local[*]").setAppName("MY")
//创建sc对象
val sc = new SparkContext(conf)
val strList: List[String] = List("Hello Scala", "Hello Spark", "Hello World")
val rdd = sc.makeRDD(strList)
val rddWC: RDD[(String, Int)] = rdd.flatMap(_.split(" ")).map((_, 1)).groupBy(_._1).map {
case (word, itera) => (word, itera.size)
}
rddWC.collect().foreach(println)
println("==================================================================================")
val rdd2: RDD[(String, Int)] = sc.makeRDD(List(("Hello Scala", 2), ("Hello Spark", 3), ("Hello World", 2)))
val rdd1WC: RDD[(String, Int)] = rdd2.flatMap {
case (words, count) => words.split(" ").map(word => (word, count))
}.groupBy(_._1).map {
case (word, counts) => (word, counts.map(_._2).sum)
}
rdd1WC.collect().foreach(println)
val rdd1: RDD[Int] = sc.makeRDD(List(1,2,3,4,5,6))
val rdd2: RDD[Int] = sc.makeRDD(List(,4,5,6,7,8,9))
//union 合集
val unionRdd: RDD[Int] = rdd1.union(rdd2)
//intersection 交集
val intersectionRdd: RDD[Int] = rdd1.intersection(rdd2)
//subtract 差集 分区数相同并且分区内数据个数相同,否则会抛异常
val subRdd: RDD[Int] = rdd1.subtract(rdd2)
//拉链 分区数相同并且分区内数据个数相同,否则会抛异常
val zip: RDD[(Int, Int)] = rdd1.zip(rdd2)
1)、partitionBy:指定分区类型,可以自定义,进行重新分区
2)、reduceByKey:根据key进行聚合,入参代表分区和分区间的计算函数
3)、groupByKey:根据key把value进行组合,把value组成一个集合
reduceByKey和groupByKey的区别:
4)、aggregateByKey:指定初始值,分区函数和分区间函数不一致
5)、foldByKey:指定初始值,分区内和分区间计算函数相同
6)、combineByKey:根据key聚合,入参分别为:规定value的格式、value累加的函数、分区间的数据聚合函数
注:reduceByKey、aggregateByKey、foldByKey、combineByKey,底层调用combineByKeyWithClassTag函数,这4个聚合函数,只是是否有初始值、分区计算函数和分区间计算函数是否相同
7)、sortByKey:按照key排序,默认升序排序,key需要实现Ordered接口
8)、mapValues:只对value进行函数操作
9)、join:两个RDD的相连,类似sql,也具有左连接、右连接、全连接等算子
10)、cogroup:对本RDD的本身先进行聚合,再进行合并
object KVTransformationRDD1 {
def main(args: Array[String]): Unit = {
//建立配置文件对象
val conf = new SparkConf().setMaster("local[*]").setAppName("MY")
//创建sc对象
val sc = new SparkContext(conf)
val rdd = sc.makeRDD(List(("a",1),("b",5),("a",5),("b",2)))
//partitionBy 指定分区
val partitionBy: RDD[(String, Int)] = rdd.partitionBy(new MyOwnDefPartition(2))
//reduceByKey 根据key聚合
val reduceByKeyRdd: RDD[(String, Int)] = rdd.reduceByKey(_+_)
//groupByKey 根据key分组
val groupByKey: RDD[(String, Iterable[Int])] = rdd.groupByKey()
val groupByKeySum: RDD[(String, Int)] = groupByKey.map {
case (k, v) => (k, v.sum)
}
//aggregateByKey 入参:初始值 分区内函数 分区间函数
val aggByKey: RDD[(String, Int)] = rdd.aggregateByKey(0)((_+_),(_+_))
//foldByKey 入参 初始值 分区和分区间函数一致
val foldByKeyRdd: RDD[(String, Int)] = rdd.foldByKey(0)(_+_)
//combineByKey 入参 value的类型 分区内函数 分区间函数
val combineByKeyRdd: RDD[(String, Int)] = rdd.combineByKey(
data => data,
(da: Int, v) => da + v,
(da1: Int, da2: Int) => da1 + da2
)
//求平均数
//groupByKey方式
val avgGroupByKey: RDD[(String, Int)] = rdd.groupByKey().map {
case (k, v) => (k, v.sum / v.size)
}
//reduceByKey方式
val avgReduceByKey: RDD[(String, Int)] = rdd.map {
case (word, num) => (word, (num, 1))
}.reduceByKey {
case (acc1, acc2) => (acc1._1 + acc2._1, acc1._2 + acc2._2)
}.map {
case (word, sum) => (word, sum._1 / sum._2)
}
//combineByKey方式
val avgCombineByKey: RDD[(String, Int)] = rdd.combineByKey(
(_, 1),
(t1: (Int, Int), v) => (t1._1 + v, t1._2 + 1),
(t2: (Int, Int), t3: (Int, Int)) => (t2._1 + t3._1, t2._2 + t2._2)
).map {
case (word, sum) => (word, sum._1 / sum._2)
}
avgCombineByKey.collect().foreach(println)
//关闭sc
sc.stop()
}
}
//自定义拦截器
class MyOwnDefPartition(partitions: Int) extends Partitioner{
override def numPartitions: Int = partitions
override def getPartition(key: Any): Int = {
val tup: (String, Int) = key.asInstanceOf[(String,Int)]
if (tup == "a"){
1
}else{
0
}
}
}
val rdd: RDD[(Int, String)] = sc.makeRDD(Array((3,"aa"),(6,"cc"),(2,"bb"),(1,"dd")))
//sortByKey 排序
val sortByKeyRdd: RDD[(Int, String)] = rdd.sortByKey()
//mapValues 相同的key对value操作
val mapValuesRdd: RDD[(Int, String)] = rdd.mapValues("||||" + _)
val rdd1: RDD[(Int, String)] = sc.makeRDD(Array((1, "a"), (2, "b"), (3, "c")))
val rdd2: RDD[(Int, Int)] = sc.makeRDD(Array((1, 4), (2, 5), (4, 6)))
val joinRdd: RDD[(Int, (String, Int))] = rdd1.join(rdd2)
val cogroupRdd: RDD[(Int, (Iterable[String], Iterable[Int]))] = rdd1.cogroup(rdd2)
//建立配置文件对象
val conf = new SparkConf().setMaster("local[*]").setAppName("MY")
//创建sc对象
val sc = new SparkContext(conf)
val logRdd: RDD[String] = sc.textFile("D:\\ideaWorkspace\\scala0105\\spark-0105\\input\\agent.log")
val resRdd: RDD[(String, List[(String, Int)])] = logRdd.map {
log => {
val fileds: Array[String] = log.split(" ")
(fileds(1) + "-" + fileds(fileds.length - 1), 1)
}
}.reduceByKey(_ + _).map {
case (pro, adCount) => {
(pro.split("-")(0), (pro.split("-")(1), adCount))
}
}.groupByKey().mapValues {
values => {
values.toList.sortBy(_._2).reverse.take(3)
}
}
resRdd.collect().foreach(println)
//关闭sc
sc.stop()
行动算子会触发整个任务的执行,因为转换算子是懒加载,并不会立即执行。
1)、reduce:对分区和分区间元素进行聚合,返回集合内数据类型
2)、collect:对数分区间数据进行聚合,返回数组,把executor的数据聚合在driver端
3)、foreach:对分区的数据进行遍历,针对于executor端
4)、count:计算RDD中元素个数
5)、first:取RDD中第一个元素
6)、take:取RDD中前几个元素
7)、takeOrdered:取排序后的RDD中前几个
8)、aggreate:对RDD中的元素进行聚合,参数:初始值、分区内函数、分区间函数,此算子初始值分别在分区内和分区间都参与运算
9)、fold:aggreate的简单版,代表分区内和分区间计算函数相同
10)、countByKey:统计KV类型RDD的key的数量
11)、save相关:saveAsTextFile、saveAsObjectFile、saveAsSequenceFile(正对KV类型RDD)
val rdd: RDD[(Int, String)] = sc.makeRDD(List((1, "a"), (1, "a"), (1, "a"), (2, "b"), (3, "c"), (3, "c")))
//reduce
rdd.reduce{
case (t1,t2) => (t1._1,t1._2)
}
//collect
rdd.collect()
//foreach
rdd.foreach(println)
//count
rdd.count()
//first
rdd.first()
//take
rdd.take(2)
//takeOrdered
rdd.takeOrdered(2)
//aggreate
rdd.aggregate((0,0))(
(t1:(Int,Int),v) =>(t1._1,t1._2),
(t2:(Int,Int),t3:(Int,Int)) => (t2._1,t3._2)
)
//fold
rdd.fold((0,"0"))(
(t2:(Int,String),t3:(Int,String)) => (t2._1,t3._2)
)
//countByKey
rdd.countByKey()
//save
rdd.saveAsTextFile("")
rdd.saveAsSequenceFile("")
rdd.saveAsObjectFile("")