注意点:存在多个action算子的时候,accumulator可能存在重复计算的情况
验证:
第一步先获取一个accumulator
//accumulator
LongAccumulator accum = sc.sc().longAccumulator();
此时进行累加求和操作:
JavaRDD<Integer> map = sc.parallelize(Arrays.asList(1, 2, 3, 4)).map(x -> {
accum.add(1);
return x;
});
map.count();
System.out.println("value:"+accum.value());
输出:
value:4
此时,再添加一个算子:
JavaRDD<Integer> map = sc.parallelize(Arrays.asList(1, 2, 3, 4)).map(x -> {
accum.add(1);
return x;
});
map.count();
System.out.println("value:"+accum.value());
map.foreach(x -> System.out.println(x));
System.out.println("value2:"+accum.value());
此刻输出为:
value:4
value2:8
原因解释:虽然在后续的操作中未使用accum进行累加操作,但是值还是增加了,原因是因为accumulator与spark的懒加载机制一样,action会触发之前的transformation操作,所以当后面调用foreach算子时,accum又重新计算了一次,导致最后的值为8.
解决方法:
在action操作之后加入:
map.cache();
将job之间的依赖进行分隔。
欢迎加群大家一起学习大数据~群里还有很多资料可供参考~
大数据大佬菜鸡交流群 575419003