Kafka 关键概念,什么是AR、OSR、ISR、HW和LEO以及之间的关系

秦晓辉@快猫星云 2022年11月29日

Kafka 多副本

Kafka 为分区引入了多副本(Replica)机制,通过增加副本数量可以提升容灾能力。同一分区的不同副本中保存的是相同的消息(当然在同一时刻,副本之间可能并非完全一样),副本之间是“一主多从”的关系,其中leader副本负责处理读写请求,follower副本只负责与leader副本的消息同步,很多时候follower副本中的消息相对leader副本而言会有一定的滞后。副本处于不同的broker中,当leader副本出现故障时,从follower副本中重新选举新的leader副本对外提供服务。Kafka通过多副本机制实现了故障的自动转移,当Kafka集群中某个broker失效时仍然能保证服务可用。

Kafka 消费端也具备一定的容灾能力。Consumer 使用拉(Pull)模式从服务端拉取消息,并且保存消费的具体位置,当消费者宕机后恢复上线时可以根据之前保存的消费位置重新拉取需要的消息进行消费,这样就不会造成消息丢失。

AR、ISR、OSR

  • 分区中的所有副本统称为AR(Assigned Replicas)。
  • 所有与leader副本保持一定程度同步的副本(包括leader副本在内)组成ISR(In-Sync Replicas),ISR集合是AR集合中的一个子集。
  • 与leader副本同步滞后过多的副本(不包括leader副本)组成OSR(Out-of-Sync Replicas)

消息会先发送到leader副本,然后follower副本才能从leader副本中拉取消息进行同步,同步期间内follower副本相对于leader副本而言会有一定程度的滞后。前面所说的“一定程度的同步”是指可忍受的滞后范围,这个范围可以通过参数进行配置。由此可见,AR=ISR+OSR。在正常情况下,所有的 follower 副本都应该与 leader 副本保持一定程度的同步,即 AR=ISR,OSR集合为空。

ISR 与 OSR 转换、ISR 集合中的副本才允许选举为leader

leader副本负责维护和跟踪ISR集合中所有follower副本的滞后状态,当follower副本落后太多或失效时,leader副本会把它从ISR集合中剔除。如果OSR集合中有follower副本“追上”了leader副本,那么leader副本会把它从OSR集合转移至ISR集合。默认情况下,当leader副本发生故障时,只有在ISR集合中的副本才有资格被选举为新的leader,而在OSR集合中的副本则没有任何机会(不过这个原则也可以通过修改相应的参数配置来改变)。

什么是 HW 和 LEO

HW是High Watermark的缩写,俗称高水位,它标识了一个特定的消息偏移量(offset),消费者只能拉取到这个offset之前的消息。

Kafka Log

如图所示,它代表一个日志文件,这个日志文件中有 9 条消息,第一条消息的 offset(LogStartOffset)为 0,最后一条消息的 offset 为 8,offset 为 9 的消息用虚线框表示,代表下一条待写入的消息。日志文件的HW为6,表示消费者只能拉取到offset在0至5之间的消息,而offset为6的消息对消费者而言是不可见的。为啥 offset 6、7、8 已经有消息了却无法被读取呢?可能是因为副本之间还没有完成同步,下文会介绍。

LEO是Log End Offset的缩写,它标识当前日志文件中下一条待写入消息的offset,图中offset为9的位置即为当前日志文件的LEO,LEO的大小相当于当前日志分区中最后一条消息的offset值加1。分区ISR集合中的每个副本都会维护自身的LEO,而ISR集合中最小的LEO即为分区的HW,对消费者而言只能消费HW之前的消息。

为了更好的理解 HW 和 LEO 的关系,下面通过一个简单的示例来进行相关的说明。如图所示,假设某个分区的ISR集合中有3个副本,即一个leader副本和2个follower副本,分区的每个副本都维护了自己的LEO,且都是3,最小的LEO就是HW,所以这个例子中HW也是3。

Kafka Log

此时,生产者又生产了两条新消息,生产者的写入操作只和leader交互,所以新的这两条消息,会先写入leader副本,leader副本的LEO就会变成5,但是消息还没有被follower同步,两个follower的LEO仍然是3,HW就是最小的LEO,所以此时HW仍然是3,消费者是看不到刚刚写入的两条消息的。

Kafka Log

过了一段时间之后,follower01已经追上了leader,follower02还没有追上,此时消息的情况可能如下图。leader和follower01的LEO都是5了,follower02的LEO还是4,HW是取LEO中最小的值,也就是4。

Kafka Log

再然后,follower02也追上了leader的进度,follower02的LEO也变成5了,HW取最小的LEO,LEO都是5,所以HW也是5,此时消费者可以消费offset为0-4这5条消息。如下图所示:

Kafka Log

如上,应该就解释清楚了这些基本概念。

关于作者

本文作者秦晓辉,Flashcat合伙人,文章内容是Flashcat技术团队共同沉淀的结晶,作者做了编辑整理,我们会持续输出监控、稳定性保障相关的技术文章,文章可转载,转载请注明出处,尊重技术人员的成果。

如果对 Nightingale、Categraf、Prometheus 等技术感兴趣,欢迎加入我们的微信群组,联系我(picobyte)拉入部落,和社区同仁一起探讨监控技术。

标签: Kafka