引言

大多数分布式系统采用多副本的机制,以此来实现水平扩展、提供容灾能力、提供可用性和可靠性等。

  • 副本是相对分区而言的,即副本是特定分区的副本;
  • 一个分区中包含一个或多个副本,其中一个为leader副本,其余都会follower副本,各个副本位于不同broke节点中,只有leader副本对外提供服务,follower副本只负责数据同步;
  • 分区中的所有副本统称AR,而ISR指与leader副本保持同步状态的副本集合;
  • LEO标识每个分区中最后一条消息的下一个位置,分区副本都有自己的LEO,ISR中最小的LEO即HW,消息者只能取到HW之前的消息。

 从生产者发出的一条消息首先会被写入分区的leader副本,不过等ISR集合中的所有follow副本都同步完之后才能被认为是已经提交,之后才会更新分区的HW,进而消息者可以消费这条消息。

1.1 失效副本

 通过kafka-topics.sh脚本的under-replicated-partitions参数来显示主题中失效副本的分区。

怎么判断一个副本是否处于同步失效的状态呢?

ISR集合中一个follower副本滞后leader副本的时间超过参数设定值,replica.lag.time.max.ms参数,默认值为10000。

 

副本集部署架构图 副本是什么意思?_元数据

1.2 ISR的伸缩

kafka在启动时会开启两个与ISR相关的定时任务,分别是"isr-expiration"和"isr-change-propagation".

isr-expiration任务会周期性地检测每个分区是否需要缩减其ISR集合,这个周期与replica.lag.time.max.ms参数有关,大小是期的一半为5000ms。

当检测到有失效副本时,就会收缩ISR集合,如有发生变更,则将记录到ZooKeeper对应的/brokers/topics/<topic>/partition/<partition>/state节点中。

节点数据示例如下:

{"controller_epoch":26, "leader":0,"version":1,"leader_epoch":2,"isr":[0:1]}

"isr"表示变更的ISR列表

当ISR集合发生变更(缩减)时,还会将变更后的记录记录缓存到isrChangeSet中,isr-change-propagation任务会周期性(2500ms)检查isrChangSet, 如isrchangeSet发生有变更,则会在Zookpeeper的/isr_change_notification路径下创建一个以isr_change开头的持久顺序节点,并将isrchangeset中的信息保存到这个节点中。Kafka控制器为/isr_change_notification添加一个Watcher,当这个节点有子节点发生变化时会角发Watcher的动作,以通知控制器更新相关元数据的信息并向它管理的broker节点发送更新元数据的请求,最后删除/isr_change_notification路径下已经处理过的节点。频繁触发Watch会影响整个节点的性能。检查加了二个条件:

  • 上一次ISR集合发生的时候距离现在已经超过5秒;
  • 上一次写入zookeeper的时间距离现在超过60秒;

1.3 LEO与HW

对于副本而言,有两个概念:本地副本和远程副本;

副本集部署架构图 副本是什么意思?_元数据_02

1.4 leader Epoch的介入

上述是leader副本与follow副本之间的切换,如果leader副本发生切换呢?