同一个分区真的永远不会被一个组上的多个消费者同时消费吗

Posted

技术标签:

【中文标题】同一个分区真的永远不会被一个组上的多个消费者同时消费吗【英文标题】:Does same partition really never be consumed by more than one consumers on a single group at the same time 【发布时间】:2021-09-04 04:58:10 【问题描述】:

假设一个主题有 2 个分区。 我们在同一组中有 2 个消费者都从该主题消费:消费者 A 消费 partition 0,消费者 B 消费 partition 1。 消费者 A 是消费者组的组长。

瞬间,Consumer B 收到了一批来自 topic 的消息,例如 message: X, Y。紧接着,Consumer B 停止了。

一段时间后,Consumer A 认为 Consumer B 已经死了,决定从 partition 1 重新平衡消费。它获取消息:X、Y、Z(按顺序),然​​后写入数据库。

之后,消费者B恢复执行,不知道过了一段时间,继续写消息X,Y,覆盖Z的效果。 然后消费者 B 完全失败。

有可能吗?如果是,那么使用消息和更新插入数据库的简单方法可能不安全。

【问题讨论】:

有一个很好的解释.. 希望这会有所帮助***.com/a/51829144/7098046 当/如果消费者提交任何偏移量时,您的描述似乎丢失了。如果 B 死了,则组重新平衡,然后 A 将读取两个分区 这里的 A 是否提交了偏移量都没有关系。因为 B 在写入数据库时​​不会从已提交的偏移主题中读取任何内容。 Kafka 消费者总是查询偏移量主题。你不能禁用它 Kafka 消费者,因为我记得只在开始时查询已提交的偏移量主题。你不知道 raft/paxos 共识或分布式锁定,是吗? 【参考方案1】:

消费者 A 认为消费者 B 已经死亡,决定从分区 1 重新平衡和消费。它得到消息:X、Y、Z(按顺序)然后写入数据库

好的,假设它为每条消息提交偏移量

如果 B 重新启动,它将开始读取最近提交的值之后的偏移量,并且不会重新读取它之前尝试过的数据,除非消费者被手动寻找到该位置.

【讨论】:

它在收到消息后立即停止,但在写入数据库之前,因此它没有触及已提交的偏移量主题来确定偏移量是否为旧版本。 B没有失败,只是暂停了,因为GC暂停,VM暂停或者有人不小心给B发送了停止信号。 失败或暂停仍会导致重新平衡和丢失已处理的记录状态 B 可以检测到它已经读取了旧的偏移量,但只有在 B 已经写入数据库之后。以上问题依然存在 B 的暂停会导致 A 重新平衡,但 B 在执行写入时甚至不知道自己已经离开了组

以上是关于同一个分区真的永远不会被一个组上的多个消费者同时消费吗的主要内容,如果未能解决你的问题,请参考以下文章

CentOS安装,LVM逻辑卷

Spring Cloud Stream的分区和分组

为多个消费者读取一次流

kafka消费者对应的分配partition分区策略

Apache Kafka 是不是适合用作无序任务队列?

IOS:UITextInput 上的 Tokenizer 永远不会被调用