如何保证向kafka中写入数据时,数据不会丢失

如何保证向kafka中写入数据时,数据不会丢失

1、Kafka写入数据丢失问题

什么情况下Kafka中写入数据会丢失呢?

      其实也很简单,大家都知道写入数据都是往某个Partition的Leader写入的,然后那个Partition的Follower会从Leader同步数据。但是万一1条数据刚写入Leader Partition,还没来得及同步给Follower,此时Leader Partiton所在机器突然就宕机了呢?

大家看下图:

如何保证向kafka中写入数据时,数据不会丢失 

      如上图,这个时候有一条数据是没同步到Partition0的Follower上去的,然后Partition0的Leader所在机器宕机了。此时就会选举Partition0的Follower作为新的Leader对外提供服务,然后用户是不是就读不到刚才写入的那条数据了?因为Partition0的Follower上是没有同步到最新的一条数据的。这个时候就会造成数据丢失的问题。

 

2、Kafka的ISR机制是什么?

       现在我们先留着这个问题不说具体怎么解决,先回过头来看一个Kafka的核心机制,就是ISR机制。

这个机制简单来说,就是会自动给每个Partition维护一个ISR列表,这个列表里一定会有Leader,然后还会包含跟Leader保持同步的Follower。也就是说,只要Leader的某个Follower一直跟他保持数据同步,那么就会存在于ISR列表里。

       但是如果Follower因为自身发生一些问题,导致不能及时的从Leader同步数据过去,那么这个Follower就会被认为是“out-of-sync”,从ISR列表里踢出去。所以大家先得明白这个ISR是什么,说白了,就是Kafka自动维护和监控哪些Follower及时的跟上了Leader的数据同步。

 

3、Kafka写入的数据如何保证不丢失?

         所以如果要让写入Kafka的数据不丢失,你需要要求几点:

         1、每个Partition都至少得有1个Follower在ISR列表里,跟上了Leader的数据同步

         2、每次写入数据的时候,都要求至少写入Partition Leader成功,同时还有至少一个ISR里的Follower也写入成功,才算这个写入是成功了

         3、如果不满足上述两个条件,那就一直写入失败,让生产系统不停的尝试重试,直到满足上述两个条件,然后才能认为写入成功

         4、按照上述思路去配置相应的参数,才能保证写入Kafka的数据不会丢失

        好!现在咱们来分析一下上面几点要求。

        第一条,必须要求至少一个Follower在ISR列表里。

那必须的啊,要是Leader没有Follower了,或者是Follower都没法及时同步Leader数据,那么这个事儿肯定就没法弄下去了。

        第二条,每次写入数据的时候,要求leader写入成功以外,至少一个ISR里的Follower也写成功。

        大家看下面的图,这个要求就是保证说,每次写数据,必须是leader和follower都写成功了,才能算是写成功,保证一条数据必须有两个以上的副本。这个时候万一leader宕机,就可以切换到那个follower上去,那么Follower上是有刚写入的数据的,此时数据就不会丢失了。

如何保证向kafka中写入数据时,数据不会丢失

       如上图所示,假如现在leader没有follower了,或者是刚写入leader,leader立马就宕机,还没来得及同步给follower。

       在这种情况下,写入就会失败,然后你就让生产者不停的重试,直到kafka恢复正常满足上述条件,才能继续写入。这样就可以让写入kafka的数据不丢失。

4、总结

       最后总结一下,其实kafka的数据丢失问题,涉及到方方面面。

       譬如生产端的缓存问题,包括消费端的问题,同时kafka自己内部的底层算法和机制也可能导致数据丢失。但是平时写入数据遇到比较大的一个问题,就是leader切换时可能导致数据丢失。所以本文仅仅是针对这个问题说了一下生产环境解决这个问题的方案。