Spark中的RDD&&算子
RDD:
弹性的分布式的数据集
弹性:在一定范围内进行变化不影响整体的情况
分布式:RDD本身没有分布式概念,里面的数据是分布式存储的
数据集:数据的集合
rdd是spark计算的核心,也是计算的瞬时结果。
特点:
a.rdd是一个抽象的概念,partition是具体的概念
b.rdd里的数据是不可变的
c.每个rdd经过一个函数的转换把结果赋给下一个rdd
d.rdd可以并行计算
五大特性
a.一组分区的集合
b.一个函数作用于所有的切片
函数是算子里作为参数的那个函数
c.每个rdd依赖于其他的rdds
d.rdd可以重新分区
e.数据的本地性
当前节点数据优先考虑在当前节点内存计算
如果条件不满足,可以使用其他节点帮助计算
rdd的容错机制
如果计算过程中某个位置出现错误,根据运算过程图(有向无环图),向父级依赖查找
数据,如果有数据直接进行以下步骤的计算,如果没有数据,继续向上级查找,直到找
到有数据的位置为止,最坏的情况是从hdfs上重新读取数据重新计算。如果当前达到某
个阈值还没有结果,重新找一个位置重新进行计算,但是原计算不停止,哪个先计算出
来使用哪个结果,另一个抛弃。
算子:
本质就是高阶函数
普通集合调用高阶函数
RDD调用的就是算子
分类:
转换算子(transformation)
做任务的步骤,但是不执行,不提交。
a.创建算子
把原始数据转成RDD类型
b.缓存算子
对某个RDD做持久化操作
行动算子(action)
提交job任务,执行代码,把RDD转成具体的数据
常见算子
transformation
1,cartesian(求笛卡尔积)
对两个集合做笛卡尔积返回各对应的键值对
2,coalesce
用于将RDD进行重分区,使用HashPartitioner。
且该RDD的分区个数等于numPartitions个数。
如果shuffle设置为true,则会进行shuffle(洗牌)。
(当重分区数少于默认默认分区数时,就按照numPartition设置,跟是否开启shuffle无关)
(当重分区数大于默认默认分区数时,若开启shuffle,就按照numPartition设置,若不开启shuffle,则还是以默认的分区数)
3,cogroup
对RDD进行合并,最多有4个RDD合并
对每一个RDD的key进行合并,在同一个RDD中有key相同的就到同一个元组中
4,distinct
将原始RDD中重复出现的元素进行过滤,返回一个新生成的RDD
即原RDD中每个元素在新生成的RDD中只出现一次
排序
5,filter
对元素进行过滤,每个元素都执行里面的函数,返回boolean类型,为true就保留
object filter {
def main(args: Array[String]): Unit = {
val conf=new SparkConf().setMaster("local[1]").setAppName("x")
val sc=new SparkContext(conf)
val rdd = sc.parallelize(List(1,2,3,4,5))
//对元素进行过滤,对每个元素应用f函数,返回值为true的元素在RDD中保留,返回为false的将过滤掉
rdd.filter(_%2==0).collect().toList.foreach(println)
}
}
6,flatMap
object flatMap {
def main(args: Array[String]): Unit = {
val conf = new SparkConf().setMaster("local[3]").setAppName("app")
val sc = new SparkContext(conf)
val list = List("aa,bb,cc","ddd,eee,fff","gggg,hhhh,iiii")
val rdd = sc.parallelize(list)
//map的变换操作是对原RDD中的每个元素进行一对一的操作,生成的RDD中元素的数量与原RDD中元素数量相同,
//但flatMap可以将每个元素进行一对多的变换操作
println(rdd.flatMap(_.split(",")).collect().toList)
// rdd.flatMap(_.split(",")).foreach(println)
7,groupByKey
将Key/Value型的RDD中的元素按照Key值进行汇聚,Key值相同的Value值会合并为一个序列
object groupByKey {
def main(args: Array[String]): Unit = {
val conf = new SparkConf().setMaster("local[3]").setAppName("app")
val sc = new SparkContext(conf)
val list = List(("animal","dog"),("animal","cat"),("BD1803/book","java"),("BD1803/book","python"),("BD1803/book","spark"))
val rdd = sc.parallelize(list)
//将Key/Value型的RDD中的元素按照Key值进行汇聚,Key值相同的Value值会合并为一个序列。
rdd.groupByKey().collect().toList.foreach(println)
}
action
1,count
返回RDD中的元素数量。
object count {
def main(args: Array[String]): Unit = {
val conf=new SparkConf().setMaster("local[5]").setAppName("xc")
val sc=new SparkContext(conf)
val rdd=sc.parallelize(List(5,5,6,9,6,9,9))
println(rdd.count())
}
}
2,countByKey
对key进行数量统计以Map的形式输出
object countByKey {
def main(args: Array[String]): Unit = {
val conf=new SparkConf().setMaster("local[2]").setAppName("sd")
val sc=new SparkContext(conf)
val RDD=sc.parallelize(List(("animal","dog"),("animal","cat"),("BD1803/book","java"),("BD1803/book","python"),("BD1803/book","spark")))
println(RDD.countByKey())
}
}
3,countByValue
对整个键值对进行数量统计,并不是只针对Value
object countByValue {
def main(args: Array[String]): Unit = {
val conf=new SparkConf().setMaster("local[5]").setAppName("sd")
val sc=new SparkContext(conf)
val rdd=sc.parallelize(List(("animal","dog"),("animal","cat"),("BD1803/book","java"),("BD1803/book","python"),("BD1803/book","spark")))
println(rdd.countByValue())
}
}
4,first
取rdd中第一个元素
object first {
def main(args: Array[String]): Unit = {
val conf=new SparkConf().setMaster("local[5]").setAppName("da")
val sc=new SparkContext(conf)
val rdd=sc.parallelize(List(5,5,6,9,5,2,5))
println(rdd.first())
}
}
5,take
取前rdd集合前(n)个
object take {
def main(args: Array[String]): Unit = {
val conf=new SparkConf().setMaster("local").setAppName("sd")
val sc=new SparkContext(conf)
val rdd=sc.parallelize(List(5,5,6,2,8,9,6,9,6,9))
rdd.take(4).foreach(println)
}
}
6,top
用于从RDD中,按照默认(降序)或者指定的排序规则,返回前num个元素
takeOrdered和top类似,只不过以和top相反的顺序返回元素。
object top {
def main(args: Array[String]): Unit = {
val conf=new SparkConf().setMaster("local[2]").setAppName("da")
val sc=new SparkContext(conf)
val rdd=sc.parallelize(List(5,5,6,2,8,9,6,9,6,9))
//用于从RDD中,按照默认(降序)或者指定的排序规则,返回前num个元素。
println(rdd.top(3).toList)
//takeOrdered和top类似,只不过以和top相反的顺序返回元素。
println(rdd.takeOrdered(9).toList)
}
}
7,takeSample
第一个参数withReplacement,取是否放回,是否有重复元素
第二个参数num,样本取的数量
第三个参数seed,随机种子
object takeSample {
def main(args: Array[String]): Unit = {
val conf = new SparkConf().setMaster("local[3]").setAppName("app")
val sc = new SparkContext(conf)
val list = List(1,2,3,4,5,6,7,8,9,10)
val rdd = sc.parallelize(list,3)
println(rdd.takeSample(false,10,System.currentTimeMillis()).toList)
}
}