功能描述:统计输入文件中有多少空行
// 在Java中累加空行
JavaRDD<String> rdd = sc.textFile(args[1]);
final Accumulator<Integer> blankLines = sc.accumulator(0);
JavaRDD<String> callSigns = rdd.flatMap(new FlatMapFunction<String, String>() {
private static final long serialVersionUID = 8729890404213554820L;
@Override
public Iterable<String> call(String line) throws Exception {
if (line.equals(" ")) {
blankLines.add(1);
}
return Arrays.asList(line.split(" "));
}
});
callSigns.saveAsTextFile("output.txt");
System.out.println("Blank lines:"+blankLines.value());
累加器是Spark两个共享变量中的一个。它提供了将工作节点中的值聚合到驱动器程序中的简单语法。累加器的一个常见用途是在调试时对作业执行过程中的事件进行计数。
在如上示例中,我们创建了一个叫作blankLines 的Accumulator[Int] 对象,然后在输入中看到一个空行时就对其加1。执行完转化操作之后,就打印出累加器中的值。注意,只有在运行saveAsTextFile() 行动操作后才能看到正确的计数,因为行动操作前的转化操作flatMap() 是惰性的,所以作为计算副产品的累加器只有在惰性的转化操作flatMap() 被saveAsTextFile() 行动操作强制触发时才会开始求值。
当然,也可以使用reduce() 这样的行动操作将整个RDD 中的值都聚合到驱动器中。只是我们有时希望使用一种更简单的方法来对那些与RDD 本身的范围和粒度不一样的值进行聚合。聚合可以发生在RDD 进行转化操作的过程中。在前面的例子中,我们使用累加器在读取数据时对错误进行计数,而没有分别使用filter() 和reduce()。
总结起来,累加器的用法如下所示。
•通过在驱动器中调用SparkContext.accumulator(initialValue) 方法,创建出存有初始值的累加器。返回值为org.apache.spark.Accumulator[T] 对象,其中T 是初始值initialValue 的类型。
• Spark 闭包里的执行器代码可以使用累加器的+= 方法(在Java 中是add)增加累加器的值。
• 驱动器程序可以调用累加器的value 属性(在Java 中使用value() 或setValue())来访问累加器的值。