【问题标题】:How does partitioning in message brokers solves ordering problem?消息代理中的分区如何解决排序问题?
【发布时间】:2020-04-21 03:29:07
【问题描述】:
我一般都有分区的想法,但我不知道它是如何真正解决排序问题的。以 Chris Richardson 的书为例,如果我有 3 个关于具有“shard-key”1 的给定订单的事件(创建订单、更新订单和取消订单)。如果每个分区有多个实例,我如何确保按顺序处理事件?不是针对同一个问题进行裁员吗?
我的意思是,在该示例中,所有消息都发送到第一个分片,但它们不会在两个实例之间循环吗?
【问题讨论】:
标签:
apache-kafka
kafka-producer-api
messagebroker
【解决方案1】:
如果您的记录有键,则默认行为是始终将任何给定键发送到同一分区。
分区是一种分而治之的方法,但会带来一些牺牲,这在任何给定的问题域中可能是完全可以接受的。具有多个分区的主题没有“顺序”的概念;正如您所指出的,您可以有多个竞争消费者,它们可能以不同的速度运行。
相反,每个分区只会分配给消费者组中的一个消费者,并且在这个级别上,排序是严格的(ish)。我说严格是因为事情总是会出错,并且可以重新处理记录,因此开箱即用的 Kafka 永远不会绝对保证您的订购。
当你说你需要按顺序处理事情时,我需要考虑一下这有多重要。例如您可能会争辩说银行账户的交易应该按顺序处理(也许),因此特定账户的所有记录都应该在同一个分区上,但两个不同账户活动的相对顺序并不重要。
关于分区策略,直到 V2.3,没有密钥的消息将以循环方式发送到分区。从v2.4 开始,KIP-480 引入了一个粘性分区器来循环批量记录,而不是严格地一次一个。
【解决方案2】:
Kafka 保证按分区排序。如果您需要保证它们的处理顺序,您的消息生产者必须确保将消息流发送到同一个分区。
但是请注意,消费者实例不能多于分区(每个消费者组)。