10.5.4 数据一致性保障(ISR、ACK、Leader/Follower复制)

数据一致性保障围绕副本集合、确认策略与复制机制展开,目标是在可用性与一致性之间取得可控平衡。本节给出原理草图、关键配置与可执行示例,并包含排错与练习。

文章图片

1. ISR(In-Sync Replicas)机制
- 定义:ISR 是与 Leader 保持同步的副本集合,只有 ISR 内副本才有资格被选为新 Leader。
- 入/出 ISR 条件
- 副本滞后(lag)超过阈值(replica.lag.time.max.ms)会被移出 ISR。
- 追赶到最新并满足时间条件后重新加入 ISR。
- 一致性意义:ISR 控制了可切换的副本范围,避免落后副本被选为 Leader 导致数据丢失。

示例:查看 ISR 与副本状态

# 预期效果:输出 ISR 副本列表、Leader、副本滞后
/opt/kafka/bin/kafka-topics.sh \
  --bootstrap-server 127.0.0.1:9092 \
  --describe --topic orders

2. ACK 确认策略
- acks=0:不等待确认,吞吐高但可能丢数据。
- acks=1:Leader 写入本地日志即确认,Leader 宕机会丢失未复制数据。
- acks=all/-1:等待所有 ISR 副本写入确认,可靠性最高但延迟增加。
- 推荐组合acks=all + min.insync.replicas 提升一致性保障。

示例:生产者配置与发送

# /opt/kafka/config/producer.properties
bootstrap.servers=127.0.0.1:9092
acks=all
retries=5
enable.idempotence=true
# 预期效果:消息只有在ISR内副本确认后才返回
/opt/kafka/bin/kafka-console-producer.sh \
  --bootstrap-server 127.0.0.1:9092 \
  --topic orders \
  --producer.config /opt/kafka/config/producer.properties

3. Leader/Follower 复制流程
- 写入流程:生产者写入 Leader → 追加日志 → Follower 拉取复制 → ISR 内确认。
- 读一致性
- Leader 读:强一致但受 Leader 负载影响。
- Follower 读:低延迟但可能读到旧数据,需要配置与业务容忍度匹配。
- 高水位(HW):消费者只能读取到 HW 以内的数据,保证已提交可见性。

示例:验证 HW 可见性

# 启动消费者读取已提交消息(只读HW以内)
/opt/kafka/bin/kafka-console-consumer.sh \
  --bootstrap-server 127.0.0.1:9092 \
  --topic orders \
  --from-beginning

4. 关键配置与策略(含安装/配置修改)
- min.insync.replicas:限制最小同步副本数,搭配 acks=all 防止单副本提交。
- unclean.leader.election.enable:默认关闭,避免落后副本强制选主导致数据回滚。
- 副本因子:生产建议 ≥3。

示例:服务端配置与生效

# /opt/kafka/config/server.properties(示例片段)
min.insync.replicas=2
unclean.leader.election.enable=false
default.replication.factor=3
replica.lag.time.max.ms=10000
# 重启服务生效(示例:systemd)
systemctl restart kafka

示例:在线修改 topic 级别 min.insync.replicas

/opt/kafka/bin/kafka-configs.sh \
  --bootstrap-server 127.0.0.1:9092 \
  --alter --entity-type topics --entity-name orders \
  --add-config min.insync.replicas=2

5. 一致性保障实践建议
- 关键业务启用 acks=allmin.insync.replicas>=2、禁止不干净选主。
- 监控 ISR 变化、Leader 频繁切换与副本 lag,提前发现一致性风险。
- 在容量规划上预留副本同步带宽,避免复制延迟导致 ISR 频繁收缩。

排错清单(可执行)

# 1) ISR 收缩:查看分区状态与滞后
/opt/kafka/bin/kafka-topics.sh --bootstrap-server 127.0.0.1:9092 --describe --topic orders

# 2) 检查副本是否频繁掉队(定位网络/磁盘瓶颈)
grep -E "ReplicaFetcher|isr|lag" /opt/kafka/logs/server.log | tail -n 50

# 3) 消息发送失败(acks=all 且 ISR 不足)
# 预期:提示 NotEnoughReplicas 或 NotEnoughReplicasAfterAppend

练习(动手验证一致性)
1. 创建副本因子为 3 的主题并验证 ISR:

/opt/kafka/bin/kafka-topics.sh \
  --bootstrap-server 127.0.0.1:9092 \
  --create --topic orders --partitions 3 --replication-factor 3
/opt/kafka/bin/kafka-topics.sh --bootstrap-server 127.0.0.1:9092 --describe --topic orders
  1. 设置 min.insync.replicas=2,并将一个 broker 停止,观察发送失败与 ISR 变化。
  2. acks=1acks=all 分别发送 1000 条消息,记录延迟与丢失情况(可用时间戳统计)。