在spark里操作和函数是两个东西。
操作分为转化操作和行动操作两种,区别是:
转化操作:返回一个新的RDD,惰性求值
行动操作:向驱动器程序(driver)返回结果,或者把结果写入外部系统,触发实际计算
函数是用在转化操作内的,用来自己定义具体怎么转化的,详见第3小节。
1、针对各个元素的转化操作
基本RDD
函数名 | 目的 | 注意 |
filter(Func) | 找满足条件的返回 | 使用的Function一定是Boolean返回类型 |
map(Func) | 对每个元素处理,1对1返回 | |
flatMap ( ) | 对每个元素处理,1对N返回 | 使用FlatMapFunction,返回迭代器 |
mapToPair ( ) | 对每个元素处理,1对1返回Tuple | 使用PairFunction |
distinct ( ) | 去重 | |
sample | 对RDD采样 | |
partitionBy ( ) | 数据重新分区 | 转为哈希分区:new HashPartitioner(100) |
Pair类型的RDD可以使用上述基本RDD上的所有操作,除此之外,还有一些特有的转化操作。由于Pair RDD中都是二元组,所以需要传递的函数应当是能够操作二元组的,而不是独立元素的。
在Pair RDD上有一组针对键的操作,它们在名字上类似reduce、combine,可以组合具有相同键的值,这些操作返回的是RDD,惰性计算,因此属于转化操作而不是行动操作。
Pair类型的RDD
函数名 | 目的 | 注意 |
reduceByKey (Func) | 合并具有相同键的值 | 使用Function2,输入2个值,输出1个值 |
foldByKey (zero) (Func) | 带初始值的reduceByKey | |
groupByKey () | 按键分组,值简单罗列 | |
combineByKey (createCombiner, mergeValue, mergeCombiners) | 和aggregate类似,用于对每个键求平均值,可以同时累加两个数。mergeValue把当前值合并到已知键上,mergeCombiners合并不同分区上的结果 | 只写value怎么处理就行,不用管key,因为默认是对key相等的才触发value的处理 |
mapValues (Func) | 保持键不动,对每个值应用Func | 可以把一个二元组的值再映射成二元组 |
flatMapValues (Func) | 同上,只是返回的是迭代器 | 通常用于符号化,如x=>(x to 5) |
keys ( ) | 返回一个仅包含键的RDD,不去重 | |
values ( ) | 返回一个仅包含值的RDD,不去重 | |
sortByKey ( ) | 返回一个根据键排序的RDD | |
2、伪集合操作(转化操作)
基本的集合操作:交、并、补、笛卡尔积都支持,有的操作会去重,涉及去重的需要经过shuffle过程,性能开销大。
基本RDD
函数名 | 目的 | 示例 |
intersection ( ) | 求两个RDD共同的元素,会去重 | rdd.intersection (other) |
union ( ) | 求两个RDD并集,不去重 | rdd.union (other) |
subtract ( ) | 移除一个RDD中的内容,会去重 | rdd.subtract (ohter) |
cartesian ( ) | 与另一个RDD的笛卡尔积,规模大时开销巨大 | rdd.cartesian (other) |
Pair类型的RDD也还是RDD,因此同样支持上述基本RDD上的集合操作,除此之外,还支持一些特有的集合操作。
Pair类型的RDD
函数名 | 目的 | 示例 |
subtractByKey ( ) | 删掉RDD中键与other RDD中键相同的元素 | rdd.subtractByKey (other) |
join ( ) | 对两个RDD内连接,相同的key,value罗列 | rdd.join (other) |
rightOuterJoin ( ) | 第一个RDD的键必须存在 | rdd.rightOuterJoin (other) |
leftOuterJoin ( ) | 第二个RDD的键必须存在 | rdd.leftOuterJoin (other) |
cogroup ( ) | 将两个RDD中拥有相同键的数据分组到一起 | rdd.cogroup (other) |
3、操作里使用的计算函数种类(都是接口)
这些函数要根据输入、输出参数的数量和类型来记忆,直接看函数名称反倒不容易记。
接口名 | 输人值 | 输出值 | 实现方法 | 在哪个操作中用 |
Function <T,R> | 1个 | 1个 | R call (T) | map、filter |
Function2 <T1,T2,R> | 2个 | 1个 | R call (T1, T2) | aggregate、fold |
FlatMapFunction <T,R> | 1个 | N个 | Iterable<R> call (T) | flatMap |
PairFunction <T,K,V> | 1个 | 1个二元组 | Tuple2<K, V> call (T) | mapToPair |
PairFlatMapFunction<T,K,V> | 1个 | N个二元组 | Iterable<Tuple2<K,V>> call (T) | flatMapToPair |
DoubleFunction<T> | 1个 | 1个double | Double call (T) | mapToDouble |
DoubleFlatMapFunction<T> | 1个 | N个double | Iterable<Double> call (T) | flatMapToDouble |
4、行动操作
执行到行动操作时,RDD才会真的开始计算。
以求平均值为例,解释reduce()、fold()和aggregate()的区别。求平均值需要统计两个值sum和count。reduce()可以遍历整个RDD,把元素累加起来,求出sum;但是如果需要在一个初始值上开始累加所有元素,就得需要fold()了。如果想同时累加出sum和count,就得用aggregate(),它支持对一个二元组的两个元素同时进行累加,但是还需要提供另外一个函数,用来将不同节点上累加后的结果合并成全局结果。
基本RDD
函数名 | 目的 | 注意 |
reduce (Func) | 并行整合RDD中所有数据 | |
fold (zero) (Func) | 和reduce一样,但是需要提供初始值 | |
aggregate (zero) (seqOp) (comOp) | 和reduce相似,但是可以返回不同类型的函数 | |
collect ( ) | 返回RDD中所有元素 | 要求所有数据必须能一起放入单台机器的内存中 |
count ( ) | RDD中元素个数 | |
countByValue ( ) | 各个元素在RDD中出现次数 | 可以直接用来求wordCount |
take (num) | 从RDD中返回num个元素 | |
top (num) | 从RDD中返回最前面的num个元素 | |
takeOrdered (num) (ordering) | 从RDD中按顺序返回前num个元素 | |
takeSample | 从RDD中返回任意一些元素 | |
foreach (Func) | 对RDD中每个元素使用Func函数 | |
所有基本RDD上的传统行动操作也都可以用在Pair RDD上。Pair RDD上还有一些额外的行动操作。
Pair类型RDD
函数名 | 目的 | 注意 |
countByKey ( ) | 对每个键对应的元素分别计数 | |
collectAsMap ( ) | 将结果以map形式返回 | |
lookup (key) | 返回指定key的所有值 | |