Scala Flink:ProcessWindowFunction
我最近在Flink的新版本中学习Scala Flink:ProcessWindowFunction,scala,apache-flink,flink-streaming,Scala,Apache Flink,Flink Streaming,我最近在Flink的新版本中学习ProcessWindowFunction。它表示ProcessWindowFunction支持全局状态和窗口状态。我使用ScalaAPI来尝试一下。到目前为止,我可以让全局状态工作,但我没有任何运气使它成为窗口状态。我所做的是处理系统日志,并计算由主机名和严重性级别键入的日志数。我想计算两个相邻窗口之间日志计数的差异。下面是我实现ProcessWindowFunction的代码 class LogProcWindowFunction extends Proces
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
也会为零。是吗误解了每个窗口状态的用法??我已经扩展了我的答案,希望更清楚。如果你还有问题,请告诉我。基本上,这归结为“下一个窗口”不是同一个窗口,并且无法访问上一个窗口的每窗口状态。感谢您更新答案。事实上,我误解了每窗口状态的定义。现在我可以完全理解它。