我们计划将Apache Flink与庞大的IOT安装程序配合使用。客户将向我们发送某种结构化的传感器数据(例如sensor_id,sensor_type,sensor_value,时间戳)。我们无法控制每个客户何时最有可能实时发送此数据,但我们无法保证。我们将所有事件存储在RabbitMQ / Kafka中。更新:我们可以假设每个传感器的事件是按顺序发生的。
在开始实施可能的流传输管道之前,我们对以下挑战的解决方案感兴趣:
多个窗口聚合
我们将所有原始传感器数据存储到Cassandra中。此外,我们希望通过多个时间窗口(例如15秒,1分钟,15分钟,1小时,1天)上的sensor_id汇总传感器数据。使用Flink流有效地实现所需输出的推荐方法是什么?
数据很晚
如前所述,我们无法控制when
数据的发送。例如,客户可能遇到网络故障,因此数据可能会延迟到达。建议如何处理呢?如果我们只能通过sensor_id保证良好的水印(因为每个客户都有自己的时间/问题/故障),我们如何使用水印?我们可以添加一些允许的延迟(例如6到12个小时左右),可以通过内存窗口存储中的flink进行管理吗?在允许延迟之后会发生什么?我们是否应该将真正的最新数据存储到另一个kafka主题中并连续进行批处理?最后,一些客户上载带有收集到的传感器数据的csv文件。该指南也适用于批处理方法吗?
未来数据
当某些客户由于传感器配置错误(因为我们无法控制数据)而向我们发送了远期数据时,流会发生什么?
我们对您的建议感到好奇。谢谢。
最佳答案
这些是很多问题。我将尝试一个接一个地回答他们:
多个窗口聚合
您可以构造级联窗口运算符的数据流,并在每个窗口之后分叉(发出或进一步处理)结果。
Input -> window(15 secs) -> window(1 min) -> window(15 min) -> ...
\-> out_1 \-> out_2 \-> out_3
数据很晚
看来问题在于,有些数据可能“很晚”到达,而不是仅按每个键排序。目前,无法使用每个按键的水印。因此,所有事件的“逻辑时钟”都是相同的。 Flink的允许延迟定义了状态等待多长时间来等待延迟到达的数据。如果数据迟到(在水印之后)但在允许的延迟内,则相应状态仍然可用,并计算更新。如果事件为时太晚(晚于允许的延迟),则状态将被丢弃,事件也将被丢弃。高允许延迟意味着需要保持更多状态。但是,原则上可以通过向外扩展解决此问题。也可以使用Flink来处理进入专用Kafka主题的最新数据。同样,可以使用流处理器更好地连续处理周期性文件。批处理解决方案需要处理数据跨文件(外部状态处理),作业计划,错误处理等问题。
未来数据
使用Flink的水印机制,操作员可以始终转发其最高水印(时间不能倒退),但可以将其水印计算为从所有输入通道接收到的最小水印。因此,除非您在所有渠道上都有未来的数据,否则应该没问题。将来的数据将作为状态放置,并在时间到达“将来”时进行计算。这意味着,您不会丢失数据,但是可能需要等待一段时间才能处理数据。
根据您的描述,我会考虑将聚合实现为有键流上的有状态FlatMap运算符。假设每个传感器的数据按顺序到达,则可以在FlatMap(或一系列FlatMap,每个时间间隔一个)中进行必要的汇总。
这里的一个挑战是您不知道何时关闭聚合,直到您看到一个晚于聚合间隔的事件。在具有全局有效水印的流中,即使未收到特定密钥的事件,时间也会提前(并且窗口将关闭)。
另一个问题是在移除传感器的情况下移除状态。这不会被自动检测到。也许可以使用特殊的标记记录来触发状态清除。