Scala Flink:ProcessWindowFunction

Scala Flink:ProcessWindowFunction,scala,apache-flink,flink-streaming,Scala,Apache Flink,Flink Streaming,我最近在Flink的新版本中学习ProcessWindowFunction。它表示ProcessWindowFunction支持全局状态和窗口状态。我使用ScalaAPI来尝试一下。到目前为止,我可以让全局状态工作,但我没有任何运气使它成为窗口状态。我所做的是处理系统日志,并计算由主机名和严重性级别键入的日志数。我想计算两个相邻窗口之间日志计数的差异。下面是我实现ProcessWindowFunction的代码 class LogProcWindowFunction extends Proces

我最近在Flink的新版本中学习
ProcessWindowFunction
。它表示
ProcessWindowFunction
支持全局状态和窗口状态。我使用ScalaAPI来尝试一下。到目前为止,我可以让全局状态工作,但我没有任何运气使它成为窗口状态。我所做的是处理系统日志,并计算由主机名和严重性级别键入的日志数。我想计算两个相邻窗口之间日志计数的差异。下面是我实现
ProcessWindowFunction
的代码

class LogProcWindowFunction extends ProcessWindowFunction[LogEvent, LogEvent, Tuple, TimeWindow] {
  // Create a descriptor for ValueState
  private final val valueStateWindowDesc = new ValueStateDescriptor[Long](
    "windowCounters",
    createTypeInformation[Long])

  private final val reducingStateGlobalDesc = new ReducingStateDescriptor[Long](
    "globalCounters",
    new SumReduceFunction(),
    createTypeInformation[Long])

  override def process(key: Tuple, context: Context, elements: Iterable[LogEvent], out: Collector[LogEvent]): Unit = {
    // Initialize the per-key and per-window ValueState
    val valueWindowState = context.windowState.getState(valueStateWindowDesc)
    val reducingGlobalState = context.globalState.getReducingState(reducingStateGlobalDesc)
    val latestWindowCount = valueWindowState.value()
    println(s"lastWindowCount: $latestWindowCount ......")
    val latestGlobalCount = if (reducingGlobalState.get() == null) 0L else reducingGlobalState.get()
    // Compute the necessary statistics and determine if we should launch an alarm
    val eventCount = elements.size
    // Update the related state
    valueWindowState.update(eventCount.toLong)
    reducingGlobalState.add(eventCount.toLong)
    for (elem <- elements) {
      out.collect(elem)
    }
  }
}
类LogProcWindowFunction扩展ProcessWindowFunction[LogEvent,LogEvent,元组,TimeWindow]{
//为ValueState创建描述符
private final valueStateWindowDesc=新的ValueStateDescriptor[长](
“窗口计数器”,
createTypeInformation[长])
private final val reduceingstateglobaldesc=新的reduceingstatescriptor[Long](
“全球计数器”,
新的SumReduceFunction(),
createTypeInformation[长])
覆盖def进程(键:元组,上下文:上下文,元素:Iterable[LogEvent],out:Collector[LogEvent]):单位={
//初始化每键和每窗口值状态
ValueWindowsState=context.windowState.getState(valueStateWindowDesc)
val reduceingglobalstate=context.globalState.getreduceingstate(reduceingstateglobaldesc)
val latestWindowCount=valueWindowsState.value()
println(s“lastWindowCount:$latestWindowCount……”)
val latestGlobalCount=if(reduceingglobalstate.get()=null)0L else reduceingglobalstate.get()
//计算必要的统计数据并确定我们是否应该发出警报
val eventCount=elements.size
//更新相关状态
ValueWindowsState.update(eventCount.toLong)
还原GlobalState.add(eventCount.toLong)

对于(elem每个窗口状态的作用域是一个窗口实例。对于上面的
过程
方法,每次调用它时,一个新窗口都在作用域中,因此最新的WindowCount始终为零

对于一个普通的、只能触发一次的窗口,每个窗口状态是无用的。只有当一个窗口以某种方式有多个触发(例如,延迟触发)时,您才能充分利用每个窗口状态。如果您试图从一个窗口到下一个窗口记住某些内容,那么您可以使用全局窗口状态来执行此操作


有关使用每个窗口状态来记住在后期触发时使用的数据的示例,请参见Flink中的幻灯片13-19。

谢谢您的回复。实际上,我发布的代码是模仿您提供的URL。我的想法是,我们可以启动每个窗口状态,对这些状态进行一些计算,然后最终更新它们,以便我们能够在下一个窗口中检索它们。因此,我希望在对
ProcessWindowFunction
的最新调用中获得保留的窗口状态值。我不明白为什么在调用
ProcessWindowFunction
时,即使我更新了相应的窗口状态,
latestWindowCount
也会为零。是吗误解了每个窗口状态的用法??我已经扩展了我的答案,希望更清楚。如果你还有问题,请告诉我。基本上,这归结为“下一个窗口”不是同一个窗口,并且无法访问上一个窗口的每窗口状态。感谢您更新答案。事实上,我误解了每窗口状态的定义。现在我可以完全理解它。