Spark学习实例(Python):共享变量Shared Variables

通常在使用Spark算子函数,比如使用map()或者reduce函数我们向函数传入条件时,函数内部可以使用驱动程序中定义的变量,但是这样会使集群中所有任务都会得到变量新的副本,这些副本的更新不会传播回驱动程序,导致读写共享变量效率低下或者内存溢出,为了解决这个问题Spark提供了两种共享变量类型:广播变量和累加器

  • 广播变量:用来高效分发较大对象,只能在Driver定义,不能在Executor端定义,同时RDD不存储数据所以不能广播出去
  • 累加器:用来对信息进行聚合,常用场景reduce()

不使用广播变量,直接定义一个变量list,然后在filter()来判断元素是否存在list中,实现代码如下:

from pyspark import SparkContext

if __name__ == '__main__':
    sc = SparkContext(appName="broadcast", master="local[*]")
    list = [2, 4, 6, 8]
    data = [1, 2, 3, 4, 5]
    rdd = sc.parallelize(data)
    print(rdd.filter(lambda x: list.__contains__(x)).collect())
    # [2, 4]
    sc.stop()

定义的list变量在驱动端Driver创建的,但是要到Executor端运行,Driver端会把list以task形式拷贝到Executor端,如果有很多task那么就会有很多list复制过去,这个list非常大的时候就会造成内存溢出,关系图如下所示:

使用广播变量,变量只会被发送到各节点一次,同时存放在Executor的BlockManager中,实现代码如下:

from pyspark import SparkContext

if __name__ == '__main__':
    sc = SparkContext(appName="broadcast", master="local[*]")
    list = [2, 4, 6, 8]
    bclist = sc.broadcast(list)
    data = [1, 2, 3]
    rdd = sc.parallelize(data)
    print(rdd.map(lambda x: bclist.value[x]).collect())
    # [4, 6, 8]
    sc.stop()

关系图如下:

累加器,对作业执行过程事件进行计数,实现代码如下:

from pyspark import SparkContext

if __name__ == '__main__':
    sc = SparkContext(appName="broadcast", master="local[*]")
    data = [1, 2, 3]
    rdd = sc.parallelize(data)
    accumulator = sc.accumulator(0)
    rdd.map(lambda x: accumulator.add(1)).collect()
    print(accumulator.value)
    # 3
    sc.stop()

关系图如下:

累加器在Driver端定义赋初始值,在Executor端更新,最后在Driver端读取最后的值。

 

Spark学习目录:

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值