作为一个非常优秀的消息中间件,kafka如何做到高可用的,我们可以一起看看它的架构。
1、多分区,多副本设计
我们知道鸡蛋是不能放在同一个篮子的,那消息同样也如此。在kafka里有一个核心的概念叫做topic,类似于一个数据集合,我们所有的消息都是在topic里。
-
多分区
为了保障数据的完整性,Kafka有一个概念叫做partition,就是把一个topic的数据分拆成多个区保存一个分一点,这样我们的数据就分布在多台机器上。但是这样还有个问题就是万一其中一个分区挂了,那我们的数据就丢失了。 -
多副本
所以kafka就采用多副本的方式提高容错性。我们将一个分区的数据,拷贝多个副本到不同分区上去,并且选择其中一个做为leader,其他副本做为follower,只有leader提供读写,其他只负责同步数据。只有当leader挂了,大家再重新推选leader,以此达到了高可用。
2、kafka如何保证数据不丢失
从上面的架构来看,什么情况下会丢数据?当我们写数据时一般都是往leader写数据,但如果这个时候leader挂了,follower还没来得及同步数据,那这时候数据就丢失了。
kafka的核心ISR机制
要弄懂数据丢失的问题,我们得先知道ISR。简单来说kafka会自动给每个partition维护一个ISR列表。这个列表中一定会有一个leader,同步包含一个跟leader数据一致的follower。如果follower因为某种原因数据不一致了就会被踢出去。
-
生产者不丢失
每个partition都至少要有个follower在ISR列表中,在写入时候必须leader和其中一个follower都写入成功才算成功。 -
kafka不丢失
1、给 topic 设置 replication.factor 参数:这个值必须⼤于 1,要求每个 partition 必须有至少 2 个副本。
2、在 Kafka 服务端设置 min.insync.replicas 参数:这个值必须大于1,这个是要求⼀个leader 至少感知到有至少⼀个 follower 还跟自己保持联系,没掉队,这样才能确保 leader挂了还有⼀个 follower 吧。
3、在 producer 端设置 acks=all :这个是要求每条数据,必须是写入所有 replica 之后,才能认为是写成功了。在 producer 端设置 retries=MAX (很大的⼀个值,无限次重试的意思):这个是要求⼀旦写入失败,就无限重试。 -
消费者不丢失
作为消费者要关闭自动提交offset。