Kafka作为分布式系统,为了实现HA,采用多副本机制,并确保主副本(Leader)Crash时,备份副本(Follower)能接管服务,这就要求备Follower和Leader一直保持同步,避免Leader异常是Follower数据丢失。

相关概念

先来看下Kafka副本同步涉及的相关术语,便于后续描述和理解,部分基础术语请参考Kafka基本概念

ISR:in-sync replics,每个分区(Partition)中同步的副本列表。
Hight Watermark:副本水位值,表示分区中最新一条已提交(Committed)的消息的Offset。
LEO:Log End Offset,Leader中最新消息的Offset。
Committed Message:已提交消息,已经被所有ISR同步的消息。
Lagging Message:没有达到所有ISR同步的消息。

Kafka消息模型

在Kafka中,每个Partition都有一个预写日志(write-ahead log),Producer写入的消息就存储在这里,每条消息有一个唯一的偏移量offset。在上图中,offset为1-6的数据已经被所有ISR同步,可以给Producer返回发送成功消息,并提供给Consumer消费,而7-10为未完全同步消息,未向Producer返回写入成功消息,也不能提供给Consumer消费。

在Kafka中,每个Partition只有Leader能接收Producer的写入,并向Consumer提供消息消费服务,Follower只复制按顺序同步Leader的消息,而且只有ISR中所有节点都同步成功的消息才算写入成功,所以消息写入延迟受最慢同步副本的限制。在日志复制协议(Log Replication Algorithm)设计上需要需要快速检测慢副本并把其从ISR中剔除。

同步检测

在0.8.2版本前,Kafka通过replica.lag.max.messagesreplica.lag.time.max.ms两个参数来度量Follower同步的情况。其中replica.lag.max.messages用于配置Follower可落后的最大消息数量,replica.lag.time.max.ms用于配置Follower和Leader通信的最大时延。由于replica.lag.max.messages是全局配置,需要根据经验配置,配置的不好会导致节点不断的加入和移出ISR(原因请自行百度),后续版本已经删除此参数,是保留replica.lag.time.max.ms一个参数。

Follower和Leader消息不同步,主要有三种情况:

  1. 慢副本:在一定周期内Follower不能赶上Leader。比如在一段时间内,由于Follower磁盘IO或网络IO的问题,导致数据写入速度慢。
  2. 卡住副本:Follower在一段时间内未向Leader获取同步数据(Fetch)的请求。比如由于GC导致进程卡住。
  3. 新启动副本:由于副本因子(offsets.topic.replication.factor)变化导致新增备份副本,此副本不在ISR列表,直到同步的消息赶上Leader。

replica.lag.time.max.ms参数主要用于检测上述1和2两种情况,如果Follower Fetch数据的时间超过该值,认为节点是卡住,被踢出ISR;当Follower连续出现多次出现同步延迟超过此阈值时,就会被认为是慢副本,被踢出ISR。


乘着风
107 声望12 粉丝

五岁时,妈妈告诉我,人生的关键在于快乐。上学后,人们问我长大了要做什么,我写下“快乐”。他们告诉我,我理解错了题目,我告诉他们,他们理解错了人生。——约翰·列侬