Kafka的ISR简述
Kafka的ISR简述
[TOC]
如何保证生产的消息高可靠?
每个partition都给配上副本,做数据同步,保证数据不丢失。
副本数据同步策略
和zookeeper不同的是,Kafka选择的是全部完成同步,才发送ack。但是又有所区别。所以,你们才会在各种博客看到这句话【kafka不是完全同步,也不是完全异步,是一种ISR机制】,这句话对也不对,不对也对(谜语人……)
首先笔者认为:Kafka使用的就是完全同步方案。
完全同步的优点
同样为了容忍 n 台节点的故障,过半机制需要 2n+1 个副本,而全部同步方案只需要 n+1 个副本,
而 Kafka 的每个分区都有大量的数据,过半机制方案会造成大量数据的冗余。(这就是和zookeeper的不同)
完全同步会有什么问题?
假设就有这么一个follower延迟太高或者某种故障的情况出现,导致迟迟不能与leader进行同步。
怎么办?leader等还是不等?
等吧:producer有话要说:“Kafka也不行啊,处理个消息这么费劲,垃圾”
不等:那你Kafka对外说完全同步,你这是完全同步么?
基于此,Kafka的设计者和开发者想出了一个非常精明的点子:ISR
什么是ISR?
先来看几个概念
1、AR(Assigned Repllicas)一个partition的所有副本(就是replica,不区分leader或follower)
2、ISR(In-Sync Replicas)能够和 leader 保持同步的 follower + leader本身 组成的集合。
3、OSR(Out-Sync Relipcas)不能和 leader 保持同步的 follower 集合
4、公式:AR = ISR + OSR
1 |
|
基于此,上述完全同步会出现的问题就不是问题了。
因为ISR的机制就保证了,处于ISR内部的follower都是可以和leader进行同步的,一旦出现故障或延迟,就会被踢出ISR。
ISR 的核心就是:动态调整
总结:Kafka采用的就是一种完全同步的方案,而ISR是基于完全同步的一种优化机制。
follower的作用
读写都是由leader处理,follower只是作备份功能,不对外提供服务。
什么情况ISR中的replica会被踢出ISR?
以前有2个配置
1 |
|
说白了就是一个衡量leader和follower之间差距的标准。
一个是基于时间间隔,一个是基于消息条数。
0.9.0.0版本之后,移除了replica.lag.max.messages 配置。
为什么?
因为producer是可以批量发送消息的,很容易超过replica.lag.max.messages,那么被踢出ISR的follower就是受了无妄之灾。
他们都是没问题的,既没有出故障也没高延迟,凭什么被踢?
replica.lag.max.messages调大呢?调多大?太大了是否会有漏网之鱼,造成数据丢失风险?
这就是replica.lag.max.messages的设计缺陷。
replica.lag.time.max.ms的误区
【只要在 replica.lag.time.max.ms 时间内 follower 有同步消息,即认为该 follower 处于 ISR 中】
你去网上看博客,很多博客表达的就是这个意思,不过笔者认为这么描述很容易误导初学者。
那我是不是可以理解为,follower有个定时任务,只要在replica.lag.time.max.ms时间内去leader那pull数据就行了。
其实不是的。千万不要这么认为,因为这里还涉及一个速率问题(你理解为蓄水池一个放水一个注水的问题)。
如果leader副本的消息流入速度大于follower副本的拉取速度时,你follower就是实时同步有什么用?
典型的出工不出力,消息只会越差越多,这种follower肯定是要被踢出ISR的。
1 |
|
follower到底出了什么问题?
两个方面,一个是Kafka自身的问题,另一个是外部原因
1 |
|
1 |
|
什么情况OSR中的replica会重新加入ISR?
基于上述,replica重新追上了leader,就会回到ISR中。
相关的重要概念
需要先明确几个概念:
1、LEO(last end offset):
当前replica存的最大的offset的下一个值
2、HW(high watermark):
小于 HW 值的offset所对应的消息被认为是“已提交”或“已备份”的消息,才对消费者可见。
1 |
|
AR、ISR、OSR、HW、LEO
分区中的所有副本统称为AR(Assigned Replicas)。所有与leader副本保持一定程度同步的副本(包括leader副本在内)组成ISR(In-Sync Replicas),ISR集合是AR集合中的一个子集。消息会先发送到leader副本,然后follower副本才能从leader副本中拉取消息进行同步,同步期间内follower副本相对于leader副本而言会有一定程度的滞后。
与leader副本同步滞后过多的副本(不包括leader副本)组成**OSR**(Out-of-Sync Replicas),由此可见,AR=ISR+OSR。在正常情况下,所有的 follower 副本都应该与 leader 副本保持一定程度的同步,即 AR=ISR,OSR集合为空。
leader副本负责维护和跟踪ISR集合中所有follower副本的滞后状态,当follower副本落后太多或失效时,leader副本会把它从ISR集合中剔除。如果OSR集合中有follower副本“追上”了leader副本,那么leader副本会把它从OSR集合转移至ISR集合。默认情况下,当leader副本发生故障时,只有在ISR集合中的副本才有资格被选举为新的leader,而在OSR集合中的副本则没有任何机会(不过这个原则也可以通过修改相应的参数配置来改变)。
ISR与HW和LEO也有紧密的关系。HW是High Watermark的缩写,俗称高水位,它标识了一个特定的消息偏移量(offset),消费者只能拉取到这个offset之前的消息。
LEO是Log End Offset的缩写,它标识当前日志文件中下一条待写入消息的offset,分区ISR集合中的每个副本都会维护自身的LEO,而ISR集合中最小的LEO即为分区的HW,对消费者而言只能消费HW之前的消息。
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!