Flink处理函数

本文介绍了ApacheFlink中的ProcessFunction,一种处理流数据的基本构建模块,包括其功能、如何处理KeyedState和定时器,以及低阶Join的实现方式。此外,还详细列举了Flink中不同类型的ProcessFunction及其应用场景。
摘要由CSDN通过智能技术生成

处理函数介绍

处理函数(PocessFunction)是Flink提供的一个低价的流处理Operator,允许返回所有流程序(无回环的)的基础构建模块:

  • events(流元素): ProcessFunction 可以被认为是一个可以处理Keyed Sate和定时器的FlatMapFunction。它通过调用输入流中接收到的每个事件来处理事件
  • state(仅在keyed stream中使用):ProcessFunction 允许访问Flink的Keyed State,可以通过RuntimeContext访问,这与其他有状态函数访问Keyed State的方式类似
  • timers(定时器,event time和processing time,仅在 keyed stream中):定时器允许应用程序对processing timeevent time的变化做出反应,每次对processElement(...)的调用都会得到一个Context对象,该对象允许访问元素事件事件的时间戳和TimeServerTimeServer可以用来对尚未发生的event-time或者processing- time 注册回调,当定时器的时间到达时,onTimer(…)方法会被调用,在这个调用期间,所有的状态都会限定到创建定时器就的键,并允许定时器操纵Keyed States。

低阶 Join

为了实现对两个输入流的低阶操作,应用程序可以使用CoProcessFunctionKeyedCoprocessFunction。这个函数被绑定到两个不同的输入,并获得对来自两个不同输入的记录的processElement1(…)和processElement2(…)单独调用。
实现低阶Join通常遵循以下模式:

  • 为了一个输入(或者两个输入)创建状态对象
  • 在从其输入接收元素时更新状态
  • 在接收到来自其他输入的元素时,探测状态并产生Join的结构

处理函数分类

Flink中提供了7个Process Function,他们分别是继承Abstract Rich Function(抽象富函数),分别如下:

  1. ProcessFuntion:流处理函数,对数据流中的每一个元素数据进行处理,processElement()方法用于处理输入流中的每一个元素并输出一个或者多个元素。支持定时器和状态处理
  2. KeydeProcessFunction:流处理键函数 和 ProcessFunction类似,只是它的输入流要求是KeyedStream。
  3. CoProcessFunction: 处理两个流的元素并产生一个输出流,为输入流中的每个元素调用,并可以产生零个或多个输出元素。CoFlatMapFunction相反,这个函数还可以通过提供CoProcessFunction.Context查询时间(事件和处理)和设置计时器。
  4. ProcessJoinFunction:处理两个Join流中的元素并产生一个输出
  5. BroadcastProcessFunction: 应用BroadcastConnectedStream的函数,该函数连接BroadcastStream,即具有广播状态的流和一个non-keyedDataStream
  6. KeyedBroadcastProcessFunction:应用于BrodcastConnectedStream的函数,它连接BroadcastStream,即一个具有广播状态的流和一个KeyedStream
  7. ProcessWindowFunction:用在基于Keyed(分组)窗口上使用处理额外信息

代码

这段代码是实现相同的累加
数据源是

li 4
wang 2
li 2

实现分组将第二个字段数字累加

package 复习
import org.apache.flink.api.common.state.{ValueState, ValueStateDescriptor}
import org.apache.flink.api.scala._
import org.apache.flink.streaming.api.functions.ProcessFunction
import org.apache.flink.streaming.api.scala.{DataStream, StreamExecutionEnvironment}
import org.apache.flink.util.Collector

object ProcssFunction {
  def main(args: Array[String]): Unit = {
    val env = StreamExecutionEnvironment.getExecutionEnvironment

    val ds: DataStream[(String, String)] = env.socketTextStream("localhost", 6666)
      .map(x => {
        val fileds: Array[String] = x.split(" ")
        (fileds(0), fileds(1))
      })
      ds.print()

    ds.keyBy(0)
      .process(new CountWithProcessFuntion)
      .print("proc")

    env.execute("test02")
  }
}

/**
 * 状态中的数据存储
 * @param key
 * @param count
 */
case class CountWithTimestamp(key:String,count:Long)

/**
 * 自定义处理函数
 */
class CountWithProcessFuntion extends ProcessFunction[(String,String),(String,Long)]{
  //  定义process function 中的状态
  lazy val state:
  ValueState[CountWithTimestamp] = getRuntimeContext.getState(new ValueStateDescriptor[CountWithTimestamp](
    "myState",
    classOf[CountWithTimestamp]
  ))

  /**
   * 对输入的每行数据做处理
   *
   * @param i
   * @param context
   * @param collector
   */
  override def processElement(i: (String, String), context: ProcessFunction[(String, String), (String, Long)]#Context, collector: Collector[(String, Long)]): Unit = {
    val current:CountWithTimestamp = state.value() match {
      case  null => CountWithTimestamp(i._1,1) // 初始化
      case CountWithTimestamp(key,count) => CountWithTimestamp(key,count+i._2.toLong)

    }
//    更新状态
    state.update(current)
//    输出
    collector.collect(state.value().key,state.value().count)

  }
//     定时器操作 --- 可以对输入数据做处理,也可以输出数据,可以注册定时器和销毁定时器
  override def onTimer(timestamp: Long, ctx: ProcessFunction[(String, String), (String, Long)]#OnTimerContext, out: Collector[(String, Long)]): Unit = super.onTimer(timestamp, ctx, out)
}
  • 11
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值