Java 在Flink中处理后,将元素传递回输入流?
场景: 我有一个来自传感器的事件流。事件可能为T型或J型Java 在Flink中处理后,将元素传递回输入流?,java,apache-flink,flink-streaming,amazon-kinesis,amazon-kinesis-analytics,Java,Apache Flink,Flink Streaming,Amazon Kinesis,Amazon Kinesis Analytics,场景: 我有一个来自传感器的事件流。事件可能为T型或J型 T型事件具有事件发生时间戳 J型事件具有开始和结束时间戳 根据J-Type事件的开始和结束时间戳,对时间范围内的所有T-Type事件应用聚合逻辑,并将结果写入数据库 为此,我创建了一个自定义触发器,它在接收到J-Type事件时被触发。在自定义ProcessWindowFunction中,我正在执行聚合逻辑和时间检查 但是,可能存在这样一种情况,T型事件不在当前J型事件的时间范围内。 在这种情况下,在清除当前窗口之前,应将T型事件推送到
- T型事件具有事件发生时间戳
- J型事件具有开始和结束时间戳
有没有办法在keyBy上下文中维护状态,以便我们对这些未处理的数据(在或之前)以及窗口元素执行计算。以下是两种解决方案。它们的基本行为或多或少是相同的,但您可能会发现其中一个更容易理解、维护或测试 至于你的问题,不,没有办法循环(重新排队)未使用的事件,而不将它们推回到运动状态。但只要坚持到需要它们,就可以了 解决方案1:使用RichFlatMapFunction 当T型事件到达时,将它们附加到
ListState
对象。当J-type事件到达时,将列表中所有匹配的T-type事件收集到输出,并更新列表以仅保留将属于后续J-type事件的T-type事件
解决方案2:使用带有自定义触发器和逐出器的全局Windows
除了您已经完成的操作之外,实现一个逐出器
,该逐出器(在启动窗口后)仅从窗口中移除J-type事件和所有匹配的T-type事件
更新:清除过期钥匙/失效传感器的状态
对于解决方案1,您可以使用来安排清除与失效密钥关联的任何非活动状态。或者您可以使用KeyedProcessFunction
而不是RichFlatMapFunction
,并使用计时器来完成同样的任务
使用窗口API管理过期键的状态可能不那么简单,但对于解决方案2,我相信您可以扩展自定义触发器,使其包含一个将清除窗口的超时。如果您在
ProcessWindowFunction
中使用了全局状态,则需要依赖状态TTL来清除该问题。在讨论解决方案之前,我想更好地了解该问题。T和J事件是否在同一个流中?那个流是通过什么(可能是通过sensorId)键控的?您解释了如何同时有两个打开的窗口。事情有多混乱?可能同时有三个或更多打开的窗口吗?窗口的J事件是否总是在T事件之前(或之后),或者是否可以进行任何排序。是的,他们在同一条小溪里。2.是的,流是keyBy(“sensorId”)。3.同一个“sensorId”不会同时有两个打开的窗口。第一个窗口在我们收到第一个J-Type后关闭。然后第二个窗口打开。这里,J-Type启动窗口触发器。在窗口1中,我们还可以接收T-type,它应该属于后续窗口。我们根据T-type事件中发生的事件时间戳,将T-type事件关联到J-type事件。如果事件发生时间戳落在J-Type时间范围内,则它属于该J-Type。如果不在时间范围内,则应将这些t型事件推送到下一个窗口,以检查其是否在该窗口中有效。处理引擎通常根据有向无环图或DAG来考虑流程管道。这是处理可以按特定顺序遍历函数的地方,函数可以链接在一起,但处理决不能返回到图中的较早点。从此以后,重新排队不再是一种策略。使用ListState
作为我当前场景的解决方案。嘿,大卫,谢谢你的回复。我对window的理解是,他们是Akka演员。如果传感器失效,sensorId
将过时。因此,如果我们没有针对windows的清除策略,这些过时的参与者将消耗主内存。在我们的情况下,重新排队是唯一最好的解决方案,因为它简化了流程,并减少了死角情况。如果有任何方法可以直接将文件发送回输入流(不带kinesis),那么请分享这种方法。我也在考虑使用一个附加流(kinesis或任何其他建议),它将从exector()接收这些无效元素,并与主输入流合并()。请分享您的想法?我非常喜欢解决方案1(有状态平面图或进程函数);这就是我要做的。我不知道重新排队如何解决传感器失效的问题。你可能会在最后几次T型比赛中无休止地回到动觉状态。