Flink累加器的结果只能在作业结束以后才能得到。这就意味着,如果是一个一直不间断执行的流处理程序是无法得到累加器结果的。只有批处理成功,也就是会结束的flink程序才能得到累加器结果。
(我试过强行停止正在执行的flink程序无法得到结果,不知道由于某些异常导致flink程序停止是否可以得到累加器的结果)。
最直接的累加器(Accumulator)就是计数器(Counter)。可以通过Accumulator.add(V value)方法增加累加器的值。在Flink程序的最后,Flink job会收集每个节点各自的和进行累加然后发回给客户端。
这对于程序的调试或者得到数据的某些信息(比如数据的行数)会有用。
程序
下面是一个简单的计算文件行数的flink程序。其中包含几个关键步骤:
- 创建累加器
- 注册累加器
- 使用累加器
- 得到累加器结果
package it.kenn.acc;
import org.apache.flink.api.common.JobExecutionResult;
import org.apache.flink.api.common.accumulators.IntCounter;
import org.apache.flink.api.common.functions.RichMapFunction;
import org.apache.flink.configuration.Configuration;
import org.apache.flink.streaming.api.datastream.SingleOutputStreamOperator;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
/**
* 累加器测试
*/
public class AccumulatorTest {
public static void main(String[] args) throws Exception {
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
AccumulatorTest accumulatorTest = new AccumulatorTest();
accumulatorTest.process(env);
}
public void process(StreamExecutionEnvironment env) throws Exception {
SingleOutputStreamOperator<String> registerAccStream = env
.readTextFile("$HOME/LearningFlink/flink-java/src/main/resources/hbase-site.xml")
.map(new RichMapFunction<String, String>() {
//1.创建累加器
private IntCounter numLines = new IntCounter();
@Override
public void open(Configuration parameters) throws Exception {
//2.注册累加器
getRuntimeContext().addAccumulator("num-lines", numLines);
}
@Override
public String map(String s) throws Exception {
//3.使用累加器
this.numLines.add(1);
return s;
}
});
registerAccStream.print();
//4. 得到累加器结果,注意结果是从execute方法的返回值中得到的
JobExecutionResult result = env.execute();
Object accRes = result.getAccumulatorResult("num-lines");
System.out.println("文件共:"+accRes + "行。");
}
}
输出结果
可以数一下下面文件确实17行,计数器输出的结果也是17行,没有错。
12> <?xml version="1.0"?>
12> <?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
10> <value>/hbase</value>
10> </property>
4> <value>localhost:2181</value>
8> </property>
8> <property>
2> <configuration>
2> <property>
2> <name>hbase.zookeeper.quorum</name>
11> </configuration>
7> <value>2181</value>
5> </property>
5>
5> <property>
5> <name>hbase.zookeeper.property.clientPort</name>
9> <name>zookeeper.znode.parent</name>
文件共:17行。