Process Function是Flink中low-level的方法。
在Process Function中可以获取到非常多的元数据信息,所以process function中可以非常的灵活处理数据。
Process Function中可以获取:
events: 数据流事件信息state: Flink状态信息,通过RuntimeContext获取Timer: 定时器信息,比如事件时间和处理时间等
process中的类需要实现KeyedProcessFunction和CoProcessFunction。
官方给的例子:
收集数据统计条数,并且当60秒内不再收到新的数据就触发窗口计算,输出统计结果
// 在process中实现KeyedProcessFunction
DataStream<Tuple2<String, Long>> result = stream
.keyBy(value -> value.f0)
.process(new CountWithTimeoutFunction());
//model
public class CountWithTimestamp {
public String key;
public long count;
public long lastModified;
}
//自定义process function
public class CountWithTimeoutFunction
extends KeyedProcessFunction<Tuple, Tuple2<String, String>, Tuple2<String, Long>> {
//记录状态 ValueState
private ValueState<CountWithTimestamp> state;
@Override
public void open(Configuration parameters) throws Exception {
//初始化状态
state = getRuntimeContext().getState(new ValueStateDescriptor<>("myState", CountWithTimestamp.class));
}
@Override
//处理每一条事件数据
public void processElement(
Tuple2<String, String> value, //事件数据
Context ctx, //上下文
Collector<Tuple2<String, Long>> out //output收集器
) throws Exception {
// 获取当前的计数
CountWithTimestamp current = state.value();
if (current == null) {
current = new CountWithTimestamp();
current.key = value.f0;
}
// 更新状态
current.count++;
current.lastModified = ctx.timestamp();
state.update(current);
// 重置计时器
ctx.timerService().registerEventTimeTimer(current.lastModified + 60000);
}
@Override
//计时器触发
public void onTimer(
long timestamp, //当前timestamp
OnTimerContext ctx, //上下文
Collector<Tuple2<String, Long>> out //输出收集器
) throws Exception {
// 获取当前状态
CountWithTimestamp result = state.value();
// 检查当前时间是不是状态时间的60秒之后
if (timestamp == result.lastModified + 60000) {
// 提交数据
out.collect(new Tuple2<String, Long>(result.key, result.count));
}
}
}