Kafka 高可用设计
Kafka在早期版本中,并不提供高可用机制,一旦某个Broker宕机,其上所有Partition都无法继续提供服务,甚至发生数据丢失
对于分布式系统,当集群规模上升到一定程度后,宕机的可能性大大提高,对高可用性就有了非常高要求
Kafka在0.8版本提供了高可用机制,主要是增加了Partition的复制设计
引入Partition的Replication之后,同一个Partition的就有了多个副本,把这些副本均匀的分布到多个Broker上,就保证了数据的安全,不再担心某个Broker宕机后使其中的Partition失效
Partition没有Replication时,写入消息的逻辑很简单,现在有个多个副本,写消息时如何处理呢?
Kafka给多个Replication设置了一个Leader,其他副本叫做follower,Producer发送消息时,只发送给Leader,follower再从leader复制消息
Kafka的消息复制思路比较独特,既不是同步复制,也不是完全的异步复制
同步复制非常安全,要求所有follower都复制完成才算是commit成功,但极大影响了吞吐率
完全异步复制的话性能很高,只要leader写入成功就算完成了,follower异步从leader进行复制,但安全性不好,数据丢失风险高
Kafka的Leader会看哪些follower的数据与自己是同步的,将其视为好同志,重点培养,放入一个列表,称为ISR(in-sync replica),当Leader收到新消息时,将消息发给列表成员,这些成员收到后,马上返回确认信息,Leader收到他们的确认后,就告诉 Producer消息已经提交成功
所以Kafka是采用了同步和完全异步的折中方式,让一部分高效的follower同步,让其他follower异步
Replication的目的就是在发生意外时及时顶上,leader失效后,就需要从follower中马上选一个新的leader
选举时优先从ISR中选定,因为这个列表中follower的数据是与leader同步的,从他们中间选取可以保证数据完整
但如果不幸ISR列表中的follower都不行了,就只能从其他follower中选取,这时就有数据丢失的可能了,因为不确定这个follower是否已经把leader的数据都复制完成了
还有一种极端情况,就是所有副本都失效了,这时有两种方案
(1)等待ISR中的一个活过来,选为Leader,数据可靠,但活过来的时间不确定
(2)选择第一个活过来的Replication,不一定是ISR中的,选为leader,以最快速度恢复可用性,但数据不一定完整
Kafka支持通过配置选择使用哪一种方案,可以根据可用性和一致性进行权衡