共享变量(广播变量、累加器)

一、广播变量

        产生背景:在Spark中,每次任务执行时,都需要将变量从驱动程序发送到每个执行器。如果变量很大,这将导致网络传输和内存开销的增加,从而影响任务的性能。

        原理:广播变量可以将变量仅发送一次,然后在每个执行器上缓存,以便多个任务可以共享同一个变量,从而减少了网络传输和内存开销,提高了任务的性能。

# 代码实现
#1.将本地list标记成广播变量即可
broadcast =sc. broadcast(stu_info_list)
#2.使用广播变量,从broadcast对象中取出本地list对象即可
value = broadcast.value
#也就是先放进去broadcast内部,然后从broadcast内部在取出来用,中间传输的是broadcast这个对象了
#只要中间传输的是broadcast对象,,spark就会留意,只会给每个Executor发一份了,而不是傻傻的哪个分区要都给.
#cording:utf8
from pyspark import SparkConf,SparkContext

if __name__ == '__main__':
    conf = SparkConf().setMaster('local[*]').setAppName('test')
    sc = SparkContext(conf=conf)

    stu_info_list = [(1, "张大仙", 11),
                     (2, '王晓晓', 13),
                     (3, '张甜甜', 11),
                     (4, '王大力', 11)]

    # 1.将数据封装为广播变量
    broadcast = sc.broadcast(stu_info_list)

    score_info_rdd = sc.parallelize([
        (1, '语文', 99),(2, '数学', 99), (3, '英语', 99), (4, '编程', 99),
        (1, '语文', 99), (2, '编程', 99), (3, '语文', 99), (4, '英语', 99),
        (1, '语文', 99), (3, '英语', 99), (2, '编程', 99)])

    def rdd_func(data):
        id = data[0]
        name = ''
        '''使用id匹配名字'''
        '''使用广播变量'''
        for stu_info in broadcast.value:
            if id == stu_info[0]:
                name = stu_info[1]
        return name, data[1], data[2]

    print(score_info_rdd.map(rdd_func).collect())

'''
场景:本地集合对象 和 分布式集合对象(RDD) 进行关联的时候(如果使用join进行操作,会产生大量shuffle,从而降低分布式集群性能)
需要将本地集合对象封装为广播变量
作用:
    可以节省:
        1.网络IO的次数
        2.Executor的内存占用
'''

二、累加器

        需求:想要对map算子计算中的数据,进行计数累加,得到全部数据计算完后的累加结果。

#cording:utf8
from pyspark import SparkConf,SparkContext

if __name__ == '__main__':
    conf = SparkConf().setMaster('local[*]').setAppName('test')
    sc = SparkContext(conf=conf)

    rdd = sc.parallelize((1, 2, 3, 4, 5, 6, 7, 8, 9, 10))
    # 未使用累加器
    count = 0
    def count_func(data):
        global count
        count +=1
        print("当前计算次数为;", count)
    rdd.map(count_func).collect()
    print('计算总数为:', count)

使用累加器代码:

#cording:utf8
from pyspark import SparkConf,SparkContext

if __name__ == '__main__':
    conf = SparkConf().setMaster('local[*]').setAppName('test')
    sc = SparkContext(conf=conf)

    rdd = sc.parallelize((1, 2, 3, 4, 5, 6, 7, 8, 9, 10))

    # 使用累加器  注意使用累加器时通过血统关系调用也会计入总数中
    count = sc.accumulator(0)
    def count_func(data):
        global count
        count += 1
        print("当前计算次数为;", count)
    rdd.map(count_func).collect()
    print('计算总数为:', count)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

吗喽也是命

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

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

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

打赏作者

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

抵扣说明:

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

余额充值