04.Kafka集群
# 01.Kafka集群介绍
# 1、kafka集群模式
# 1)多分区多副本集群模式
① 核心特点
每个主题拆分为多个分区分布在不同 Broker 上
,提升吞吐量与负载均衡
每个分区拥有多个副本
,其中一个是 Leader,负责读写,其余为 Follower,用于备份与故障切换
② 工作机制
读写操作通过分区 Leader 进行,Follower 同步数据
Leader 宕机时,通过 ZooKeeper 或 KRaft 选举新 Leader,确保高可用性
③ 部署配置
Kafka:建议至少 5 个节点,分担分区与副本负载,增强容错能力
ZooKeeper:部署 3~5 个节点,保证领导者选举和一致性
副本数量:每分区建议配置 3 个副本,平衡可靠性和性能
# 2)KRaft 模式
自Kafka 2.8起,KRaft(Kafka Raft)模式逐渐取代Zookeeper,成为Kafka集群的元数据管理方式
KRaft模式中,集群中的元数据由特殊的控制节点(Controller Nodes)管理,这些节点通过Raft协议进行选主和元数据同步
# 2、多分区多副本工作场景
# 1)Kafka 集群架构
节点(Brokers)
- 负责存储分区数据、处理读写请求,多 个节点协调任务,分担负载
分区(Partitions)
- 数据流分为 50~100 个分区,支持高并发处理。每分区一个 Leader,其他为副本
副本(Replicas)
- 3 副本机制,确保数据冗余与高可用性,分布在不同 Broker 上防止单点故障
# 2)Kafka 工作机制
领导者选举(Leader Election)
- Broker 宕机时,ZooKeeper 或 KRaft 选出新的分区 Leader,保障读写不中断
数据同步
- Kafka 的 ISR(In-Sync Replica)机制定义了哪些副本是同步的
- 并且当
所有 ISR 副本都成功写入数据时,Kafka 才确认消息写入成功
,这样可以保证强一致性
数据持久化
- 顺序写入磁盘,提升日志存储效率,适合高并发写入场景
# 3)性能调优
分区数量
50 到 100 个分区
可以让 Kafka 并行处理大量任务,每个分区可以对应一个消费者进行并行消费,提升吞吐量- 但过多的分区也会增加每个 Broker 维护元数据和处理分区领导者选举的开销
副本数量
3 副本可以平衡数据安全和性能
- 在某个节点失效时,其余两个副本能保证数据的高可用性,但
副本越多,写入时的同步延迟也越大
网络和磁盘 IO
- Kafka 性能还依赖于节点间的网络传输速率和磁盘的读写能力
- 集群需要高速网络连接和优化的磁盘子系统(如 SSD),以避免成为瓶颈
# 4)可扩展性和高可用性
水平扩展
- 随着任务量增加,可以通过
增加分区数或增加更多的 Broker 来实现水平扩展
- 分区是 Kafka 扩展性的重要基础,更多的分区允许更多的消费者进行并行消费,提高处理能力
- 随着任务量增加,可以通过
高可用性
通过 3 副本策略,当某个 Broker 宕机时
,集群仍能保证分区数据的可用性和一致性- Kafka 还通过 ZooKeeper/KRaft 进行元数据管理和故障恢复
# 5)应用场景
- 大规模任务处理
- Kafka 的分区机制允许任务的并行处理,3 副本确保数据不会因为某个节点故障而丢失
- 50 到 100 个分区可以很好地支持任务负载的并行化执行
- 日志持久化
- Kafka 将消息持久化到磁盘,适合用于日志数据的存储和回放
- 日志可以被多个消费者读取,实现数据流分析和系统监控
# 02.KRaft原理
# 1、KRaft元数据管理
Kafka 的元数据(如主题、分区、副本分配、配置等)存储在特殊内部主题
__cluster_metadata
中元数据日志有多个副本,分布在不同的 Broker 上,确保冗余和容错
通过 Raft 协议 管理,
__cluster_metadata
的日志由Raft Leader 负责写入和同步到所有 Follower
更新数据必须获得多数节点(Quorum)的确认,确保一致性Zookeeper
# 2、Raft数据一致性原理
# 0) Raft 核心概念
1)领导者选举(Leader Election)
通过
选举产生集群中的唯一 Leader
,所有写请求由 Leader 处理
,Follower 负责复制日志
保证了所有的更新都是从一个集中点发出,避免了多节点写入造成的不一致
2)日志复制(Log Replication)
Leader 将日志条目复制到所有 Follower
只有当日志条目被
多数节点(Quorum)确认后,才被标记为提交(Committed)
,从而实现分布式数据一致性
3)安全性(Safety)
- 确保已提交的日志条目不会被覆盖,即使在网络分区或 Leader 切换后,所有节点最终会达到一致的日志状态
# 1) 领导者选举
① 触发选举
- 若 Follower 在
超时前未收到 Leader 的心跳或日志请求
,则转变为候选者(Candidate)
,并开始新一轮选举
- 若 Follower 在
② 投票过程
候选者增加自己的任期号(Term Number),给自己投票
,并向其他节点发送RequestVote
请求- 每个节点根据当前日志状态(包括任期号和日志索引)决定是否投票
候选者获得多数投票后,成为新的 Leader
③ 心跳维持
- Leader 周期性发送心跳(AppendEntries RPC)以维护自己的领导地位
④ 失败与重试
- 若选举过程中没有选出 Leader,候选者会超时并再次发起选举,直至成功
# 2) 日志复制
① 客户端请求
- 客户端请求写操作时,
Leader 将该操作转换为日志条目,并追加到自己的日志
- 客户端请求写操作时,
② 日志同步
- Leader 使用
AppendEntries
RPC 将日志条目复制到所有 Follower 节点
- 每个日志条目都带有前一条
日志的索引和任期号
,Follower 仅在匹配时才接受新的日志
- Leader 使用
③ 日志提交
- 当
日志条目被多数节点确认后
,Leader 将其标记为已提交(Committed)
- Follower 在收到提交通知后也会标记日志为已提交
- 当
④ 日志应用
日志条目被提交后
,Leader 和 Follower 会将日志中的操作应用到本地状态机
# 3) 安全性
① 日志不可逆(Log Immutability)
已提交的日志条目不会被覆盖
,新的 Leader 必须拥有所有已提交的日志
,这通过选举中检查日志匹配性来保证
② 日志一致性
Raft 确保在网络分区或节点故障的情况下,日志状态最终保持一致
任期号和日志索引用于区分和防止过时的 Leader 写入新日志
# 3、任期号和日志索引
任期号 (Term)
和日志索引 (Log Index)
是核心概念,用于确保系统的 一致性 和 安全性
1)任期号 (Term)
每次选举产生新的 Leader,任期号都会增加
任期号由集群中的所有节点维护,用于区分不同的领导权时段
2)日志索引 (Log Index)
每条日志在
日志条目中都有一个唯一递增的索引值
配合任期号,唯一标识日志条目(即
(Term, Index)
)
3)Raft 的一致性保证
任期号保证 Leader 的合法性
(Term, Index)
保证日志的唯一性和顺序性,防止过时的 Leader 写入无效或冲突的日志
eg:
集群包含 3 个节点(A、B、C),当前
任期号 Term=3
,Leader 是 Server A
网络分区导致 Server A 与 B、C 分离
,触发重新选举选举
Leader 是 Server C
,任期号 Term=4
网络恢复后,
Server A 仍认为自己是 Leader
,试图追加日志(Term=3, Index=3)
。Server C 检查 Term=3
,发现过时,拒绝请求并通知 Server A 更新任期号