Kafka新版本重大更新,发布4.0!!

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 更高效、更易用。

相关推荐
宦如云几秒前
Bash语言的哈希表
开发语言·后端·golang
失业写写八股文4 分钟前
本地事务 vs 分布式事务:核心区别与解释
分布式·后端
丑过三八线15 分钟前
【Kafka】Kafka4.0在windows上启动
windows·分布式·kafka
uhakadotcom27 分钟前
快速构建交互式数据应用:Streamlit入门指南
后端·面试·github
无名之逆1 小时前
hyperlane:Rust HTTP 服务器开发的不二之选
服务器·开发语言·前端·后端·安全·http·rust
机构师1 小时前
<iced><rust><GUI>基于rust的GUI库iced的学习(02):svg图片转png
后端·rust
老赵骑摩托1 小时前
Go语言nil原理深度解析:底层实现与比较规则
开发语言·后端·golang
dengjiayue1 小时前
kafka 与 RocketMQ对比
分布式·kafka·rocketmq
卑微小文1 小时前
惊!代理 IP 竟成社交媒体营销破局“神助攻”!
后端
程序员爱钓鱼1 小时前
Go 语言邮件发送完全指南:轻松实现邮件通知功能
后端·go·排序算法