Kafka 消息不丢失
- 生产者丢失
- 消费者丢失
- 不丢失配置
Kafka 保证消息不丢失:只对已提交的消息 (committed message) 做有限度的持久化保证
- 已提交的消息:当 n 个 Broker 成功接收到该消息并写入到日志文件后,就告诉生产者该消息已成功提交
- 有限度的持久化保证 : 消息保存在 N 个 Broker 上,要至少有 1 个存活
- Kafka 只对已提交的消息,并满足一定的条件,能实现不丢失消息
生产者丢失
Kafka Producer 是异步发送消息的 ,调用 producer.send(msg)
,会立即返回,就无法知道消息是否发送成功
消息发送不成功的原因:
- 网络抖动 : 导致消息就没有发到 Broker 端
- 消息本身不合格,导致 Broker 拒绝接收 (如 : 消息太大)
- 所有的 Broker 都挂了
解决方法:Producer 用 producer.send(msg, callback)
有回调通知的发送 API
消费者丢失
Consumer 端的位移:
- 位移:该 Consumer 消费当前 Topic 分区的位置
Consumer 的对位移的消息丢失解决:
- 先消费消息,再更新位移的顺序
- 能最大限度地保证消息不丢失,但可能消息的重复处理
Consumer 用多个线程异步处理消息,并自动更新位移
- 当某个线程运行失败,某个消息没有被成功处理,但位移已经更新,该消息对 Consumer 就是丢失状态
- 解决方案:Consumer 手动提交位移
不丢失配置
- 当 ISR 只有 1 个副本 ,acks=all ,相当于 acks=1
min.insync.replicas
目的 :下限的限制- 不能只满足 ISR 全部写入,还要保证 ISR 中的写入个数大于
min.insync.replicas
- 对可重试的错误,retries 才会触发,否则直接进入到 callback
Producer | producer.send(msg, callback) | 用带回调通知的 send 方法 |
---|---|---|
acks = all | all:所有副本 Broker 都接收到消息,才认为已提交 | |
retries > 0 | 自动重试消息发送,避免消息丢失 | |
Broker | unclean.leader.election.enable = false | 不允许落后 Leader的Broker,成为新Leader |
replication.factor >= 3 | 消息多副本 | |
min.insync.replicas > 1 | 消息至少要写入 n 个副本才是已提交 | |
replication.factor = min.insync.replicas + 1 | 防止一个副本挂了,整个分区就无法正常工作 | |
Consumer | enable.auto.commit = false | 手动提交位移 |