(四)spark之共享数据--广播变量

一、前述

Spark中因为算子中的真正逻辑是发送到Executor中去运行的,所以当Executor中需要引用外部变量时,需要使用广播变量。

二、广播变量介绍

比如数据库中一份公共配置表格,需要同步给各个节点进行查询。广播变量允许程序在每台机器上面缓存一个只读的变量,每台机器上的所有task共享这个只读变量。而不是每个任务保存一份拷贝。

如果将变量声明为广播变量,那么只是每个executor拥有一份,这个executor启动的task会共享这个变量,节省了通信的成本和服务器的资源。如果没有生命广播变量,那么有多少个任务就会产生多少个变量副本,对服务器资源消耗极大。

一个广播变量可以通过调用SparkContext.broadcast(v)方法从一个初始变量v中创建。广

播变量是v的一个包装变量,它的值可以通过value方法访问。

如图所示: 在Driver端声明广播变量a,Driver将广播变量a发送到所有的worker(executor)中,各executor内执行的task在用到该变量时,会直接在自己的worker中获取,这种获取方式不需要走网络传输,避免了IO消耗,提高了数据处理的性能。

如果没有这种广播机制,那么Driver在执行过程中就需要将该变量发送到所有的Task中,以便task执行时使用,尤其在大集群、多任务的环境下,这种方式往往需要远程传输,对集群资源和程序性能的消耗是不言而喻的。

下面附上声明广播变量的样例代码供参考:

val conf = new SparkConf()

conf.setMaster("local").setAppName("brocast")

val sc = new SparkContext(conf)

val list = List("hello xasxt")

val broadCast = sc.broadcast(list)

val lineRDD = sc.textFile("./words.txt")

lineRDD.filter { x => broadCast.value.contains(x) }.foreach { println}

sc.stop()

需要注意的是:

1)不能将一个RDD使用广播变量广播出去

2)广播变量只能在Driver端定义,不能在Executor端定义。

3)在Driver端可以修改广播变量的值,在Executor端无法修改广播变量的值。

4)如果executor端用到了Driver的变量,如果不使用广播变量在Executor有多少task就有多少Driver端的变量副本。

5、如果Executor端用到了Driver的变量,如果使用广播变量在每个Executor中只有一份Driver端的变量副本。

猜你喜欢

转载自blog.csdn.net/zhtzh312/article/details/94734054