Kafka & RocketMQ 关于数据丢失的态度和策略
kafka & rocketmq 关于自身应用的场景#
技术是服务于业务的,当我们在思考为什么kafka可以容忍少量数据丢失,而rocketmq不能容忍数据丢失时,我们就不能不考虑它们所面临的业务场景
- kafka 日志采集、监控指标、实时统计、IoT 设备数据等
- rocketmq 交易、支付、订单、物流等金融级场景
kafka & rocketmq 关于数据丢失的场景#
kafka#
生产端丢失#
- acks=0生产者发完直接认为成功,网络抖动、broker 宕机都会丢数据.acks=1:仅主分区落盘就返回,主副本刚写入就宕机,副本未同步 → 丢数
- 发送失败不重试 / 重试次数为 0
服务端丢失#
- 未开启日志刷盘(默认刷盘策略)
- 副本同步不及时 + leader 宕机 高水位 HW 未推进,新消息只在 leader、没同步到 follower,leader 宕机选新主 → 丢未同步数据
- 分区副本数 = 1 单副本无备份,机器故障必然丢部分数据
消费者端丢数#
- 自动位移提交(默认)+ 消费未完成就提交 offset
- 手动提交 offset 时机错误
rocketmq#
生产者端:强确认 + 重试,避免发了就丢#
3 种发送模式#
- Oneway:只管发、不等应答(类似 Kafka acks=0),丢得最多,适合日志
- 异步发送 + 回调:发完就走,回调里处理失败;不写回调会丢
- 同步发送(默认推荐):send() 阻塞,直到 Broker 明确返回写入成功才认为发送完成
自带重试#
同步发送失败默认重试 3 次,可配置;网络抖动、主从切换时比 Kafka 更稳
Broker 端:刷盘 + 主从双保险#
- 刷盘策略 ASYNC_FLUSH(默认):写 PageCache 就返回,后台异步刷盘 SYNC_FLUSH:写 PageCache 刷盘完成后再返回,同步刷盘,耗时长
- 主从复制 ASYNC_MASTER:主写成功立即返回,异步复制给从;主挂可能丢少量 SYNC_MASTER2:主写成功后,同步复制给从
- 存储结构 CommitLog 顺序写、ConsumeQueue 索引异步写;只要 CommitLog 不丢,索引丢了可重建,数据更安全
消费端:手动 ACK + 重试 + 死信队列,防止 “消费中丢”#
- 必须手动 ACK:消费成功后调用 message.ack();没 ACK 会一直重发
- 自动重试:消费异常(数据库失败、超时)→ 不 ACK → Broker 重新投递
- 死信队列:重试 16 次仍失败 → 进死信队列,人工处理,不丢
原创
mq-2
本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。
评论交流
欢迎留下你的想法