Apache Kafka 4.0 是一个里程碑式的版本,带来了多项重大更新,尤其是在架构、性能和功能扩展方面。以下是 Kafka 4.0 的主要更新及其原理的详细介绍:
1. 完全移除 ZooKeeper,默认使用 KRaft 模式
更新内容
- Kafka 4.0 彻底移除了对 ZooKeeper 的依赖,默认运行在 KRaft(Kafka Raft)模式下。KRaft 是 Kafka 自带的元数据管理机制,基于 Raft 共识协议实现。
- ZooKeeper 在之前的版本中负责元数据存储、领导者选举和集群协调,而现在这些功能完全由 Kafka 内部的控制器(Controller)接管。
原理
-
Raft 协议:KRaft 使用 Raft 共识算法来管理元数据日志的复制和一致性。Raft 将集群分为领导者(Leader)和跟随者(Follower),通过日志复制和投票机制确保数据一致性。
- 领导者选举:当控制器节点宕机时,KRaft 通过投票选出新的领导者,投票基于节点的日志状态(即谁拥有最新的日志)。
- 日志复制:元数据变更(如主题创建、分区分配)被记录为日志条目,由领导者广播到跟随者,确保所有节点状态一致。
-
元数据存储:元数据不再存储在 ZooKeeper 的 ZNode 树中,而是以日志形式存储在 Kafka 自己的日志文件中(通常位于磁盘上的元数据日志目录)。
-
控制器集群:KRaft 引入了一个小型控制器集群(通常 3-5 个节点),这些节点共同维护元数据并处理集群管理任务。
优势
- 消除了 ZooKeeper 的外部依赖,简化了部署和运维。
- 减少了 ZooKeeper 的性能瓶颈(如高负载下的延迟),元数据操作更快。
- 提高了可扩展性,控制器集群可以动态调整规模。
注意事项
- 升级到 4.0 前,需从 ZooKeeper 模式迁移到 KRaft(建议先升级到 3.7 或 3.8 并完成迁移)。
2. KIP-848:新一代消费者组重平衡协议
更新内容
- Kafka 4.0 正式引入了新的消费者组重平衡协议,显著提升了消费者组在分区重新分配时的性能和稳定性。
原理
-
传统重平衡问题:旧协议(基于"停止世界"模型)在重平衡时会暂停所有消费者,导致服务中断时间较长,尤其是在大规模消费者组中。
-
新协议设计:
- 增量重平衡:新协议允许消费者在重平衡期间继续处理未被重新分配的分区,而不是全部暂停。
- 协调者优化:组协调者(Group Coordinator)使用更高效的状态机和通信机制,减少了重平衡的协调开销。
- 分区分配策略:通过客户端和协调者之间的双向通信,分区分配更加智能,支持动态调整而无需全量重新分配。
-
实现细节:
- 消费者客户端定期向协调者发送心跳信号,报告其状态。
- 协调者根据心跳和组成员变化,逐步调整分区分配,而不是一次性重新计算。
优势
- 重平衡时间从秒级缩短到毫秒级,减少了服务中断。
- 在大规模消费者组(数百或数千消费者)中表现更优。
- 提高了消费者应用的可用性和吞吐量。
3. KIP-932:Kafka 队列(早期访问)
更新内容
- Kafka 4.0 引入了队列语义的支持(早期访问阶段),允许 Kafka 直接支持点对点消息传递模式,而不仅仅是发布-订阅模型。
原理
-
传统模型:Kafka 的主题(Topic)基于发布-订阅模型,消息被所有订阅者消费。
-
队列模式:
- 在队列模式下,一个消费者组内的消息只被一个消费者处理,类似于传统消息队列(如 RabbitMQ)。
- 通过在消费者组协议中引入"独占消费"逻辑实现:当一个消费者从分区消费消息时,其他消费者被阻止访问该分区。
-
实现细节:
- 队列模式通过配置主题或消费者组的属性启用。
- 分区分配策略被调整为"单一消费者分配",确保消息的顺序性和独占性。
优势
- 扩展了 Kafka 的使用场景,适用于需要队列语义的工作负载(如任务分发)。
- 无需额外部署其他消息队列系统,统一技术栈。
当前限制
- 作为早期访问功能,尚不完全稳定,可能在后续版本中进一步完善。
4. KIP-966:Eligible Leader Replicas(预览)
更新内容
- 引入"合格领导副本"(ELR)概念,作为同步副本(ISR)的子集,确保领导者选举时数据完整性。
原理
-
背景:在 Kafka 中,分区的领导者负责处理读写请求,同步副本(ISR)保持与领导者一致。当领导者宕机时,从 ISR 中选举新领导者,但可能存在数据未完全同步的风险。
-
ELR 定义:ELR 是 ISR 的一个子集,只有那些日志达到高水位线(High-Watermark,即所有副本都确认的偏移量)的副本才被认为是"合格的"。
-
选举过程:
- 当领导者失效时,控制器只从 ELR 中选择新领导者。
- 如果没有合格副本,则暂停选举,直到副本同步完成。
优势
- 防止因领导者选举导致的数据丢失或不一致。
- 提高了高可用性场景下的数据可靠性。
当前状态
- 预览功能,可能在未来版本中成为默认行为。
5. KIP-996:Pre-Vote 机制(预览)
更新内容
- 在 KRaft 模式下引入"预投票"机制,优化领导者选举过程。
原理
-
传统 Raft 选举:当领导者失效时,所有节点直接进入投票阶段,可能导致频繁的选举冲突。
-
Pre-Vote 机制:
- 在正式投票前,节点先进行"预投票"阶段,询问其他节点是否支持其成为领导者。
- 只有在获得足够支持后,节点才会发起正式投票。
-
实现细节:
- 预投票不更改节点状态,仅用于收集信息。
- 减少了因网络分区或短暂故障导致的无效选举。
优势
- 提升了 KRaft 控制器集群的稳定性。
- 减少了不必要的领导者切换,降低了集群抖动。
6. 其他重大更新
-
Java 版本升级:
- 客户端要求 Java 11,经纪人要求 Java 17,利用新版 Java 的性能优化(如垃圾回收改进)和安全性。
-
日志框架迁移到 Log4j2:
- 替换 Log4j,解决安全漏洞,并提供更灵活的日志配置。
-
移除过时功能:
- 删除消息格式 v0/v1 和其他标记为过时的 API,精简代码库。
7. Docker部署尝鲜
下面是在docker环境中部署Kafka 4.0, 该集群包含3个控制节点、2个Broker节点、1个kafdrop仪表盘:
yaml
services:
controller-1:
image: 'apache/kafka:4.0.0'
restart: "always"
environment:
KAFKA_NODE_ID: 1
KAFKA_PROCESS_ROLES: controller
KAFKA_LISTENERS: CONTROLLER://:9093
KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER
KAFKA_INTER_BROKER_LISTENER_NAME: INTERNAL
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: INTERNAL:PLAINTEXT,EXTERNAL:PLAINTEXT,CONTROLLER:PLAINTEXT
KAFKA_CONTROLLER_QUORUM_VOTERS: 1@controller-1:9093,2@controller-2:9093,3@controller-3:9093
KAFKA_GROUP_INITIAL_REBALANCE_DELAY_MS: 0
networks:
- kfk-network
controller-2:
image: 'apache/kafka:4.0.0'
restart: "always"
environment:
KAFKA_NODE_ID: 2
KAFKA_PROCESS_ROLES: controller
KAFKA_LISTENERS: CONTROLLER://:9093
KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER
KAFKA_INTER_BROKER_LISTENER_NAME: INTERNAL
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: INTERNAL:PLAINTEXT,EXTERNAL:PLAINTEXT,CONTROLLER:PLAINTEXT
KAFKA_CONTROLLER_QUORUM_VOTERS: 1@controller-1:9093,2@controller-2:9093,3@controller-3:9093
KAFKA_GROUP_INITIAL_REBALANCE_DELAY_MS: 0
networks:
- kfk-network
depends_on:
- controller-1
controller-3:
image: 'apache/kafka:4.0.0'
restart: "always"
environment:
KAFKA_NODE_ID: 3
KAFKA_PROCESS_ROLES: controller
KAFKA_LISTENERS: CONTROLLER://:9093
KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER
KAFKA_INTER_BROKER_LISTENER_NAME: INTERNAL
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: INTERNAL:PLAINTEXT,EXTERNAL:PLAINTEXT,CONTROLLER:PLAINTEXT
KAFKA_CONTROLLER_QUORUM_VOTERS: 1@controller-1:9093,2@controller-2:9093,3@controller-3:9093
KAFKA_GROUP_INITIAL_REBALANCE_DELAY_MS: 0
networks:
- kfk-network
depends_on:
- controller-1
broker-1:
image: 'apache/kafka:4.0.0'
restart: "always"
ports:
- 39092:19092
environment:
KAFKA_NODE_ID: 4
KAFKA_PROCESS_ROLES: broker
KAFKA_LISTENERS: 'INTERNAL://:9092,EXTERNAL://:19092'
KAFKA_ADVERTISED_LISTENERS: 'INTERNAL://broker-1:9092,EXTERNAL://192.168.221.128:39092'
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: INTERNAL:PLAINTEXT,EXTERNAL:PLAINTEXT,CONTROLLER:PLAINTEXT
KAFKA_CONTROLLER_QUORUM_VOTERS: 1@controller-1:9093,2@controller-2:9093,3@controller-3:9093
KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER
KAFKA_INTER_BROKER_LISTENER_NAME: INTERNAL
KAFKA_GROUP_INITIAL_REBALANCE_DELAY_MS: 0
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 2
networks:
- kfk-network
depends_on:
- controller-1
- controller-2
- controller-3
broker-2:
image: 'apache/kafka:4.0.0'
restart: "always"
ports:
- 29092:19092
environment:
KAFKA_NODE_ID: 5
KAFKA_PROCESS_ROLES: broker
KAFKA_LISTENERS: 'INTERNAL://:9092,EXTERNAL://:19092'
KAFKA_ADVERTISED_LISTENERS: 'INTERNAL://broker-2:9092,EXTERNAL://192.168.221.128:29092'
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: INTERNAL:PLAINTEXT,EXTERNAL:PLAINTEXT,CONTROLLER:PLAINTEXT
KAFKA_CONTROLLER_QUORUM_VOTERS: 1@controller-1:9093,2@controller-2:9093,3@controller-3:9093
KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER
KAFKA_INTER_BROKER_LISTENER_NAME: INTERNAL
KAFKA_GROUP_INITIAL_REBALANCE_DELAY_MS: 0
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 2
networks:
- kfk-network
depends_on:
- controller-1
- controller-2
- controller-3
kafdrop:
image: obsidiandynamics/kafdrop
restart: "no"
ports:
- "9000:9000"
environment:
KAFKA_BROKERCONNECT: "broker-1:9092,broker-2:9092"
depends_on:
- broker-1
- broker-2
networks:
- kfk-network
networks:
kfk-network:
name: kfk-network
external: true
总结与原理核心
Kafka 4.0 的核心更新围绕"简化架构"和"提升性能"展开:
- KRaft 通过 Raft 协议内嵌元数据管理,消除了 ZooKeeper 的外部依赖,原理上是将分布式一致性逻辑整合到 Kafka 内部。
- 消费者组重平衡 通过增量分配和优化协调,减少了停机时间,核心在于分布式状态机的改进。
- 队列支持 和 ELR/Pre-Vote 则扩展了功能并增强了可靠性,基于现有协议的微调和扩展。
这些更新的原理都建立在分布式系统理论(如 Raft 共识、分区分配优化)之上,旨在让 Kafka 更高效、更易用。