Leader - Follower 消息同步
以Kafka为例子
在 Kafka 中,Leader 节点确保所有 Follower 节点成功接收消息的机制,主要通过 ISR(In-Sync Replicas,同步副本列表) 和 acks 消息确认机制 实现,具体流程如下:
1. 核心机制:ISR 列表与同步确认
-
ISR 列表:每个分区的 Leader 会维护一个 ISR 列表,记录与自己保持同步的 Follower 节点(包括 Leader 自身)。
Follower 需满足两个条件才能留在 ISR 中:- 与 Leader 保持网络连接(通过定期 heartbeat 心跳机制确认存活);
- 消息同步进度不落后于 Leader 太多(可通过
replica.lag.time.max.ms
配置容忍的最大同步延迟,默认 30 秒)。
-
消息同步流程:
- 生产者发送消息到 Leader 后,Leader 将消息写入本地日志;
- Follower 定期向 Leader 发送拉取请求(
FetchRequest
),同步新消息并写入本地日志; - Follower 同步完成后,向 Leader 返回确认(
FetchResponse
); - Leader 收到 Follower 的确认后,更新该 Follower 的同步进度,确保其留在 ISR 中。
2. 确保所有 Follower 接收的关键配置:acks 参数
生产者通过设置 acks
参数,控制 Leader 何时向生产者返回“消息发送成功”的确认,从而间接确保 Follower 同步状态:
-
当
acks=all
(或-1
)时:
Leader 必须等待 ISR 中所有副本(包括所有 Follower) 都成功写入消息后,才向生产者返回确认。
这是最严格的配置,可确保消息被所有同步的 Follower 接收(只要它们在 ISR 中)。 -
其他
acks
配置的区别:acks=1
(默认):仅 Leader 写入成功后即返回确认,不等待 Follower 同步(可能存在 Follower 未收到的风险);acks=0
:Leader 接收消息后立即返回确认,不等待写入本地日志(可靠性最低)。
3. 异常处理:Follower 同步失败的情况
- 若某个 Follower 长时间未同步(超过
replica.lag.time.max.ms
),Leader 会将其从 ISR 中移除; - 此时若
acks=all
,Leader 只需等待 剩余 ISR 中的副本 确认即可(无需等待已脱离 ISR 的 Follower); - 若需严格确保“最初配置的 2 个 Follower 都必须收到”,需结合以下配置:
min.insync.replicas=N
(例如设置为 3,即 Leader + 2 Follower 都在 ISR 中才允许写入);- 同时保证
acks=all
,此时若任何一个 Follower 脱离 ISR,生产者会收到异常(NotEnoughReplicasException
),需重试直到所有 Follower 同步完成。
总结
要确保 2 个 Follower 都收到消息,需满足:
- 生产者配置
acks=all
; - 2 个 Follower 均处于 ISR 列表中(同步正常);
- 可选配置
min.insync.replicas=3
(强制要求 Leader + 2 Follower 都同步成功,否则拒绝写入)。
通过这套机制,Kafka 既能保证消息可靠同步到 Follower,又能通过 ISR 动态调整同步范围,避免因个别节点故障导致整个集群不可用。
投票
当client端写请求给follower,请求会被重定向到leader
follower 150-300 ms收不到leader请求,就转化为候选人角色,开启投票。
投票的信息内容:日志的数据量,term的轮数