当前位置: 首页 > news >正文

从零学习Kafka:ZooKeeper vs KRaft

在 Kafka 的演进史中,抛弃 ZooKeeper 模式,拥抱 KRaft 模式这一变化被认为是其架构上最重要的一次变革。本文我们就来讨论 Kafka 为什么要抛弃 ZooKeeper,以及 KRaft 的设计思路。

为什么抛弃 ZooKeeper

在传统的 Kafka 架构中,Kafka 将元数据管理的责任交给了 ZooKeeper,ZooKeeper 存储了 Topic 列表、分区位置、ISR 列表等信息,为 Kafka 提供了一个可靠的分布式协调服务。集群中的一个 Broker 会被选为 Controller,Controller 负责管理分区副本状态,处理分区重平衡。

随着 Kafka 的发展,对于 ZooKeeper 的重度依赖也带来了一些问题。

元数据同步瓶颈

当 Controller 变更时,它需要从 ZooKeeper 加载完整的集群元数据,然后把这些数据同步给所有的 Broker,对于分区数量很大的集群,这个过程会很长,从而导致整个集群的服务终端。

一致性风险

在 ZooKeeper 模式下,集群本质上存在两个权力中心(ZooKeeper 和 Kafka Controller),它们之间的数据同步延迟会带来一致性问题。我们来看一个具体的场景。

假设我们现在有一个三台 Broker 的集群,分别为 Broker0,Broker1,Broker2,Broker0 为当前 Controller。

在某一时刻,当 Broker0 突然遇到了长时间 Full GC 时,由于 ZooKeeper 长时间没有收到 Broker0 的心跳消息,判断 Broker0 宕机,于是就删除了 /controller 临时节点,然后将 Broker1 选为新的 controller。这时 Broker0 从 GC 中恢复,此时它可能还没有意识到自己已经不是 Controller了,这就会导致集群中存在两个 Controller。假设有一个 Topic 原本的 Leader 是 Broker2,此时 Broker0 和 Broker1 都会给 Broker2 发送指令,下令把分区 Leader 切换到自己。这就会带来比较严重的影响,即一部分 Producer 会把数据写到 Broker0,另一部分 Producer 把数据写到 Broker1。直接导致数据混乱,同时 Consumer 也不知道要消费哪个 Broker 的数据。

运维复杂性

第三个问题就是运维复杂性,ZooKeeper 属于一个独立的组件,如果选择 ZooKeeper 模式,运维人员就需要维护两套系统(Kafka + ZooKeeper),大幅提升了运维复杂度。

基于以上问题,Kafka 社区决定放弃 ZooKeeper,发展内部的共识协议 KRaft。

引入 KRaft

抛弃 ZooKeeper 之后,Kafka 演进到了 KRaft(Kafka Raft)模式,这是一种 Kafka 内部的共识协议,它可以让 Kafka 实现自我管理。

架构

KRaft

KRaft 模式下,Broker 有两种角色,一种是 Controller Quorum,另一种是 Broker Nodes,可以在配置文件中通过 process.roles 参数来指定 Broker 的角色。Controller Quorum 通常由 3 个或 5 个 Broker 组成,它们之间会选举出来一个作为 Leader。

对于元数据的存储,KRaft 维护了一个内部 Topic __cluster_metadata,所有的集群变更都会作为一条条消息写入到这个 Topic 中,集群内的其他 Broker 通过消费这个 Topic 的消息来感知集群变更。Broker Nodes 节点作为业务节点,只负责数据的读写。

部署方式

KRaft 模式下有两种部署方式,一种是混合模式,一种是隔离模式。

混合模式是指同一个进程即是 Broker,又是 Controller,即 process.roles=broker,controller。这种模式一般适合小型集群或者测试环境。

隔离模式是指 Broker 和 Controller 运行在不同的服务器,这样 Controller 就不会受到大流量的影响,整个集群会更加稳定。在配置时,一部分节点配置为 process.roles=broker,另一部分配置为 process.roles=controller 即可。

为什么解决了问题

