专栏名称: OSC开源社区
OSChina 开源中国 官方微信账号
目录
相关文章推荐
稀土掘金技术社区  ·  用了三年 ... ·  昨天  
程序猿  ·  有了这些 VS Code 的 ... ·  昨天  
稀土掘金技术社区  ·  CSS 全新属性如何实现一个内凹圆角 ·  2 天前  
51好读  ›  专栏  ›  OSC开源社区

kafka的高可用和一致性探究

OSC开源社区  · 公众号  · 程序员  · 2016-11-25 08:28

正文

请到「今天看啥」查看全文



我们本篇文章就重点通过kafka的原理来揭示在acks=-1的情况下,哪些情况下会丢失数据,或许可以提一些改进措施来做到不丢失数据。


下面会先介绍下leader和follower副本复制的原理


1.3 副本复制过程


● leader副本的属性

● highWatermarkMetadata:代表已经被isr列表复制的最大offset,consumer只能消费该offset之前的数据

● logEndOffsetMetadata:代表leader副本上已经复制的最大offset

leader副本拥有其他副本的记录,保存着他们的如下属性:

logEndOffsetMetadata:代表该follower副本已经复制的最大offset

● lastCaughtUpTimeMs:记录该follower副本上一次追上leader副本的所有消息的时间

● follower副本的属性

highWatermarkMetadata:follower会获取到leader的highWatermarkMetadata更新到自己的该属性中


● logEndOffsetMetadata:代表follower副本上已经复制的最大offset

其中follower会不断的向leader发送fetch请求,如果没有数据fetch则被leader阻塞一段时间,等待新数据的来临,一旦来临则解除阻塞,复制数据给follower。


我们来看下当producer的acks=-1时,一次消息写入的整个过程,上述是属性是怎么变化的。


1.3.1 消息准备写入leader副本,leader副本首先判断当前isr列表是否小于min.insync.replicas,不小于才允许写入。


如果不小于,leader写入到自己的log中,得到该消息的offset,然后对其他follower的fetch请求解除阻塞,复制一定量的消息给follower

同时leader将自己最新的highWatermarkMetadata传给follower


同时会判断这次复制是否复制到leader副本的末尾了,即logEndOffsetMetadata位置,如果是的话,则更新上述的lastCaughtUpTimeMs


1.3.2 follower会将fetch来的数据写入到自己的log中,自己的logEndOffsetMetadata得到了更新,同时更新自己的highWatermarkMetadata,就是取leader传来的highWatermarkMetadata和自己的logEndOffsetMetadata中的最小值


然后follower再一次向leader发送fetch请求,fetch的初始offset就是自己的logEndOffsetMetadata+1。


1.3.3 leader副本收到该fetch后,会更新leader副本中该follower的logEndOffsetMetadata为上述fetch的offset,同时会对所有的isr列表的logEndOffsetMetadata排序得到最小的logEndOffsetMetadata作为最新的highWatermarkMetadata


如果highWatermarkMetadata已经大于了leader写入该消息的offset了,说明该消息已经被isr列表都复制过了,则leader开始回应producer


判断当前isr列表的size是否小于min.insync.replicas,如果小于返回NotEnoughReplicasAfterAppendException异常,不小于则代表正常写入了。


1.3.4 follower在下一次的fetch请求的响应中就会得到leader最新的highWatermarkMetadata,更新自己的highWatermarkMetadata








请到「今天看啥」查看全文