Spark 2.X 上累加器(Accumulators)不能用了
2017-04-06 本文已影响410人
俺是亮哥
本文基于Spark2.1.0版本
今天整理累加器的知识点时,发现实例化一个Accumulator对象,编译无法通过:
![](https://img.haomeiwen.com/i5432088/e38c6de79cb9032f.png)
查了一下Spark2.x的API,发现对Accumulator类的定义发生了变化:
![](http://upload-images.jianshu.io/upload_images/5432088-e6a3ecd6835de03d.png)
![](http://upload-images.jianshu.io/upload_images/5432088-7983dadf51fd67b2.png)
新的累加器创建的方法如下:
![](http://upload-images.jianshu.io/upload_images/5432088-f15fcee358a5fee4.png)
![](http://upload-images.jianshu.io/upload_images/5432088-0886f9bddb783daa.png)
![](http://upload-images.jianshu.io/upload_images/5432088-82504db8d2ef4de3.png)
可以看出,新版的累加器有了如下的改良:
1,不用传初始化值参数,默认是从0开始;
2,创建累加器时,可以指定累加器的名字,这样在Driver 4040 Web UI的Task显示时,可以看到该名字的累加器在各Task中的实际的值(如果不指定累加器名字,则不会在Web UI上显示)-- 这点我说的不准确,旧的累加器类也有这个功能,只不过我一直没用过,惭愧。。。
3,新增了reset方法,可以重置该累加器归零(还有几个新的方法,不一一举例)
So,按照API的指示,修改如下:
![](http://upload-images.jianshu.io/upload_images/5432088-eb4e60824e98f849.png)
在Driver 的4040 Web UI上观察,发现Task table增加了 Accumulators 列,能看到每个Task上的叫做ErrorCnt 的累加器的值(可以同时定义多个累加器)
![](http://upload-images.jianshu.io/upload_images/5432088-41c34df51dd1bf02.png)
迭代器使用起来很简单,很方便,但在使用过程中一定要注意(新手容易忽略):
因为Spark 相同的Task有可能被重复执行多次(容错性导致),所以累加器的值很有可能被累加多次,那么得到的结果就不准确了,所以一般把累加器放在行动操作中来使用,只有这样,Spark才会把每个任务对各累加器的修改应用一次。
下面举一个foreach的行动操作的例子:
![](http://upload-images.jianshu.io/upload_images/5432088-4524c8dcb844908c.png)
![](http://upload-images.jianshu.io/upload_images/5432088-bf5d16ecd5c9e9d9.png)
java代码如下:
![](http://upload-images.jianshu.io/upload_images/5432088-01b1c48ea398cea2.png)