Kafka流消息消费顺序

时间:2019-06-25 20:28:51

标签: apache-kafka apache-kafka-streams

该主题包含10个分区,这些分区具有由各种IoT设备每3-4秒生成一次的消息。消息上的键是LocationId和DeviceId。值是与设备相关的详细信息。

流拓扑已部署到4个EC2实例。该过程必须确定每个设备的最新更新值,并分析其重要性。

我看到的是,由于消息分布在多个分区中,因此流使用者可以看到较旧的消息,而且它们的顺序不正确。

如何确定特定密钥的最新消息?

我在Kafka群集上看到以下消息行为-

L1D1 at 1:00 am - critical=false (P1)
L2D2 at 1:00 am - critical=false (P1)
L1D1 at 1:02 am - critical=**true** (P2)
L2D2 at 1:05 am - critical=false (P1)
L1D1 at 1:03 am - critical=false (P2)
L2D2 at 1:03 am - critical=false (P1)

请注意,在1:02时设备D1发出严重警报,但在1:03时则没有。如果按流处理消息是1:03、1:02(基于分区的任何随机顺序)

由于不能保证顺序,如何有效确定特定设备的最新消息?

2 个答案:

答案 0 :(得分:2)

  

由于不能保证顺序,如何有效确定特定设备的最新消息?

Kafka保证在主题分区内的邮件排序 ,但不能跨多个主题分区进行邮件排序。您需要做的是确保将来自同一设备的消息发送到同一主题分区。如果您尚未更改Kafka的默认设置,则可以使用特定于设备的标识符(例如:DeviceId)来实现。

  

我看到的是,由于消息分布在多个分区中,因此流使用者可以看到较旧的消息,而且它们的顺序不正确。

如果您使用(LocationId, DeviceId)之类的复合密钥,则不会按顺序获得同一设备的更新,因为该设备的消息分布在多个分区上,因为该消息密钥包括还有LocationId

  

该过程必须确定每个设备的最新更新值,并分析其重要性。 [...]由于不能保证订单的顺序,如何有效地确定特定设备的最新消息?

在您的情况下,我会将消息密钥从(LocationId, DeviceId)更改为DeviceId。我们称其为“流D”。

如果您仍需要按(LocationId, DeviceId)进行原始分组,则可以通过随后将流D从DeviceId到{{1}进行重新分组(也称为重新密钥或重新分区)来实现。 }转换为新的派生流LD。

答案 1 :(得分:0)

您的流处理策略是什么? KSQL还是SDK? 如果您使用KSQl,则只需创建一个流/表

检查: https://docs.confluent.io/current/ksql/docs/developer-guide/create-a-table.html