Apache Kafka 队列功能的改进与替代方案
Apache Kafka 社区正在积极开发支持队列功能的新特性,作为 KIP-932(Kafka 改进提案)的一部分。与此同时,SoftwareMill 提出了一个基于现有消费者组抽象的实现方案。
Kafka 的现状与挑战
Apache Kafka 多年来一直是消息传递解决方案的事实标准,主要因其高性能和持久性消息传递而闻名。然而,Kafka 的设计侧重于高吞吐量,这导致了一些灵活性上的限制,例如不支持单个消息的确认机制。
Kafka 使用消费者组来实现消息消费,依赖于将主题分区独占分配给消费者,并通过分区偏移量进行跟踪。这种设计引入了“队头阻塞”问题,即单个消息处理缓慢或阻塞可能会影响甚至停滞消费者应用程序。此外,消息处理的并行性受限于分区数量,因此分区数量需要提前根据期望的吞吐量仔细确定。
KIP-932:Kafka 的共享组抽象
KIP-932 提出了一种新的共享组抽象,以实现协作式消息消费。共享组采用非独占的分区分配方式,消除了消费者数量与分区数量之间的限制,简化并缩短了重新平衡过程,避免了“全局停止”的隔离事件。
共享组允许消费者单独处理和确认消息,Kafka 可以在更细粒度上跟踪消息消费。当请求可用消息时,Kafka 共享分区返回一批标记为已获取的消息,这些消息将保持该状态,直到消费者确认或处理时间超限。如果超限,消息将重新标记为可用。
Kafka 还跟踪消息的投递尝试次数,如果超过阈值,则标记为拒绝。目前,死信队列(DLQ)功能尚不可用,但未来可能会添加。Kafka 代理在专用内部主题中维护和持久化所有必要的内部状态,以在个别级别跟踪消息投递。共享组功能计划在 Kafka 4.0 版本中发布。
SoftwareMill 的 KMQ 方案
对于不想等待 Kafka 4.0 的用户,SoftwareMill 的 Adam Warski 提出了一个替代方案 KMQ,该方案可以在当前和过去的 Kafka 版本中运行。
KMQ 是一种实现单个消息确认的模式,使用 Kafka 消费者组的功能。与共享组类似,KMQ 也使用额外的组件——重新投递跟踪器(Redelivery Tracker),负责标记消息为已投递和已确认,但这发生在应用程序端。跟踪器依赖于专用的“标记”主题和单独的消费者组,并在处理超时时将消息重新发布回跟踪的主题。如果重新投递计数器超过配置的阈值,消息将被发布到配置的死信队列(DLQ)主题。
尽管 KMQ 方案需要将标记发布到专用主题,引入了一些额外的延迟,但在项目团队进行的性能测试中,其吞吐量与常规消费者组相当。KMQ 模式的主要优势是支持当前 Kafka 客户端版本的单个消息确认,同时提供高性能。然而,该模式并未解决队头阻塞问题,并行性仍受限于分区数量。
总结
Kafka 社区通过 KIP-932 引入共享组抽象,旨在解决现有消费者组模式的一些限制,如队头阻塞和并行性问题。与此同时,SoftwareMill 的 KMQ 方案提供了一种基于现有 Kafka 功能的替代实现,支持单个消息确认,但并未完全解决所有问题。这两种方案各有优劣,用户可以根据需求选择合适的解决方案。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用。你还可以使用@来通知其他用户。