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