结论:
kafka只对已提交的消息,做最大限度的持久化保证不丢失
- 已提交:Broker回复Producer已经收到了消息
- 最大限度的持久化:至少有一个Broker存活
丢数据的场景
Producer端
- broker在收到producer发来的消息时,会回复ACK给到Producer
- ACK = 0:producer发送消息给到Broker,就自认为是发送成功,不去校验ACK。如果发送过程中发生网络抖动,那么消息丢失。
- ACK = 1:Producer发送消息给到Broker LeadPartition并接受成功。如果LeadPartition因为异常毁坏了,而且Follower Partition还没有同步数据,且没有ACK返回,这时就会丢失消息。
- ACK = -1: 等待LeadPartition和FollowerPartition都确认收到了消息;如果这个时候只有leadPartition,那么就相当于ACK = 1的情况,leadPartition在持久化文件前损坏了,那么消息就会丢失。
Broker端
- Broker端是通过异步刷盘的;如果数据已经写入到系统中的PageCache中但是还没有来得及刷入磁盘,此时Broker宕机或者停电,极端情况下会造成数据丢失
Consumer端
- consumer会拉取Broker中的数据,然后提交Offset
- 先提交Offset,后处理数据;如果此时consumer处理数据时发送异常宕机,待Consumer重启后,就会从该Offset下的下一个开始消费,对于Consumer来说,消息就丢失了
- 先处理数据,后提交Offset;如果在提交offset之前consumer发生宕机,不回丢失消息,但是Consumer回重复消费;