如何从多线程Kafka生产者中获得插入顺序

时间:2019-01-15 19:04:18

标签: java apache-kafka

我有一个带有历史记录表的Ingres DB,该表记录DB事件,例如插入更新和删除。 我有一个生产者,它将是多线程的。 该生产者将读取“历史记录”表,以找到要选择的表和行,然后在该行中添加Kafka主题。 现在,生产者需要确保以与历史表登录相同的方式将事件添加到Kafka主题。 因此,消费者以与记录在“历史记录”表中相同的顺序读取它们,并在Postgrace DB上执行它。

我可以将这些数据产生给多个生产者。 例子

Producer1 has message 1 to 5
producer2 has message 6 to 10
producer3 has message 11 to 15

但是当我吃东西的时候,我得到的话题是这样的消息

messageId 1
messageId 2
messageId 3
messageId 6
messageId 7
messageId 11

以此类推

我想按以下顺序获取所有消息

messageId 1
messageId 2
messageId 3
messageId 4
messageId 5
messageId 6
messageId 7
messageId 8
messageId 9

以此类推

注意:-我有1个主题,1个分区和1个使用者

3 个答案:

答案 0 :(得分:0)

在发送数据时,Kafka不保证顺序,因为默认情况下每个主题都有几个分区,并且如果您没有密钥,则会将消息随机分配给分区。在下游,每个分区都可以独立使用。

如果需要保证插入和使用顺序,则需要将Kafka主题配置为仅使用1个分区。那是保证卡夫卡秩序的唯一方法。但是,您将失去kafka的许多好处,这些好处是在多个服务器,内核等上分布的高性能。

答案 1 :(得分:0)

最多,您可以通过将消息发送到单个分区来保持消息的顺序与生产者创建消息的顺序相同。 Kafka分区保证了消息的使用顺序,即在分区中创建消息的顺序。

在您的方案中,消息是由多个生产者生成的,并且它们不同步,无法按顺序用消息填充分区。因此,不可能像您期望的那样在消费者端实现订单。

答案 2 :(得分:0)

对于每个Google's recommendation,如果您使用同步发布者(生产者)和单个订阅者,请遵循the 2nd half of the page中Node JS代码中的算法,以确保处理顺序。

类似地,如果您有多个发布者,则需要通过在getPublishCounterValue方法和setPublishCounterValue方法之间有一个关键部分来同步发布者,这会破坏发布者的多线程本质。

最好的解决方法是遵循the section of

  

最终结果中的顺序很重要

     

典型用例:日志,状态更新

多线程发布者必须为每个发布/订阅事件消息附加时间戳,以便订阅者可以将事件消息作为实体存储在Google Cloud DatastoreFirestore中。单独的事件消息处理器cron作业可以按时间戳排序的方式检索事件消息的实体,以强制执行消息排序。