我们重点看一下 KRaft 模式为什么解决了前面提到的一致性问题。最直观的一点就是 KRaft 模式下权力中心合二为一,避免了出现多个 Leader 的情况,Controller Quorum 选举的每一任 Leader 都有一个唯一的 Epoch。在向 __cluster_metadata 主题写入指令时会带有自己的 Epoch,其他 Broker 消费到指令时,只认 Epoch 最大的指令。

总结

最后我们以一张表格来对比一下 ZooKeeper 和 KRaft 两种模式。

特性 ZooKeeper 模式 KRaft 模式
外部依赖 需要部署 ZooKeeper 集群
元数据存储 存储在 ZooKeeper 中 内部 Topic
Leader 选举 依赖 ZooKeeper 协调 基于 Raft 协议选举
元数据更新 Controller 广播给 Broker Broker 主动消费
分区上限 受限于 ZK,约 20 万左右 可以支撑 100 万+分区
恢复时间 较长 极短

基于以上对比,我们还了解了依赖 ZooKeeper 为 Kafka 带来的性能瓶颈、一致性问题、以及运维复杂度的提高。在新版本的 Kafka 中,已经全面拥抱 KRaft 了。当然,Kafka 弃用 ZooKeeper 并不代表 ZooKeeper 一无是处,每个系统都有适合自己的应用场景,在合适的场景应用合适的系统才是正确的选择。

http://www.jsqmd.com/news/673407/

相关文章:

  • 告别PS!Mulimg Viewer图像拼接保姆级教程:从实验数据到期刊级Figure全流程
  • 深开鸿的开源鸿蒙OS,能不能用云固件的模式来快速安装?超多截图,有故事。第一集,故事未完,还有第二集。
  • 零基础玩转all-MiniLM-L6-v2:5分钟搞定语义搜索环境搭建
  • 如何利用backdoor-apk实现安卓应用的远程控制
  • 谢菲尔德大学发现极限压缩AI模型时,初始化才是真正的拦路虎
  • 制造业、质检类20种业务场景,SQL精写技巧
  • 从理论到代码:我是如何复现EVO的ATE/RPE计算并与官方结果对齐的(含避坑点)
  • 从宁德新能源面试官视角,拆解Halcon/OpenCV工程师的硬核技能树(附避坑指南)
  • Workrave终极指南:告别重复性劳损的完整解决方案
  • DebateLab-个人博客(1)后端总体架构与比赛状态机设计
  • 魔兽争霸3终极优化指南:如何用WarcraftHelper解决老游戏兼容性问题
  • C语言学习笔记5
  • 3分钟学会ncmdump:终极网易云音乐NCM文件解密转换指南
  • Go语言如何做协程调度_Go语言协程调度原理教程【实用】
  • HTML怎么实现记住我功能_HTML checkbox保存登录状态【方法】
  • 想给游戏加个BGM?试试用C和minimp3实现一个轻量级跨平台音频播放模块
  • Qwen3.5-2B低门槛部署指南:无Linux经验用户也能完成的5步流程
  • 避坑指南:沁恒CH582/CH583 Sleep模式下RTC唤醒的中断与主频那些事儿
  • 阿里通义实验室“变形金刚“:当AI探索助手学会了按需切换记忆模式
  • SAP PS 项目预算按 “成本计划→预算分配→执行监控→调整→结算→关闭” 的阶段推进,核心表为 BPGE/BPJA(总计 / 年度预算)、BPBE(行项目)、RPSCO(汇总成本 / 预算),配合
  • 别再死记硬背了!用Python手把手教你构建NLP中的共现矩阵(附完整代码与SVD降维实战)
  • 终极风扇控制指南:5分钟让Windows电脑安静如新的完整教程
  • Gemma-3-270m入门指南:从模型选择到提问技巧的完整新手教学
  • 嵌入式BI革命:SaaS/ISV厂商如何用衡石科技快速上线数据分析能力
  • Debian 12.10 root 登录失败,两步解决!
  • AngularJS ng-model 指令
  • PCB绘制
  • Blazor + WASM + WebGPU 实时渲染面试突击包:含WebAssembly SIMD加速、GPU缓冲区绑定、帧同步调试全流程(仅限Q2开放下载)
  • 大恒相机取消曝光限制(超长曝光)设置与代码实现(C/C++/C#)
  • WinClaw安全实战 10|5分钟微信接入指南:零代码远程操控电脑,AI助手随身带