kafka如何保证不丢失数据呢

时间:2024-04-03 18:52:14

kafka如何保证不丢失数据呢

kafka主要数据传输点主要有三个
1、保证producer写入过程中不丢数据
2、保证broker中不丢数据
3、保证消费者消费时不丢数据

场景一 producer写入过程中丢失数据:
–首先得了解kafka的写入流程才能找寻到producer丢数据的场景
1、producer首先从zk的"…/state"节点中get到本分区中leader的信息
2、producer将信息推送给leader
3、leader顺序写入本地log
4、followers从leader pull拉取到信息后也写入本地log,然后返回ack给leader
5、 此时当所有follower都返回ack后,生成一个hw,并且提交offset
6、最后leader返回ack给producer,表示此次数据接收完成。
注:kafka的生产者推送消息是采用异步的方式进行消息推送 main线程不断将消息发送给recordAccumulator,Sender线程不断从RecordAccumulator中拉取消息发送到kafka broker中。

第二步详解:

kafka如何保证不丢失数据呢

那么在这样的写入流程下,必须要保证写入失败的情况下producer得知道,那么topic之间是以ledaer返回
—ack=0
ack=0表示 producer发送消息后不需要等待leader发送ack就可以继续发送第二条消息,这种情况会产生producer无法知道这条数据的写入是否发生了异常,所以在这种情况下发生了异常retry参数也是不起作用的,所以这种情况会产生数据丢失,但是速度快。
—ack=1
ack=1表是producer发送数据后leader数据写入后就返回ack给producer,这种情况下可能会出现这个leader虽然落盘了,但是fllower的副本没有同步,此时leader挂了,需要重新在isr中选举leader,但是这条数据producer会默认发送成功所以不会再发送。该种情况下这条数据就丢失了
—ack=-1
ack=-1就是leader同步后,并且所有的isr的副本都同步完成后,并发送ack给leader,此时leader才会返回成功给producer。也就是说当producer发送数据给leader后fllower未同步,此时leader挂了,那么就producer就会感知到消息发送异常,会重新写发送。(这种情况会导致数据重复发送)

—那么当重试之后需依然发送失败呢 retry.backoff.ms=100(毫秒)这时候配置一下返回时间,就需要在catch块内将这个条消息入缓存或者db,等恢复后重新发送。

场景二 consumer消费数据过程中丢失:
consumer消费消息主要是流程
1.利用poll方法循环获取topic中消息
2.消费消息
3.提交offset

那么数据丢失可能性就是offset提交了 但是消息消费出错了
offset提交方式一共有两种

1、自动提交是auto.commit.interval.ms 默认是5秒钟提交一次,无论你拉取的数据在处理过程中是否 报错都会5s提交一次,所以不可取
2、手动提交 enabel.auto.commit=flase
这时候手动提交的offset的代码一定要在消息消费之后,手动提交的好处就是:比如你拉取了100条数据,50条时报错了,你就可以手动提交偏移量为50+1;保证了50之后的数据还是会再次消费到的。

场景三 broker中数据丢失
该场景丢失数据主要是在leader挂了导致
1、主要是要设置副本数,replication-factor 3
2、min.insync.replicas = 2
分区ISR队列集合中最少有多少个副本,默认值是1,这个值一般设置n/2+1
3、unclean.leander.election.enable = false
改参数表示新的leader只能从isr中选举出来,isr之外的副本不行