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中,每个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.messages
和replica.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消息不同步,主要有三种情况:
- 慢副本:在一定周期内Follower不能赶上Leader。比如在一段时间内,由于Follower磁盘IO或网络IO的问题,导致数据写入速度慢。
- 卡住副本:Follower在一段时间内未向Leader获取同步数据(Fetch)的请求。比如由于GC导致进程卡住。
- 新启动副本:由于副本因子(
offsets.topic.replication.factor
)变化导致新增备份副本,此副本不在ISR列表,直到同步的消息赶上Leader。
replica.lag.time.max.ms
参数主要用于检测上述1和2两种情况,如果Follower Fetch数据的时间超过该值,认为节点是卡住,被踢出ISR;当Follower连续出现多次出现同步延迟超过此阈值时,就会被认为是慢副本,被踢出ISR。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。