点一下关注吧!!!非常感谢!!持续更新!!!
目前已经更新到了:
- Hadoop(已更完)
- HDFS(已更完)
- MapReduce(已更完)
- Hive(已更完)
- Flume(已更完)
- Sqoop(已更完)
- Zookeeper(已更完)
- HBase(已更完)
- Redis (已更完)
- Kafka(正在更新…)
章节内容
上节我们完成了如下内容:
- Kafka 控制器中的 Broker 选举
- Kafka可靠性中的 副本复制、失效副本、副本滞后 等问题
一致性保证
基本概念
水位标记
水位或者水印(Watermark)一次,表示位置信息,即位移(offset)。Kafka源码中使用的名字是高水位,HW(high Watermark)。
副本角色
Kafka分区使用多个副本replica提供高可用。
LEO和HW
每个分区副本对象都有两个重要的属性:LEO和HW
- LEO:记日志末端位移(log and offset),记录了该副本日志中下一条消息的位移值。如果LEO=10,那么表示该副本保存了10条消息,位移值范围是【0,9】。
- Leader LEO 和 Follower LEO的更新是有区别的
- HW:即上面提到的水位值,对于同一个副本对象而言,其HW值不会大于LEO值,小于等于HW值的所有消息都认为是“已备份”的replicated。Leader副本和Follower副本的HW更新不同。
上图中,HW值是7,表示位移的07的所有消息都已经处于“已提交状态”(COMMITED)。而LEO值是14,813的消息就是未完全备份(fully replicated)。
- 为什么没有14?LEF是指向下一条消息到来时的位移。
- 消费者无法消费分区下Leader副本中位移大于分区HW的消息
Follower副本何时更新LEO
Follower副本不停向Leader副本所在的Broker发送fetch请求,一旦获取消息后写入自己的日志中进行备份。
那么Follower副本的LEO是何时更新的呢?Kafka有两套Follower副本LEO:
- 一套LEO保存在Follower副本所在的Broker的副本管理中
- 另一套LEO保存在Leader副本所在的Broker的副本管理中
- Leader副本上保存了所有Follower副本的LEO
Kafka使用前者帮助Followr副本更新其HW值,利用后者帮助Leader副本更新其HW。
Follower副本的本地LEO何时更新
Follower副本的LEO值就是日志的LEO值,每当新写入一条消息,LEO值就会被更新,当Follower发送fetch请求后,Leader将数据返回给Follower,此时Follower开始Log写数据,从而自动更新LEO值。
Leader端Follower的LEO何时更新
Leader端的Follower的LEO更新发生在Leader处理Follower fetch请求的时候,一旦Leader接收到Follower发送的fetch请求,它先从Log中读取相应的数据,给Follower返回数据前,先更新Follower的LEO。
Follower副本何时更新HW
Follower更新HW发生在其更新LEO之后,一旦Follower向Log写完数据,尝试更新自己的HW值。
比较当前LEO值域fetch响应中Leader的HW值,取两者的小者作为新的HW值。
即:如果Follower的LEO大于Leader的HW,Follower HW值不会大于Leader的HW值。
Leader副本何时更新LEO
和Follower更新LEO相同,Leader写Log时自动更新自己的LEO值
Leader副本何时更新HW
Leader的HW值就是分区HW值,直接影响分区数据对消费者的可见性
Leader会【尝试】去更新分区HW的四种情况:
- Follower副本成为Leader副本时,Kafka会尝试去更新分区HW
- Broker奔溃导致副本被踢出ISR时,检查下分区HW值是否需要更新是有必要的
- 生产者向Leader副本写消息时,因为写入消息会更新Leader的LEO,有必要检查HW值是否需要更新
- Leader处理Follower fetch请求时,首先从Log读取数据,之后尝试更新分区HW值
当 Kafka Broker 都正常工作时,分区HW值的更新时机有两个:
- Leader处理produce请求时
- Leader处理fetch请求时
Leader如何更新自己的HW值呢?
Leader Broker保存了一套Follow副本的LEO以及自己的LEO。当尝试确定分区HW时,它会选出所有满足条件的副本,比较它们的LEO(包括Leader的LEO),并选择最小的LEO值作为HW值。
需要满足的条件如下(二选一):
- 处于ISR中
- 副本LEO落后于LeaderLEO的事件不大于replica.lag.time.max.ms参数值(默认10s)
如果Kafka只判断第一个条件的话,确定分区HW值时就不会考虑这些未在ISR中的副本,但这些副本已经具备了立刻进入ISR的资格,因此就可能出现分区HW值越过ISR中副本LEO的情况(不允许)。因为分区HW定义就是ISR中所有副本LEO的最小值。