最近看到一个问题,kafka 是如何保证数据可靠的,仔细想了下这个问题,还是挺有趣的,所以和兄弟们分享分享。
一:背景
kafka 是一个分布式系统,所以他也要符合我们的CAP 定理对吧,那么是怎么符合的呢?兄弟们都知道kafka 的主要架构模型就是如下:
生产者往某个topic 发送消息,kaka 的broker 把消息存储起来,然后consumer 需要消费的时候就来拉取数据;
所以这就涉及到一个问题,万一某个broker 挂了,topic 的partition 没有了,那岂不是发不了消息了吗?所以这就涉及到了我们的topic 的分区的副本机制了,副本就是做容错的嘛,即使老大挂了,副本顶上
既然副本要顶上的话,那么副本的follower 就要和原来的老大leader 的数据基本上差不多才能顶上,对不,要不然顶上去也没啥意思啊。
对头,所以这就涉及到一开始分区的副本的leader 和follower 之间通信同步数据的问题,假设producer 发送一条消息到topiA 的partition-0,它有三个副本,我们要保证数据可靠肯定要确保老大leader把数据拿到手了,告诉了其他的副本兄弟之后,然后给producer 发送一个ack 表示确认消息已经收到了,你开始发送下一条消息吧,哥们
但是,上面的那个partition-0 要同步给多少副本兄弟才发送ack 给producer呢,这个是有讲究的,同步多了,producer 又会嫌弃慢,快nm呢;如果不怎么同步又会说你tm符合cap 定理嘛;所以这是个尺度的拿捏,然后这个时候kafka 官方就出现了ISR
二: ISR,OSR,AR
首先讲下这三个词组的意思:
ISR(In-Sync Replicas ):与leader保持同步的副本集合
OSR(Out-Sync Replicas): 与leader没有保持同步的副本集合
AR(Assigned Replicas):分区的所有副本
由上面的定义可以看出AR=ISR+OSR
所以,kafka 官方就很鸡贼,既然两头都不行,那么取一个折中的办法,选出来一些副本集合,在规定时间要和leader 老大同步完成信息的,只要这些集合里面的follower 都同步完成了,那么就可以向producer 发送ack 消息确认了;要不然就不会确认了;而且如果某个follower 在规定时间没有同步完成数据,则会被踢出这个ISR集合,等同步好了才上来。
不过我们也可以根据实际场景来选择这个ack同步的机制,ack 有三个值可以选择;
ack=0, 则表示当producer 发送消息给到broker之后,不等broker 写入数据就直接返回发送下一条;
ack=1, 则表示当发送消息后,等分区里面的leader 把数据写入之后就发送ack给到producer,producer 继续发送;
ack=-1, 则就是我们所说的,要等ISR 全部同步完成才发送ack消息,然后就让producer 继续发送消息
三:LEO,HW, LW,
LEO(log end offset):标识当前日志文件中已写入消息的最后一条的下一条待写入的消息的offset。上图中offset为9的位置即为当前日志文件的 LEO,LEO 的大小相当于当前日志分区中最后一条消息的offset值加1.分区 ISR 集合中的每个副本都会维护自身的 LEO ,而 ISR 集合中最小的 LEO 即为分区的 HW,对消费者而言只能消费 HW 之前的消息。
HW(High Watermark):所有副本中最小的LEO, 一个分区中所有副本最小的offset,取一个partition对应的ISR中最小的LEO作为HW,consumer最多只能消费到HW所在的位置上一条信息。
注意:HW/LEO这两个都是指已写入消息的最后一条的下一条的位置而不是指最后一条的位置。
LSO(Last Stable Offset): 对未完成的事务而言,LSO 的值等于事务中第一条消息的位置(firstUnstableOffset),对已完成的事务而言,它的值同 HW 相同
LW(Low Watermark): 低水位, 代表 AR(分区中的所有副本)集合中最小的 logStartOffset 值
.3.1:follower故障
follower发生故障后会被临时踢出ISR,待该follower恢复后,follower会读取本地磁盘记录的上次的HW,并将log文件高于HW的部分截取掉,从HW开始向leader进行同步。等该follower的LEO大于等于该Partition的HW,即follower追上leader之后,就可以重新加入ISR了。
3.2.leader故障
leader发生故障之后,会从ISR中选出一个新的leader,之后,为保证多个副本之间的数据一致性,其余的follower会先将各自的log文件高于HW的部分截掉,然后从新的leader同步数据。
版权归原作者 大数据小尘 所有, 如有侵权,请联系我们删除。