java—当应用程序中存在一个生产者和多个消费者时,apache kafka如何处理一致性

r9f1avp5  于 2021-06-07  发布在  Kafka
关注(0)|答案(3)|浏览(320)

假设您有一个具有一个生产者(p1)和多个消费者(c1-c2-c3)的体系结构。当一个小的java客户机按顺序产生m1、m2、m3等消息,而另一个java客户机(扩展到另一台机器的3x)得到一条消息,然后在计算完某个内容后将该消息写入数据库表。
如果使用者应用程序中的计算周期不同,并且最初使用的消息可能会按最后的顺序写入同一个表,则可能会导致数据不一致。
也许我在文档中遗漏了一些东西,但我想知道Kafka如何处理这种情况下的一致性。

fdbelqdn

fdbelqdn1#

如果您正在使用3个分区向主题t1写入内容,并且您的使用者位于使用者组中,那么每个使用者将使用t1的一个分区。假设c1从分区1读取,c2从分区2读取,等等。不能保证跨多个分区的数据排序,只能保证在一个分区内排序。考虑以下示例:
p1按顺序生成以下记录:

╔════════╗
║ Record ║
╠════════╣
║ R1     ║
║ R2     ║
║ R3     ║
║ R4     ║
║ R5     ║
║ R6     ║
╚════════╝

假设记录按以下方式进行分区:

╔═════════════╦═════════════╦═════════════╗
║ Partition 1 ║ Partition 2 ║ Partition 3 ║
╠═════════════╬═════════════╬═════════════╣
║ R1          ║ R2          ║ R3          ║
║ R4          ║ R5          ║ R6          ║
╚═════════════╩═════════════╩═════════════╝

现在c1可以在c2和c3开始之前读取所有的记录。所以记录r4将在r2和r3之前处理。但是,分区1中的顺序将始终被保留,因此r1将始终在r4之前被接收和处理。

jhkqcmku

jhkqcmku2#

消费者不听生产者的话。取而代之的是:
生产者向kafka服务器集群管理的kafka主题写入消息,
kafka服务器将该消息持久保存在为该主题创建的分区之一中,并且
只有这样,消费者才能访问消息。
如果消费者在同一消费者组中,那么他们中只有一个将从消息的分区中读取,并且只有该消费者能够读取该消息。如果消费者不在同一消费群体中,那么他们可能都能阅读信息。事实上,该消息可能会被许多使用者多次读取,直到kafka服务器删除该消息,因为该消息早于为主题配置的生存时间。
一旦消费者阅读了来自Kafka主题的消息,Kafka就无法控制该消息的处理方式、处理时间甚至处理时间。

cwdobuhd

cwdobuhd3#

如果要保持发送到kafka主题的相关消息的顺序,可以选择一个将这些消息作为kafka分区键的唯一标识符。
例如,如果您正在处理来自不同客户的事务,您可以选择customerid(假设它是客户的唯一标识符)作为分区密钥,这样您为给定客户发送给kafka的所有消息都将在同一分区中结束;这意味着它们将被同一个消费者按顺序消费。
但是,如果您认为所有消息都是相关的并且相互依赖的,那么除了自己在使用者端处理并发性之外,没有什么可做的了,或者最好只有一个分区和一个使用者。

相关问题