假设您有一个具有一个生产者(p1)和多个消费者(c1-c2-c3)的体系结构。当一个小的java客户机按顺序产生m1、m2、m3等消息,而另一个java客户机(扩展到另一台机器的3x)得到一条消息,然后在计算完某个内容后将该消息写入数据库表。
如果使用者应用程序中的计算周期不同,并且最初使用的消息可能会按最后的顺序写入同一个表,则可能会导致数据不一致。
也许我在文档中遗漏了一些东西,但我想知道Kafka如何处理这种情况下的一致性。
假设您有一个具有一个生产者(p1)和多个消费者(c1-c2-c3)的体系结构。当一个小的java客户机按顺序产生m1、m2、m3等消息,而另一个java客户机(扩展到另一台机器的3x)得到一条消息,然后在计算完某个内容后将该消息写入数据库表。
如果使用者应用程序中的计算周期不同,并且最初使用的消息可能会按最后的顺序写入同一个表,则可能会导致数据不一致。
也许我在文档中遗漏了一些东西,但我想知道Kafka如何处理这种情况下的一致性。
3条答案
按热度按时间fdbelqdn1#
如果您正在使用3个分区向主题t1写入内容,并且您的使用者位于使用者组中,那么每个使用者将使用t1的一个分区。假设c1从分区1读取,c2从分区2读取,等等。不能保证跨多个分区的数据排序,只能保证在一个分区内排序。考虑以下示例:
p1按顺序生成以下记录:
假设记录按以下方式进行分区:
现在c1可以在c2和c3开始之前读取所有的记录。所以记录r4将在r2和r3之前处理。但是,分区1中的顺序将始终被保留,因此r1将始终在r4之前被接收和处理。
jhkqcmku2#
消费者不听生产者的话。取而代之的是:
生产者向kafka服务器集群管理的kafka主题写入消息,
kafka服务器将该消息持久保存在为该主题创建的分区之一中,并且
只有这样,消费者才能访问消息。
如果消费者在同一消费者组中,那么他们中只有一个将从消息的分区中读取,并且只有该消费者能够读取该消息。如果消费者不在同一消费群体中,那么他们可能都能阅读信息。事实上,该消息可能会被许多使用者多次读取,直到kafka服务器删除该消息,因为该消息早于为主题配置的生存时间。
一旦消费者阅读了来自Kafka主题的消息,Kafka就无法控制该消息的处理方式、处理时间甚至处理时间。
cwdobuhd3#
如果要保持发送到kafka主题的相关消息的顺序,可以选择一个将这些消息作为kafka分区键的唯一标识符。
例如,如果您正在处理来自不同客户的事务,您可以选择customerid(假设它是客户的唯一标识符)作为分区密钥,这样您为给定客户发送给kafka的所有消息都将在同一分区中结束;这意味着它们将被同一个消费者按顺序消费。
但是,如果您认为所有消息都是相关的并且相互依赖的,那么除了自己在使用者端处理并发性之外,没有什么可做的了,或者最好只有一个分区和一个使用者。