Process Function API(底层)
Process Function API(底层)
我们之前学习的转换算子是无法访问事件的时间戳信息和水位线信息的。而这 在一些应用场景下,极为重要。例如MapFunction这样的map转换算子就无法访问 时间戳或者当前事件的事件时间。
基于此,DataStream API提供了一系列的Low-Level转换算子。可以访问时间戳、watermark以及注册定时事件。还可以输出特定的一些事件,例如超时事件等。 Process Function用来构建事件驱动的应用以及实现自定义的业务逻辑(使用之前的 window函数和转换算子无法实现)。例如,Flink SQL就是使用 Process Function实现的。
ProcessFunction可以看作是最底层的API
Flink提供了 8 个 Process Function:
-
ProcessFunction -
KeyedProcessFunction -
CoProcessFunction -
ProcessJoinFunction -
BroadcastProcessFunction -
KeyedBroadcastProcessFunction -
ProcessWindowFunction -
ProcessAllWindowFunction
Keyed Process Function
这里我们重点介绍 KeyedProcessFunction。
KeyedProcessFunction用来操作 KeyedStream。KeyedProcessFunction 会处理流 的每一个元素,输出为 0 个、1 个或者多个元素。所有的 Process Function 都继承自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参数一样,提供了上下文的一些信息,例如定时器 触发的时间信息(事件时间或者处理时间)。
自定义一个KeyedProcessFunction
/**
* 三个参数是:key的数据类型
* 输入的数据类型
* 输出的数据类型
*/
class MyKeyedProcessFunction extends KeyedProcessFunction[String, SensorReading, String] {
var myState: ValueState[Int] = _
override def open(parameters: Configuration): Unit = {
myState = getRuntimeContext.getState(new ValueStateDescriptor[Int]("valueState", classOf[Int]))
}
override def processElement(i: SensorReading, context: KeyedProcessFunction[String, SensorReading, String]#Context,
collector: Collector[String]): Unit = {
//获取当前的key,其实还可以直接从数据里面获取
context.getCurrentKey
//获取当前数据的时间戳
context.timestamp()
//获取当前的watermark
context.timerService().currentWatermark()
/**
* 定义一个一分钟后触发的定时器,当定时器触发后,会执行onTimer方法
* 可以注册多个定时器,定时器的区别就是时间戳
* 不同的定时器执行时都是在onTimer方法里面
*/
context.timerService().registerEventTimeTimer(context.timestamp() + 60 * 1000l)
/**
* 定时器的删除,删除也是传入一个参数,参数就是时间戳
*/
// context.timerService().deleteEventTimeTimer()
}
/**
*
* @param timestamp是定时器触发的时间 ,我们可以将根据不同的时间戳来判断不同的定时器,然后执行不一样的方法
* @param ctx
* @param out
*/

最低0.47元/天 解锁文章
676

被折叠的 条评论
为什么被折叠?



