本文参考Zhen He
1、aggregate
原型
def aggregate[U: ClassTag](zeroValue: U)(seqOp: (U, T) => U, combOp: (U, U) => U): U
含义
aggregate是一个聚合函数,一个RDD分区后,产生多个Partition,在aggregate中需要指定两个处理函数,第一个函数用于对每个分区内部处理,第二个函数用于分区之间的处理。aggregate 的初始值作用于前后两个部分, 分区是严格按照顺序的,顺序不同aggregate 结果就不同。
示例
//分区顺序严重aggregate的结果,分区特点,先平均分配,多的依次放到序号大的分区
val z = sc.parallelize(List(1,2,3,4,5,6), 2)
//使用parallelize产生2个分区,可以使用mapPartitionWithIndex查看分区
//分区结果是(1,2,3)和(4,5,6)
z.aggregate(0)(math.max,_+_)
res0: Int = 9
特别注意:初始值 0 是加在分区的左边
//第一个参数0 表示将0放入到每个分区中,然后每个分区进行计算。每个分区之间汇总时,再次将0放入其中计算
//math.max表示对每个分区内部取最大值,第一个分区有(1,2,3),再加上0,所以是(0,1,2,3)取最大值
//_+_表示每个分区之间进行相加
val x = sc.parallelize(List(1,2,3,4,5,6,7,8,9), 3)
x.aggregate(5)(math.max,_+_)
res1: Int = 25
//分析三个分区为(1,2,3),(4,5,6),(7,8,9)其中aggregate的初始值为5
//每次分区计算数据为(5,1,2,3),(5,4,5,6),(5,7,8,9),分别取最大值,得到(5,6,9)
//分区之间使用 _+_ 计算时,再次将5,放入其中,所以变成(5,5,6,9)
//最后将其相加变成5+5+6+9=25
//字符串类型处理
val z = sc.parallelize(List("a","b","c","d","e","f"),2)
z.aggregate("x")(_ + _, _+_)
res2: String = xxdefxabc
//第一个分区集合中有("x","a","b","c") 分区内部的聚合结果为"xabc"
//由于是并行的聚合,所以"xabc"和"xdef"谁在前面和后面并不知道
//分区之间进行聚合时,集合变成了("x","xabc","xdef")
//两个高级的示例
val z = sc.parallelize(List("12","23","345","4567"),2)
z.aggregate("")((x,y) => math.max(x.length, y.length).toString, _+_)
res3: String = 42
//分为两个区("12","23")和("345","4567")
//由于需要使用两个函数,所以这里定义了一个闭包函数,集合中的每两个元素,取出最大的长度。
//每个分区进行比较时集合为("","12","34")、("","345","4567")
//每个分区聚合之后的结果为("2","4")
//分区之间进行聚合时,集合为("","2","4"),再次聚合结构可能是"24"也可能是"42"
val z = sc.parallelize(List("12","23","345","4567"),2)
z.aggregate("asd")((x,y) => math.min(x.length, y.length).toString, _+_)
res4: String = asd11
//分区后的结果为("12","23") ("345","456")
//分区内部应用初始值之后的结果为("asd","12","34") ("asd","345","456")
//每个分区中有三个元素,每个分区内部需要多次聚合,分为("asd","12")和("34")
//("asd","12")聚合结果是"2", 再与("34")聚合结果是"1"
//所以("asd","12","34") 聚合结果是"1"
//同理("asd","345","456") 聚合结果是"1"
//两个分区之间再次聚合,将初始值应用到其中,得到"asd11"
val z = sc.parallelize(List("12","23","345",""),2)
z.aggregate("")((x,y) => math.min(x.length, y.length).toString,_+_)
res5: String = 10
//分区后的结果为("12","23") ("345","")
//分区内部应用初始值之后的结果为("","12","23") ("","345","")
//有三个元素,需要多次聚合("","12") ("23")
//("","12")聚合结果是"0" 再与("23")聚合,得到的结果是"1"
//("","345")聚合结果是"0" 再与("")聚合,得到的结果是"0"
//最后两次结果相加,得到的是"10"
特别注意:为了说明分区顺序的重要性,请看下面的例子
val z = sc.parallelize(List("12","23","","345"),2)
z.aggregate("")((x,y) => math.min(x.length, y.length).toString,_+_)
res6: String = 11
//分区后的结果为("12","23") ("","345")
//分区内部应用初始值之后的结果为("","12","23") ("","","345")
//有三个元素,需要多次聚合("","12") ("23")
//("","12")聚合结果是"0" 再与("23")聚合,得到的结果是"1"
//("","")聚合结果是"0" 再与("345")聚合,得到的结果是"1"
//最后两次结果相加,得到的是"11"
2、aggregateByKey[Pair]
原型
def aggregateByKey[U](zeroValue: U)(seqOp: (U, V) ⇒ U, combOp: (U, U) ⇒ U)(implicit arg0: ClassTag[U]): RDD[(K, U)]
含义
aggregateByKey 也是一个聚合函数,一个RDD分区后,产生多个Partition,在aggregateByKey中需要指定两个处理函数,第一个函数用于对每个分区内部处理,第二个函数用于分区之间的处理。aggregateByKey的初始值只作用于每个分区内部,不影响分区之间聚合,分区是严格按照顺序的,顺序不同aggregateByKey结果就不同。
示例
3、cartesian
原型
def cartesian[U: ClassTag](other: RDD[U]): RDD[(T, U)]
含义
cartesian 笛卡尔积,两个RDD中的元素两两组合
示例
4、checkpoint
原型
def checkpoint()
含义
checkpoint 检查点机制,假设你在迭代1000次的计算中在第999次失败了,然后你没有checkpoint,你只能重新开始恢复了,如果恰好你在第998次迭代的时候你做了一个checkpoint,那么你只需要恢复第998次产生的rdd,然后再执行2次迭代完成总共1000的迭代,这样效率就很高,比较适用于迭代计算非常复杂的情况,也就是恢复计算代价非常高的情况,适当进行checkpoint会有很大的好处。
示例
5、coalesce, repartition
原型
def coalesce ( numPartitions : Int , shuffle : Boolean = false ): RDD [T]
def repartition ( numPartitions : Int ): RDD [T]
含义
repartition 表示对已经分区的数据重新分区,是coalesce 的一个简单应用
示例
6、cogroup [Pair], groupWith [Pair]
原型
def cogroup[W](other: RDD[(K, W)]): RDD[(K, (Iterable[V], Iterable[W]))]
def groupWith[W](other: RDD[(K, W)]): RDD[(K, (Iterable[V], Iterable[W]))]
含义
cogroup 超级分组,可以将3个key-value类型的RDD进行分组
示例
7、collect, toArray
原型
def collect[U: ClassTag](f: PartialFunction[T, U]): RDD[U]
def toArray(): Array[T]
含义
collect 将RDD数据转换成Scala中的数组并返回
示例
8、collectAsMap
原型
def collectAsMap(): Map[K, V]
含义
collectAsMap 和collect非常类似,但是,是将数据转换成key-value类型的Map
示例
9、combineByKey[Pair]
原型
def combineByKey[C](createCombiner: V => C, mergeValue: (C, V) => C, mergeCombiners: (C, C) => C): RDD[(K, C)]
含义
combineByKey 高效的实现按照key来聚合,通过在每一个分区内部先聚合,再在分区之间聚合。每个分区内部是通过迭代方式来聚合,效率非常高。
示例
10、context, sparkContext
原型
def compute(split: Partition, context: TaskContext): Iterator[T]
含义
context 返回创建RDD时的SparkContext
示例
11、count
原型
def count(): Long
含义
count 返回RDD中存储的元素的个数
示例
12、countApproxDistinct
原型
def countApproxDistinct(relativeSD: Double = 0.05): Long
含义
countApproxDistinct 近似统计RDD中不重复的值的个数,可以通过relativeSD 来确定统计精度,这种方式适合大规模,分布式的数据快速统计
示例
13、countApproxDistinctByKey [Pair]
原型
def countApproxDistinctByKey(relativeSD: Double = 0.05): RDD[(K, Long)]
含义
countApproxDistinctByKey 和 countApproxDistinct 类似,但是他是统计元组中的相同的key的个数,相比于其他统计方式,这种统计速度更快
示例
14、countByKey [Pair]
原型
def countByKey(): Map[K, Long]
含义
countByKey 和 count 类似,但是他是用于统计元组中每个相同的key出现的次数,最后返回的是一个元组
示例
15、countByValue [Pair]
原型
def countByValue(): Map[T, Long]
含义
countByValue 计算RDD中不同值出现的次数,以value作为统计的标准。分区统计时,这个操作会将信息合并到单个reduce中去。
示例