PySpark reduce reduceByKey用法

用法

  • reduce:对rdd内部 元素 进行迭代操作
    reduce方法 分区内和分区间调用相同的用户给定的函数;
    先在每个分区内执行完用户给定的函数后,将每个分区的结果通过collect()方法统计到Driver端;然后在Driver端 通过用户给定的函数进行分区间操作;
    其实:reduce方法调用的元素间的迭代操作就是用的 python自带的 functools reduce方法

PySpark reduce reduceByKey用法_第1张图片

  • reduceByKey:先根据key对每个分区内的数据进行分组,然后调用用户指定的函数对每个key的values进行 迭代操作; 然后分区间再进行一次操作;
    内部调用的就是 combineByKey方法;
  • combineByKey和aggregateByKey区别
    两者类似,都是在分区内和分区间执行函数;
    只是combineByKey没有默认值,这时 如add时先获取第一个数据,由于没有其他数据进行相加,则直接返回 自己 add(1,None) ⇒ 1
    而aggregateByKey由于有默认值 假设为 2; 则add(1,2) ⇒ 3

示例代码

# -*- coding: utf-8 -*-
"""
(C) rgc
All rights reserved
create time '2021/5/30 21:01'

Usage:

"""
# 构建spark
from functools import reduce

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], 2)
_list = [[3, 5], [2, 3], [3, 6]]
rdd1 = sc.parallelize(_list, 2)


def reduce_func(x, y):
    """
    reduce累积
    :param x: 第一个数据
    :param y: 第二个数据
    :return: ((((2*1)*3)*4)*4)
    """
    return x * y


# reduce方法 分区内和分区间调用相同的用户给定的函数;
# 先在每个分区内执行完用户给定的函数后,将每个分区的结果通过collect()方法统计到Driver端;然后在Driver端 通过用户给定的函数进行分区间操作;
# 其实:reduce方法调用的元素间的迭代操作就是用的  python自带的 functools reduce方法
rdd_res = rdd.reduce(reduce_func)
print(rdd_res)  # 96
# 通过spark.reduce实现list中每个值向上层展开;
print(rdd1.reduce(lambda x, y: x + y))  # [3, 5, 2, 3, 3, 6]
# 通过functools.reduce实现list中每个值向上层展开;
print(reduce(lambda x, y: x + y, _list))  # [3, 5, 2, 3, 3, 6]

# reduceByKey:先根据key对每个分区内的数据进行分组,然后调用用户指定的函数对每个key的values进行 操作; 然后分区间的结果再进行一次操作;
# 其实:调用的就是 combineByKey
rdd_res1 = rdd.map(lambda x: (x, 2)).reduceByKey(reduce_func)
print(rdd_res1.collect())  # [(2, 2), (4, 4), (1, 2), (3, 2)]

总结

  • 调用pyspark的reduce可以当做调用python自带的functools.reduce只是可以在多机器分布式的运行而已;
  • pyspark.reduce是行动算子(也就是执行到reduce代码才实际执行RDD流程),因为内部包含了collect()方法
  • reduceByKey分区内先进行了一次操作,所以有效的减少了落盘的数据量(shuffle操作),从而在分区间操作时效率高一些;

你可能感兴趣的:(PySpark,PySpark,reduce,reduceByKey)