process function 相对于前文所述的map、flatmap、filter算子来说,最大的区别是开发人员对数据的处理逻辑拥有更大的自由度。同时,ProcessFunction 继承了 RichFunction,因而具备了 open、close、getRuntimeContext等方法。
不同类型的datastream上,应用 process function 时,flink 提供了大量不同类型的 process function,让其针对不同的datastrean 拥有更具有针对性的功能。
- 在普通的datastream上调用process算子,传入的是 ProcessFunction
SingleOutputStreamOperator<Tuple2<String, String>> s1 = stream1.process(new ProcessFunction<String, Tuple2<String, String>>() {
// 可以使用 生命周期 open 方法
@Override
public void open(Configuration parameters) throws Exception {
// 可以调用 getRuntimeContext 方法拿到各种运行时上下文信息
RuntimeContext runtimeContext = getRuntimeContext();
runtimeContext.getTaskName();
super.open(parameters);
}
@Override
public void processElement(String value, ProcessFunction<String, Tuple2<String, String>>.Context ctx, Collector<Tuple2<String, String>> out) throws Exception {
// 可以做测流输出
ctx.output(new OutputTag<String>("s1", Types.STRING),value);
// 可以做主流输出
String[] arr = value.split(",");
out.collect(Tuple2.of(arr[0], arr[1]));
}
// 可以使用 生命周期close方法
@Override
public void close() throws Exception {
super.close();
}
});
- 在 keyedStream上调用 process 算子,传入的是 KeyedProcessFunction
// 对s1流进行keyby分组
KeyedStream<Tuple2<String, String>, String> keyedStream = s1.keyBy(tp2 -> tp2.f0);
// 然后在keyby后的数据流上调用process算子
SingleOutputStreamOperator<Tuple2<Integer, String>> s2 = keyedStream.process(new KeyedProcessFunction<String, Tuple2<String, String>, Tuple2<Integer, String>>() {
@Override
public void processElement(Tuple2<String, String> value, KeyedProcessFunction<String, Tuple2<String, String>, Tuple2<Integer, String>>.Context ctx, Collector<Tuple2<Integer, String>> out) throws Exception {
// 此处没做聚合,直接输出:把f0变整数,把f1变大写
out.collect(Tuple2.of(Integer.parseInt(value.f0), value.f1.toUpperCase()));
}
});
s2.print();