Kafka维护一个AR(All Partition)列表,由ISR(与Leader数据同步的Replica)和OSR(与Leader数据不一样步的Replica)组成。刚开始全部的副本都在ISR中,在kafka工做的过程当中,由于各类问题(网络、磁盘、内存)致使某些副本同步速度慢于replica.lag.time.max.ms指定的阈值,则它们被踢出ISR,移动到OSR中。 kafka默认配置下,ISR中的全部Replica数据从Leader中同步完成,生产者才会认为数据提交成功,所以ISR的数据不易过多,并且他们之间的网络也应该畅通。OSR内的Replica是否同步了leader的数据不影响数据是否提交成功,它们会尽力不断从Leader中同步数据(出现OSR须要及时运维人员,排查故障,让其尽快回到ISR中,下降集群宕机的风险)网络
.HW(HighWatermark):数据被成功提交(ISR中的全部Replica同步完成),HW更新到该位置,HW以前的数据才能够被消费者访问,保证没有同步完成的数据不会被消费者访问到,这就是隔离性(两个事务之间互不影响)。运维
在leader宕机后,只能从ISR列表中选取新的leader,不管ISR中哪一个副本被选为新的leader都知道HW以前的数据,能够保证在切换了leader后,消费者能够继续看到以前已经提交的数据ui
若是leader宕机,选出了新的leader,而新的leader并无彻底同步以前leader的全部数据,以后又接受了新的数据,此时旧的leader恢复,则会发现新的leader中的数据和本身持有的数据不一致,此时旧的leader会将本身的数据截断到宕机以前的hw位置,并同步新leader的数据spa
生产者向leader发送数据时,能够选择须要的可靠性级别 ,经过request.required.acks参数配置:事务
0 - 生产者不停向leader发送数据,而不须要leader反馈成功消息 这种模式效率最高,可靠性最低 可能在发送过程当中丢失数据 可能在leader宕机时丢失数据 1 - 生产者发送数据给leader,leader收到数据后要等到ISR列表中的全部副本都同步数据完成后,才向生产者发送成功消息,若是一直收不到成功消息,则认为发送数据失败会自动重发数据. 这种模式下可靠性很高,可是当ISR列表中只剩下leader时,当leader宕机让然有可能丢数据 此时能够配置min.insync.replicas指定要求观察ISR中至少要有指定数量的副本,默认该值为1,须要改成大于等于2的值 这样当生产者发送数据给leader可是发现ISR中只有leader本身时,会收到异常代表数据写入失败,此时没法写入数据,保证了数据绝对不丢 虽然不丢可是可能会多数据,例如生产者发送数据给leader,leader同步数据给ISR中的follower,同步到一半leader宕机,此时选出新的leader,可能具备部分这次提交的数据,而生产者收到失败消息重发数据,新的leader接受 数据则数据重复了
所以kafka只支持At Most Once和At Least Once,不支持Exactly Once(到业务中去重)内存
默认配置下,当leader宕机时会选择ISR中的一个follower成为新的leader,若是ISR中的全部副本都宕机,而又要求集群可用,那么有下面两种选择:kafka
1.必须等待ISR列表中的副本活过来才选择其成为leader继续工做,将unclean.leader.election.enable设置为false同步
2.选择任何一个活着的副本可能不在ISR中成为leader继续工做,将unclean.leader.election.enable设置为trueit
第一种方法,可靠性有保证,可是可用性变低,只有最后挂了的leader活过来kafka集群才能继续工做io
第二种方法,可用性高,可靠性没有保证,任何一个副本活过来就能够继续工做,可是有可能存在数据不一致的状况