Flink ProcessFunction
分层API
Flink提供三层API. 每个API在简洁性和表达之间提供不同的权衡,并针对不同的用例
-
1、SQL/Table API (dynamic tables)
-
2、DataStream API(streams, windows)
-
3、ProcessFunction(event,state,time)
ProcessFunction
不要跟ProcessWindowFunction混为一谈。
ProcessFunction是一个低阶的流处理操作,它可以访问流处理程序的基础构建模块:
-
1、事件(event)(流元素)。
-
2、状态(state)(容错性,一致性,仅在keyed stream中)。
-
3、定时器(timers)(event time和processing time, 仅在keyed stream中)。
ProcessFunction可以看作是一个具有keyed state 和 timers访问权的FlatMapFunction
-
1、通过RuntimeContext访问keyed state 。
-
2、计时器允许应用程序对处理时间和事件时间中的更改作出响应。对processElement(…)函数的每次调用都获得一个Context对象,该对象可以访问元素的event time timestamp和TimerService。
-
3、TimerService可用于为将来的event/process time瞬间注册回调。当到达计时器的特定时间时,将调用onTimer(…)方法。在该调用期间,所有状态都再次限定在创建计时器时使用的键的范围内,从而允许计时器操作键控状态。
Flink提供了8个Process Function:
-
ProcessFunction
-
KeyedProcessFunction
-
CoProcessFunction
-
ProcessJoinFunction
-
BroadcastProcessFunction
-
KeyedBroadcastProcessFunction
-
ProcessWindowFunction
-
ProcessAllWindowFunction
KeyedProcessFunction
KeyedProcessFunction用来操作KeyedStream。
KeyedProcessFunction会处理流的每一个元素,输出为0个、1个或者多个元素。
所有的ProcessFunction都继承自RichFunction接口,所以都有open()、close()和getRuntimeContext()等方法。
而KeyedProcessFunction[KEY, IN, OUT]还额外提供了两个方法:
processElement(v: IN, ctx: Context, out: Collector[OUT])
流中的每一个元素都会调用这个方法,调用结果将会放在Collector数据类型中输出。Context可以访问元素的时间戳,元素的key,以及TimerService时间服务。Context还可以将结果输出到别的流(side outputs)。
onTimer(timestamp: Long, ctx: OnTimerContext, out: Collector[OUT])
是一个回调函数。当之前注册的定时器触发时调用。参数timestamp为定时器所设定的触发的时间戳。Collector为输出结果的集合。OnTimerContext和processElement的Context参数一样,提供了上下文的一些信息,例如定时器触发的时间信息(事件时间或者处理时间)。
TimerService 和 定时器(Timers)
Context和OnTimerContext所持有的TimerService对象拥有以下方法:
-
currentProcessingTime(): Long
返回当前处理时间 -
currentWatermark(): Long
返回当前watermark的时间戳 -
registerProcessingTimeTimer(timestamp: Long): Unit
会注册当前key的processing time的定时器。当processing time到达定时时间时,触发timer。 -
registerEventTimeTimer(timestamp: Long): Unit
会注册当前key的event time 定时器。当水位线大于等于定时器注册的时间时,触发定时器执行回调函数。 -
deleteProcessingTimeTimer(timestamp: Long): Unit
删除之前注册处理时间定时器。如果没有这个时间戳的定时器,则不执行。 -
deleteEventTimeTimer(timestamp: Long): Unit
删除之前注册的事件时间定时器,如果没有此时间戳的定时器,则不执行。
当定时器timer触发时,会执行回调函数onTimer()。
注意定时器timer只能在keyed streams上面使用。
案例:KeyedProcessFunction如何操作KeyedStream
需求:监控温度传感器的温度值,如果温度值在十秒钟之内(processing time)连续上升,则报警。
package cn.kgc.kb09.ProcessFunction
import cn.kgc.kb09.Tramsfrom.WaterSensor
import org.apache.flink.api.common.state.{
ValueState, ValueStateDescriptor}
import org.apache.flink.configuration.Configuration
import org.apache.flink.streaming.api.TimeCharacteristic
import org.apache.flink.streaming.api.functions.KeyedProcessFunction
import org.apache.flink.streaming.api.functions.timestamps.BoundedOutOfOrdernessTimestampExtractor
import org.apache.flink.streaming.api.scala._
import org.apache.flink.streaming.api.windowing.time.Time
import org.apache.flink.util.Collector
/**
* KeyedProcessFunction
* 判断水位线持续上涨,报警
*/
object ProcessFunctionDemo1 {
def main(args: Array[String]): Unit = {
val env = StreamExecutionEnvironment.getExecutionEnvironment
env.setParallelism(1)
env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
// 从socket端口接收数据
val stream = env.socketTextStream("192.168.247.201",7777)
val dataStream = stream.map(data => {
val arrays = data.split(",")
WaterSensor(arrays(0).trim