RDD分区函数mapPartitions与foreachPartition解析

文章讲述了在Spark中,使用分区函数如mapPartitions和foreachPartition相对于map和foreach的优势,特别是在处理大数据时减少数据库连接的创建和释放,从而提高效率。通过示例展示了如何使用这些分区函数,并建议在涉及资源密集型操作时优先考虑使用分区函数。
摘要由CSDN通过智能技术生成
  • 分区函数
    在Spark中, 对于map算子和foreach算子都提供了分区函数, 分别为mapPartitions() 和 foreachPartition()

    map算子 和 foreach算子, 是针对RDD中每一个分区下每一个元素, 而分区函数则是针对每个分区的整个数据集

    假设有如下数据集的RDD:
    rdd = sc.parallelize([1,2,3,4,5,6,7,8,9,10],3)

    查看这个RDD中各个分区的结果:
    rdd.glom().collect()
    结果:
    [
        [1, 2, 3], 
        [4, 5, 6], 
        [7, 8, 9, 10]
    ] 

    执行相关的操作: 将分区内每一个元素 + 1返回

    def fn1(num):
        return num + 1

    rdd.map(fn1).glom().collect()
    结果为:
    [
        [2, 3, 4], 
        [5, 6, 7], 
        [8, 9, 10, 11]
    ]

    思考: fn1函数会被执行多少次呢?  10次, 在第一个分区内会被执行3次, 第二个分区会被执行3次, 第三个分区会被执行4次

    假设: 如果在fn1函数中, 执行连接数据库的操作, 然后读取数据库中数据, 处理完成后, 将连接数据库的对象关闭, 请问, 这个打开连接和 关闭数据库连接操作会被触发多少次呢? 至少会被触发执行10次(有多少条数据, 就会被触发执行多少次),每一次创建连接和释放连接都要花费时间和资源, 频繁创建和关闭也会造成一定的资源浪费

    思考: 打开连接和关闭连接, 由于业务要求, 必须放置到fn1中, 但是又想提升效率, 如何处理呢?

    处理方案: 引入分区函数, 将map替换为mapPartitions来实现, 分区函数是针对每一个分区进行处理的

    同样的案例:
    def fn1(arr):
        arr2 = []
        for e in arr:
            arr2.append(e + 1)
        return arr2

    rdd.mapPartitions(fn1).glom().collect()

    结果为:
    [
        [2, 3, 4], 
        [5, 6, 7], 
        [8, 9, 10, 11]
    ]

    此时 fn1函数只会被触发3次(rdd有多少个分区, 就会被触发多少次)

演示 foreach和foreachPartition函数

假设有如下数据集的RDD:
    rdd = sc.parallelize([1,2,3,4,5,6,7,8,9,10],3)

    查看这个RDD中各个分区的结果:
    rdd.glom().collect()
    结果:
    [
        [1, 2, 3], 
        [4, 5, 6], 
        [7, 8, 9, 10]
    ] 

    基于foreach 打印每一个数据

    def fn1(num):
        print(num)


    rdd.foreach(fn1)
    结果:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

    基于 foreachPartition打印:
    def fn1(partitionData):
        for e in partitionData:
            print(e)

    rdd.foreachPartition(fn1)

    结果:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

总结: 建议在使用map和foreach的时候, 建议更换mapPartitions和foreachPartition, 尤其是在函数中存在一些与资源相关的操作, 比如说 数据库的连接, IO操作。。。

分区函数: 作用在每一个分区上

非分区函数: 作用在每个分区的每一个元素上

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

留不住的人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值