Spark 支持 2 种类型的共享变量,广播变量(broadcast variable)和累加器(accumulator)。
广播变量
广播变量允许程序员缓存一个只读的变量在每台机器上面,而不是每个任务保存一份拷贝。
通过调用SparkContext.broadcast(v)
方法从一个初始变量v中创建广播变量,通过value访问。
示例:
scala> spark-shell
scala> val broadcastVar = sc.broadcast(Array(1, 2, 3))
broadcastVar: org.apache.spark.broadcast.Broadcast[Array[Int]] = Broadcast(0)
scala> broadcastVar.value
res0: Array[Int] = Array(1, 2, 3)
scala> val broadcastVar = sc.broadcast(Array(4,3,2))
broadcastVar: org.apache.spark.broadcast.Broadcast[Array[Int]] = Broadcast(1)
scala> broadcastVar.value
res1: Array[Int] = Array(4, 3, 2)
显示:
广播变量创建以后,可以在集群的任何函数中使用它来代替变量v,这样就不需要再次传递变量v到每个节点上。另外,为了保证所有的节点得到广播变量具有相同的值,对象v在广播之后不能被修改。
累加器
累加器是一种只能通过关联操作进行“加”操作的变量,它能高效的应用于并行操作中。用来实现counters
和sums
。
Spark原生支持数值类型的累加器,开发者可以自己添加支持的类型。如果创建了一个具名的累加器,它可以在spark的UI中显示。这对于理解运行阶段(running stages)的过程有很重要的作用(python中还不被支持)。
调用SparkContext.accumulator(v)
方法从一个初始变量v中创建累加器。运行在集群上的任务,可以通过"add"
方法或者"+="
操作来给它加值。但是,只有驱动程序可以使用value
方法来读取累加器的值。
示例:
scala> val accum = sc.accumulator(0, "My Accumulator")
scala> sc.parallelize(Array(1, 3, 5, 7)).foreach(x => accum += x)
scala> accum.value
显示:
开发者可以利用子类AccumulatorParam创建自己的累加器类型。 AccumulatorParam接口有两个方法:
(1)zero
方法为你的数据类型提供一个“0 值”(zero value);
(2)addInPlace
方法计算两个值的和。
Spark也支持用SparkContext.accumulableCollection
方法累加一般的scala集合类型。