kafka 副本复制参数理解笔记

kafaka有几个参数来保证数据在异常情况下不丢失。一直以来都没有搞的太清楚,后来又一次看了官方的文档,然后理解了,但不知昨天又想这个事情的时候,发现又模糊了。所以还是写下来,以来加深理解,而来做个思维备份吧。(说到思维备份,突然想到了黑镜里面的意识副本,什么时候我们的现实生活中也能有一种工具,可以把这个时候的想法瞬间保存起来,这貌似就不用我手动备份了。不过这种东西要是真实现了,貌似也很恐怖,呵呵)

 

kafka 的partition通过增加副本机器来防止宕机造成的数据丢失。partition中有leader角色 和 副本角色。leader负责处理producer 和 consume的请求,而副本机器只负责sync leader收到的消息。

按照正常的思维,当producer发消息给leader后,leader需要复制给其他副本,如果复制成功,那么数据就可以在至少一台机器不宕机的情况下,保证数据的不丢失。

但是有没有想过,不管是leader 还是 副本机器,他们都是将消息写log的,也就是已经持久化了,那么宕机了,按说也不会丢失啊。那是因为根本没有持久化。kafka的broker收到消息后,确实写的log,但是只是写到了page cache中,并没有刷到磁盘上。刷磁盘的动作是一个批处理的策略,会通过消息量,间隔时间来定期定量来刷,所以如果在刷之前宕机了(物理机宕机,进程挂掉其实并不会导致未刷到磁盘的数据丢失),消息就有可能宕机。其实就是每次broker收到了消息,然后立马将消息刷的磁盘(通过系统调用sync,来强制刷磁盘),这也不能保证数据不会丢失。因为从page cache 到磁盘的过程中其实也是个很复杂的流程,当系统调用返回成功了,也可能突然的宕机导致数据还没有持久化到磁盘(具体细节忘了,总之不是我们想的那样,支付宝的ocean base数据就因为这个不确定性,他们直接绕过了操作系统对刷磁盘的管理,直接自己实现了这一层)。所以如果kafka的leader和其他副本同时宕机了,还是有数据丢是的风险。这个是概率问题,看你想要几个9的可靠性吧。物理机宕机还是很少见的。

 

如果排除物理机宕机,那么只要kafka的副本中有一台机器活着,数据就会得到安全保证。kafka通过另个参数来控制这个行为。

broker端设置的 min.insync.replicas。 producer端设置的 acks。 这篇文章主要是讲这个,哎,扯了那么多其他的东西,罪过罪过。

producer的acks是说,broker是否回复我的send响应,什么情况下响应。

当acks 为0的时候: producer调用send完,然后producer线程把数据写入本地的tcp协议栈后,就算成功。根本不需要broker的响应。这种是最弱的,与broker的tcp断连,broker宕机都可能使数据丢失。

当acks为1时: producer发送的消息需要到达leader,然后leader也将这条消息写入log成功。但不用等到其他副本同步这条消息,leader即可返回客户端响应,即可认为是成功。这种情况防止了producer与broker tcp断连导致数据丢失。但无法防止leader宕机情况。你可能会说,一般只是进程宕机,数据都写入log了,又不会丢。其实说的没错,但是我要告诉你kafka 副本的处理机制,就会发现数据没丢,但是可能被当成垃圾数据被删掉。你想如果prodcuer发送给了leader,leader写入log成功,还没有同步给其他副本,然后就返回客户端成功了。这个时候leader挂了,其中一个副本顶替了leader的角色,副本上可没有这条消息。所以副本会认为没有那条消息,及时这个时候当时的leader又重启了,那这个leader会询问现在的leader,我该从那条消息开始认为都是好的呢?新leader就会说上一条消息,然后老leader就把本来告诉producer说发送成功的消息给删掉了(是不是很不负责任)。所以这个配置没有解决broker宕机这种情况。

 

当acks为all(-1)时:

当这么配置的时候,可以达到,n个副本中只要有一个副本活着,数据就不丢失。配置这后,具体操作时,producer发送消息给broker,broker需要将消息成功复制给所有在ISR列表中的副本后(这句话不准确,我要再研究研究),才算成功。

 

broker参数

min.insync.replicas: 

这个是说,ISR列表中最少有几个机器,如果低于这个数字,那么写服务将不可用。

有人有时候有一种理解是错误的,有人认为,如果将min.insync.replicas设为2,但ISR中有三台机器,那么只需要两台写成功了,就可以返回producer成功了。这是错误的,不管min.insync.replicas配置的是多少。如果acks是all,那么ISR中需要有全部的机器复制成功才算成功。

 

你可能感兴趣的:(kafka)