Spark累加器与广播变量

This commit is contained in:
罗祥 2019-06-04 15:07:11 +08:00
parent 1656a8e12a
commit 8240087521

View File

@ -12,8 +12,8 @@
在Spark中提供了两种类型的共享变量累加器(accumulator)与广播变量(broadcast variable)
+ 累加器:用来对信息进行聚合,主要用于累计计数等场景;
+ 广播变量:主要用于在节点间高效分发大对象。
+ **累加器**:用来对信息进行聚合,主要用于累计计数等场景;
+ **广播变量**:主要用于在节点间高效分发大对象。
## 二、累加器
@ -52,9 +52,9 @@ val addMore = (x: Int) => x + more
**2. Spark中的闭包**
在实际计算时Spark会将对RDD操作分解为TaskTask运行在Worker Node上。在执行之前Spark会对任务进行闭包如果闭包内涉及到自由变量则程序会进行拷贝并将副本变量放在闭包中之后闭包被序列化并发送给每个执行者。因此当在foreach函数中引用`counter`它将不再是Driver节点上的`counter`,而是闭包中的副本`counter`,默认情况下,副本`counter`更新后的值不会回传到Driver所以计数器的最终值仍然为零。
在实际计算时Spark会将对RDD操作分解为TaskTask运行在Worker Node上。在执行之前Spark会对任务进行闭包如果闭包内涉及到自由变量则程序会进行拷贝并将副本变量放在闭包中之后闭包被序列化并发送给每个执行者。因此当在foreach函数中引用`counter`它将不再是Driver节点上的`counter`,而是闭包中的副本`counter`,默认情况下,副本`counter`更新后的值不会回传到Driver所以`counter`的最终值仍然为零。
需要注意的是在Local模式下**有可能**执行foreach的Worker Node与Diver处在相同的JVM并引用相同的原始`counter`,这时候更新可能是正确的,但是在集群模式下却不行。所以在遇到此类问题时应优先使用累加器。
需要注意的是在Local模式下有可能执行`foreach`的Worker Node与Diver处在相同的JVM并引用相同的原始`counter`,这时候更新可能是正确的,但是在集群模式下一定不正确。所以在遇到此类问题时应优先使用累加器。
累加器的原理实际上很简单就是将每个副本变量的最终值传回Driver由Driver聚合后得到最终值并更新原始变量。