Flink中的处理函数
之前所介绍的流处理API,无论是基本的转换、聚合,还是更为复杂的窗口操作,其实都是基于DataStream进行转换的,所以就可以统称为DataStream API。
但是在Flink的更底层,我们可以不定义任何具体的算子(比如map,fliter,或者window),而只是提炼出一个统一的“处理”(process)操作,它是所有转换算子中的一个概括性的表达,开发者可以自定义处理逻辑,所以这一层的接口就叫做“处理函数”。Flink中各层之间的关系图如下(最底层就是处理函数):
一、处理函数的功能和使用
我们之前学习的转换算子,一般只是针对于某种具体操作来定义的,能够拿到的信息比较有限。如果我们想要访问事件的时间戳,或者当前的水位信息,这些在转换算子中都是做不到的。跟时间相关的操作,目前我们只会用窗口来处理,而在很多应用需求中,要求我们对时间有更精细的控制,需要获取水位线,甚至要“把控时间”、定义什么时候做什么事,这就不是基本的时间窗口能实现的了。
这时就需要使用底层的处理函数,处理函数提供了一个“定时服务”,我们可以通过它访问流中的事件(event)、时间戳(timestamp)、水位线(watermark),甚至可以注册“定时事件”。而且处理函数继承了AbstractRichFunction抽象类,所以拥有富函数类的所有特性,同样可以访问状态(state)和其他运行时信息。此外,处理函数还可以直接将数据输出到侧输出流(side output)中。所以,处理函数是最为灵活的处理方法,可以实现这种自定义的业务逻辑。
二、处理函数的分类
Flink提供了8个不同的处理函数:
(1)、ProcessFunction
这是最基本的处理函数,基于DataStream直接调用.process()时作为参数传入。
(2)、KeyedProcessFunction
这是对流按key分区后的处理函数,基于KeyedStream调用.process()时作为参数传入。
(3)、ProcessWindowFunction
这是开窗之后的处理函数,也是全窗口函数的代表。基于WindowedStream调用.process()时作为参数传入。
(4)、ProcessAllWindowFunction
这也是开窗之后的处理函数,基于AllWindowedStream调用.process()时作为参数传入。
(5)、CoProcessFunction
合并(connect)两条流之后的处理函数,基于ConnectedStreams调用.process()时作为参数传入。
(6)、ProcessJoinFunction
间隔联结两条流之后的处理函数,基于IntervalJoined调用.process()时作为参数传入。
(7)、BroadcastProcessFunction
广播连接流处理函数,基于BroadcastConnectedStream调用.process()时作为参数传入。
(8)、KeyedBroadcastProcessFunction
按键分区的广播连接流处理函数,同样是基于 BroadcastConnectedStream 调用.process()时作为参数传入。