用法背景:
RDD(Resilient Distributed Dataset):
弹性分布式数据集,是Spark中最基本的数据处理模型;代码中是一个抽象类,它代表一个弹性的、不可变、可分区、里面的元素可并行 计算的集合。
弹性
- 存储的弹性:内存与磁盘的自动切换;
- 容错的弹性:数据丢失可以自动恢复;
- 计算的弹性:计算出错重试机制;
- 分片的弹性:可根据需要重新分片。
分布式:数据存储在大数据集群不同节点上
数据集:RDD 封装了计算逻辑,并不保存数据
数据抽象:RDD 是一个抽象类,需要子类具体实现
不可变:RDD 封装了计算逻辑,是不可以改变的,想要改变,只能产生新的 RDD,在 新的 RDD 里面封装计算逻辑
可分区、能够并行计算;
RDD 可以将数据(元素)通过分区函数 放在多个分区中,然后将这些分区 通过任务 交给不同的Exectuor去执行,从而达到并行计算的目的;
同样,多个分区 也可以在一个Executor中执行,只是无法并行执行,如下代码中的示例
aggregate/aggregateByKey 就是针对 分区内 和 分区之间 执行不同或相同函数的转换算子;
用法:
aggregate(默认值,分区内函数,分区间函数):
rdd分区内每个元素先进行聚合,然后分区间 再进行聚合;
注意: 初始值 会参与分区内和分区间的计算;
aggregateByKey(默认值,分区内函数,分区间函数):
rdd分区内 所有元素先根据key进行分组,对每组内部的值之间 先进行聚合,然后分区间 根据key 再进行聚合;
注意: 初始值 只参与分区内的计算,不参与分区间计算
初始值的作用: 在对rdd中的每个元素进行遍历操作时(类似for循环每个元素,并对每个元素执行一个函数操作) ,由于第一个元素在执行函数时 没有其他元素可以交互,只能给一个默认值; 如 add(第一个参数,默认值);
示例代码:
# -*- coding: utf-8 -*-
"""
(C) rgc
All rights reserved
create time '2021/5/26 19:37'
Usage:
aggregate 用法
aggregateByKey 用法
"""
# 构建spark
from pyspark.conf import SparkConf
from pyspark.context import SparkContext
conf = SparkConf()
# 使用本地模式;且 executor设置为1个方便debug
conf.setMaster('local[1]').setAppName('rgc')
sc = SparkContext(conf=conf)
rdd = sc.parallelize([2, 1, 3, 4, 4], 1)
def seq_func(x, y):
"""
分区内的函数
:param x: 指 zeroValue 参数 也就是(2,0)
:param y: 指 具体的元素
:return: 元素的值==> 元素的累加,元素的个数
"""
return x[0] + y, x[1] + 1
def comb_func(x, y):
"""
分区间的函数
:param x: 第一个元素
:param y: 第二个元素
:return: 元素的值==> 分区间元素的累加结果,分区间元素的个数之和
"""
return x[0] + y[0], x[1] + y[1]
# aggregate:rdd分区内每个元素先进行聚合,然后分区间 再进行聚合;
# 注意: 初始值 会参与分区内和分区间的计算;
# 所以 每个分区内的一次初始值(5) + 分区内的元素(2+1+3+4+4) + 分区间的一次初始值(5) = 24
rdd_res = rdd.aggregate((5, 0), seq_func, comb_func)
print(rdd_res) # (24,5)
# aggregateByKey:rdd分区内 所有元素先根据key进行分组,对每组的值 先进行聚合,然后分区间 根据key 再进行聚合;
# 注意: 初始值 只参与分区内的计算,不参与分区间计算
rdd_res = rdd.map(lambda x: (x, 1)).aggregateByKey((1, 0), seq_func, comb_func)
print(rdd_res.collect()) # [(2, (2, 1)), (1, (2, 1)), (3, (2, 1)), (4, (3, 2))]
总结:
在一个RDD中,如果需要对 分区内和分区间 进行不同的操作,可以使用aggregate aggregateByKey 2种方法;
如果需要在聚合操作前根据key进行分组 则使用 aggregateByKey方法;否则使用aggregate方法;