Apache Flink:多窗口聚合和延迟数据

kae*_*nia 4 real-time bigdata iot apache-flink flink-streaming

我们计划将 Apache Flink 与巨大的 IOT 设置一起使用。客户将向我们发送某种结构化的传感器数据(如 sensor_id、sensor_type、sensor_value、timestamp)。我们无法控制每个客户何时发送此数据,很可能是实时发送,但我们无法保证。我们将所有事件存储在 RabbitMQ/Kafka 中。更新:我们可以假设每个传感器的事件按顺序排列。

在开始实施可能的流媒体管道之前,我们对以下挑战的解决方案感兴趣:

  1. 多窗口聚合

我们将所有原始传感器数据存储到 Cassandra 中。此外,我们希望通过sensor_id 在多个时间窗口(例如15 秒、1 分钟、15 分钟、1 小时、1 天)上聚合传感器数据。使用 Flink 流有效实现所需输出的推荐方法是什么?

  1. 很晚的数据

如前所述,我们无法控制when发送的数据。例如,客户可能会遇到网络故障,因此数据可能会延迟到达。推荐的方法是如何处理这个问题的?如果我们只能通过 sensor_id 来保证好的水印(因为每个客户都有自己的时间/问题/失败),我们如何使用水印?我们可以添加一些允许的延迟(比如 6 - 12 小时左右),这是否可以通过内存窗口存储中的 flink 进行管理?在允许迟到之后会发生什么?我们是否应该将真正迟到的数据存储到另一个 kafka 主题中并连续进行批处理?最后,一些客户上传带有他们收集的传感器数据的 csv 文件。这是否也指导批处理方法?

  1. 未来数据

由于传感器配置错误(因为我们无法控制它),当某些客户向我们发送远在未来的数据时,流会发生什么情况?

我们很好奇您的建议。谢谢。

Fab*_*ske 6

这是相当多的问题。我会尽量一一解答:

  1. 多窗口聚合

您可以构建级联窗口运算符的数据流,并在每个窗口之后分叉(以发出或进一步处理)结果。

Input -> window(15 secs) -> window(1 min) -> window(15 min) -> ...
                        \-> out_1        \-> out_2         \-> out_3
Run Code Online (Sandbox Code Playgroud)
  1. 很晚的数据

似乎问题在于某些数据可能“非常”晚到达,而不是数据仅按每个键的顺序排列。目前无法使用每个键的水印。因此,所有事件的“逻辑时钟”都是相同的。Flink 的允许延迟定义了状态保持多长时间以等待延迟到达的数据。如果数据延迟到达(在水印之后)但在允许的延迟范围内,则相应的状态仍然可用并计算更新。如果事件太晚(晚于允许的延迟),则状态将被丢弃,并且事件也将被丢弃。允许的高延迟意味着需要保留更多状态。但是,这个问题原则上可以通过横向扩展来解决。进入专用 Kafka 主题的后期数据的处理也可以使用 Flink 来完成。此外,使用流处理器可以更好地连续处理周期性文件。批处理解决方案需要处理跨文件的数据(外部化状态处理)、作业调度、错误处理……

  1. 未来数据

使用 Flink 的水印机制,算子总是转发其最高水印(时间不能倒退),但将其水印计算为从所有输入通道接收到的最小水印。因此,除非您拥有所有渠道的未来数据,否则应该没问题。未来的数据将作为状态放置,并在时间到达“未来”时进行计算。这意味着,您不会丢失数据,但您可能需要等待相当长的时间才能对其进行处理。


根据您的描述,我会考虑将聚合实现为键控流上的有状态 FlatMap 运算符。鉴于每个传感器的数据按顺序到达,您可以在 FlatMap(或一系列 FlatMap,每个时间间隔一个)中进行必要的聚合。

这里的一个挑战是,您不知道何时关闭聚合,直到您看到晚于聚合间隔的事件。在具有全局有效水印的流中,即使没有接收到特定键的事件,时间也可以提前(并且窗口被关闭)。

另一个问题是在移除传感器的情况下移除状态。这不会被自动检测到。也许可以使用特殊的标记记录来触发状态清理。