Spark Pair RDD操作

Spark Pair RDD操作

1. 创建Pair RDD
val pairs = lines.map(x => (x.split(" ")(0), x)
2. Pair RDD的转化方法

表1 Pair RDD的转化方法(以键值对集合{(1,2), (3,4), (3, 6)}为例)

函数名目的示例结果
reduceByKey()合并具有相同键的值rdd.reduceByKey((x,y)=>x+y){(1,2), (3,10)}
groupByKey()对具有相同键的值进行分组rdd.groupByKey(){(1,[2]), (3, [4, 6])}
mapValues()对Pair RDD中的每个值应用而不改变键rdd.mapValues(x=>x+1){(1,3),(3,5),(3,7)}
keys()返回一个仅包含键的RDDrdd.keys{1,3,3}
values()返回一个仅包含值的RDDrdd.values{2,4,6}
sortByKey()返回一个根据键排序的RDDrdd.sortByKey(){(1,2), (3,4), (3, 6)}

表2 针对两个pair RDD的转化操作 (rdd={1,2},{3,4},{3,6}, other={(3,9)})

函数名目的示例结果
subtractBykey删掉RDD中与other RDD中键相同的元素rdd.subtractByKey(other){(1,2)}
join对两个RDD进行内连接rdd.join(other){(3,(4,9)), (3, (6,9))}
leftOuterJoin左外连接, 确保第一个RDD的键必须存在rdd.leftOuterJoin(other){(1, (2, None)),(3, (4, Some(9)),(3, (6, Some(9Ish )))}
rightOuterJoin右外连接, 确保第二个RDD的键必须存在rdd.rightOuterJoin(other){(3, (Some(4), 9)),(3,(Some(6), 9))}
cogroup将两个RDD具有相同键的数据分组到一起rdd.cogroup(other){(1, ([2],[])), (3, ([4,6], [9]))}
2.1 聚合操作

用combineByKey()求每个键对应平均值的数据流示意图:

分区1

key | value|
| ——| —–|
|coffee | 1|
|coffee | 2|
|panda | 3|

分区2

key | value|
| ——| —–|
|coffee | 9|

处理分区1的过程:

(coffee, 1) -> new key

accumulators[coffee] = createCombiner(1)

(coffee, 2) -> existing key

accululators[coffer] = mergeValue(accumulators[coffee], 2)

(panda, 3) -> new key

accumulators[panda] = createCombiner(3)

处理分区2的过程:

(coffee, 9) -> new key

accumulators[coffee] = createCombiner(9)

合并分区:

mergeConbiners(partation1.accumulators[coffee], partation2.accumulators[coffee])

以上用到的函数如下:

def createCombiner(value): (value, 1)

def mergeValue(accumulator, value): (accumulator[0]+value, accumulator[1]+1)

def mergeCombiners(accumulator1, accumulator2): (accumulator1[0]+accumulator2[0], accumulator1[1]+accumulator2[1]
2.2 数据分组

groupBykey()可以对RDD相同键的数据进行分组。对于一个类型K的键和一个类型V的值组成的RDD, groupByKey()操作返回的RDD结果是[K, Iterable[V]]。

注意:

rdd.reduceByKey(func)与rdd.groupByKey().mapValues(values=> value.reduce(func))等价, 但前者更为高效

3. Pair RDD的行动方法

表3 Pair RDD的行动操作(以键值对集合{(1,2), (3,4), (3,6)}为例)

函数名描述示例结果
countByKey()对每个键对应的元素分别计数rdd.countByKey(){(1,1), {3,2}}
collectAsMap()将结果以映射表的形式返回rdd.collectAsMap(){(1,2), (3,6)}
lookup(key)返回给定键对应的所有值rdd.lookup(3)[4,6]
3.1 数据分区

Spark程序可以通过分区来减少网络通信开销。分区并非对于所有场景都是有好处的:比如, 如果给定RDD只被扫描一遍,那么完全没有必要做分区, 只有当数据多次在诸如连接这种基于键的操作时,分区才会有帮助。

假设我们有一份不变的大文件**userData, 以及每5分钟产生的小数据**events, 现要求在每5分钟产出events数据后, userData对events做一次join操作。

未对userData使用partitionBy()时的数据流动示意图:

使用partitionBy()时的数据流动示意图:

3.2 获取RDD的分区方式
3.3 从分区总获益的操作
3.4 影响分区方式的操作
3.5 自定义分区方式
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值