spark2学习笔记之(三)——共享变量:累加器(Accumulator)

spark有两种类型的共享变量:累加器和广播变量。累加器用来对信息进行聚合,广播变量用来高效分发较大的对象。

1、累加器使用

应用场景:

我们想在并发读取日志文件的同时统计出总共有多少空行。这需要一个全局变量,spark里提供了一个累加器可以实现这种效果。

spark 2.X的代码如下:

SparkConf conf = new SparkConf();
conf.setAppName("RealNameDS");
conf.setMaster("local");

JavaSparkContext jsc = new JavaSparkContext(conf);
		
JavaRDD<String> lineRDD = jsc.textFile(input);
		
LongAccumulator blankLines = jsc.sc().longAccumulator("blankLines");
lineRDD.flatMap(new FlatMapFunction<String, String>() {

	@Override
	public Iterator<String> call(String line) throws Exception {
		if("".equals(line.trim())) {
			blankLines.add(1);
		}
		return Arrays.asList(line.split(" ")).iterator();
	}
});

//第一个行动操作
wordRDD.count();
System.out.println("blank lines: " + blankLines.value());
//第二个行动操作
wordRDD.saveAsTextFile("output.txt");
System.out.println("blank lines: " + blankLines.value());

2、累加器的坑与容错性

Accumulator的值只有在driver里才能访问,在工作节点上的task不能访问累加器的值。从task的角度来看,累计器是一个只写变量。查看Accumulator的值也只能在driver里。

RDD的转化操作是惰性的,所以作为计算副产品的累加器只有在行动操作之后才能有真实值。

注意:每经过一个行动操作,都会触发RDD重新计算,所以累加器的值只有在第一个行动操作之后是准确的。上面例子中两次打印的blankLines.value()值不一样。如果需要使用多次则使用cache或persist操作切断依赖。 

由于spark集群会自动重新执行失败或较慢的任务来应对有错误的或者比较慢的机器,所以在RDD转化操作中使用的累加器是不能保证绝对可靠的。转化操作中的累加器最好只在调试时使用。如果想要一个无论在失败还是重复计算时都绝对可靠的累加器,必须把它放在foreach()这样的行动操作中。

3、自定义累加器

自定义的累加器要保证里面的操作同时满足交换律和结合律,例如要找累加的值中的最大值。

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值