flink(7) ProcessFunction API

ProcessFunction API (底层API)

普通的转换算子只能获取到当前的数据,或者加上聚合状态 如果RichFunction可以有生命周期方法,还可以获取运行时上下文,进行状态编程,但是都无法访问事件时间的时间戳信息和水位线相关的信息。

于是 dataStream API 提供了一系列的Low-Level转换算子。可以访问时间戳、watermark以及注册定时事件。还可以输出特定的一些事件,如超时事件。 Process Function 用来构建事件驱动的应用以及实现自定义业务逻辑  如:Flink SQL就是用Process Function实现的。

ProcessFunction 是唯一可以获取到时间相关信息的Api

Flink 提供了8个Process Function:

ProcessFunction

KeyedProcessFunction

CoProcessFunction

ProcessJoinFunction

BroadcastProcessFunction

KeyesBroadcastProcessFunction

ProcessWindowFunction

ProcessAllWindowFunction

 

KeyedProcessFunction 用来操作KeyedStream 。KeyedProcessFunction会处理流的每一个元素,输出为0个、1个或者多个元素。所有的ProcessFunction都继承自RichFunction接口 所以除了RichFunction 自带的 以外KeyedProcessFunction 额外有两个方法

def main(args: Array[String]): Unit = {
    val env = StreamExecutionEnvironment.getExecutionEnvironment
    val inputDataStream: DataStream[String] = env.socketTextStream("127.0.0.1", 9436)

    val dataStream = inputDataStream.map(data => {
      val dataArray = data.split(",")
      SensorReading(dataArray(0), dataArray(1).toLong, dataArray(2).toDouble)
    })

    // 检测每一个demo 温度是否连续上升,在10秒之内 
    //解决方法 每条数据都为他注册一个定时器 如果10秒之后 数据是连续上升的 就触发定时器 通过KeyedProcessFunction方法

    val warningStream = dataStream
      .keyBy("id")
      .process(new TempIncreWarining(10000L))
    warningStream.print()
    env.execute(" window test")
  }

//自定义KeyedProcessFunction 传入 k i o  k代表 key的类型 i 时输入类型 o 时输出类型
class TemIncreWarining(interval :Long) extends KeyedProcessFunction[Tuple,inputDemo,String]{

//由于需要跟之前的温度值做对比,所以将上一个温度保存成状态 
lazy val lastTempState:ValueState[Double] = getRuntimeContext.getState(new ValueStateDescriptor[Double]("lastTemp",classOf[Double]))

//为了方便删除定时器,还需要保存定时器的时间戳
lazy val curTimerTsState: ValueState[Long] = getRuntimeContext.getState(new ValueStateDescriptor[Double]("cur_timestamp",classOf[Double]))

//processElement 流中的每一个元素都会调用这个方法 ,调用结果会在Collector数据类型中输出 
    override def                     
processElement(value:inputDemo,ctx:KeyedProcessFunction[Tuple,inputDemo,String]#Context,out:Collector[String]):Unit = {
//timerService可以注册定时器(两种时间语义 都可以) 获取当前时间语义  获取当前watermark
//首先取出状态
val lastTemp = lastTempState.value()
val curTimerTs = curTimerTsState.value()

//将上次温度值的状态更新为当前数据的温度值
lastTempState.update(value.temperature)

//判断当前温度值,如果比之前温度高,并且没有定时器的话,注册10秒后的定时器
if(value.temperature > lastTemp && curTimerTs==0){
    val ts = cdx.timerService.currentProcessingTime()+interval//定时定时器的时间戳
    ctx.timerService().registerProcessingTimeTimer(ts)//注册定时器
    curTimerTsState.update(ts)
}
//如果温度下降,删除定时器
else if(value.temperature < lastTemp){
    ctx.timerService().deleteProcessingTimeTimer(curTimerTs)

    //清空状态
    curTimerTsState.clear()
}
}
//onTimer 是一个回调函数,当之前注册的定时器触发时调用
    override def onTimer(timestamp:Long,ctx:KeyedProcessFunction[Tuple,inputDemo,String]#OnTimerContext,out:Collector[String]):Unit ={
        out.collect(“温度值连续”+interval/1000 +“秒上升”)
        
        curTimerTsState.clear()
    }
}

Process Function 是一类特殊的函数类,是.process()方法的参数,DataStream/KeyedStream/ConnectedStream/WindowedStream .....等都可以调用.process()方法

传入的是不同的process function

如果注册了watermark。定时器的触发需要watermark的更新来触发

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值