IT小栈

  • 主页
  • Java基础
  • RocketMQ
  • Kafka
  • Redis
  • Shiro
  • Spring
  • Spring Boot
  • Spring Cloud
  • 资料链接
  • 关于
所有文章 友链

IT小栈

  • 主页
  • Java基础
  • RocketMQ
  • Kafka
  • Redis
  • Shiro
  • Spring
  • Spring Boot
  • Spring Cloud
  • 资料链接
  • 关于

Kafka HW与Leader Epoch

2020-03-21

上一节我们在副本机制中讲解了关于副本的基本概念及多副本存在的意义,引出了ISR出现的原因,本节我们继续围绕副本深入探讨。

1、HW高水平

1.1、相关的概念:

AR: 分区中的所有副本统称为AR

ISR: 与Leader副本保持一定同步状态的副本集合,当然Leader也是ISR中的成员

LEO: 标识每个分区中最后一条消息的下一个位置,分区的每一个副本都有自己的LEO

HW: ISR中最小的LEO即为HW,俗称高水位,消费者只能拉取HW之前的消息

通过图中我们直观的分析HW和LEO的概念。图中展示的是一个分区下的三个副本,我们认为三个副本都在ISR中,1个Leader副本和2个Follower副本,Leader副本的LEO是8,Follower1副本的LEO是7,Follower2副本的LEO是6,那么这个分区的HW是6;如果Follower2副本被判定为失效副本从ISR集合中移除,那么此时分区的HW为Leader和Follower1副本的LEO最小值,即为7。

1.2、高水位的作用

1、定义消息可见性,即用来标识分区下的哪些消息是可以被消费者消费的。

2、帮助 Kafka 完成副本同步。

位移值等于高水位的消息也属于未提交消息。也就是说,高水位上的消息是不能被消费者消费的

同一个副本对象,其高水位值不会大于 LEO 值

高水位和 LEO 是副本对象的两个重要属性。Kafka 所有副本都有对应的高水位和 LEO 值,而不仅仅是 Leader 副本。只不过 Leader 副本比较特殊,Kafka 使用 Leader 副本的高水位来定义所在分区的高水位。换句话说,分区的高水位就是其 Leader 副本的高水位。

1.3、高水位更新机制

我们先梳理一下消息的追加到副本的过程。我们已某个主题的分区数是3,副本因子是3的进行分析

1、生产者客户端发送消息至Leader副本(Broker0上的副本1、Broker1上的副本2、Broker2上的副本3)

2、消息被追加到Leader副本的本地日志,并更新日志的偏移量LEO

3、Follower副本向Leader副本请求同步数据,会携带当前副本的LEO(如Broker1上的副本1和Broker2上的副本1向Broker0上的副本1请求数据)

4、Leader副本所在的服务器读取本地日志,并更新对应的Follower副本的信息(Leader副本会记录每个Follower副本的LEO信息,更新的LEO 是Follower请求时带过来的自身的LEO,不是计算拉取后的因为还没持久化,不知道消息是否成功入到Follower中)

5、Leader副本将拉取的结果返回给follower副本

6、Follower副本获取从Leader副本获取的消息,将消息追加到本地日志中并更新日志的偏移量信息LEO

了解了以上过程我们来动态的说明LEO和HW更新的过程

图中展示了副本Follower拉取Leader消息时这个LEO和HW动态更新的过程

Follower每次请求时会携带自身的LEO,Leader会记录每个Follower的LEO;计算HW=min(Leader的LEO,Follower1的LEO,Follower2的LEO)。

Leader返回给Follower消息时会携带HW值,Follower获取到HW时会更新自身的HW=min(Leader的HW,自身的LEO)

在一个分区中Leader副本所在的节点会记录所有副本的LEO,Follower只会记录自身的LEO

各个副本所在的节点都会记录自己的HW

2、Leader Epoch引入

以上我们的分析都是说明正常情况下的Leader副本与Follower副本之间的同步过程,如果Leader副本发生切换,那么同步又该如何处理0.11 版本之前都是依据HW的同步机制,但是这样很容易造成数据丢失,或者因为Leader副本和Follower副本不一致的问题。社区在 0.11 版本正式引入了 Leader Epoch 概念,来规避因高水位更新错配导致的各种不一致问题。

2.1、分析数据丢失场景

分为四个阶端,灰色背景的为Leader

第一阶段:A是Leader,此时A的HW是2,B的HW是1,此时B携带自身的额LEO拉取A中的消息,此时B重启,B还没有从A中拉取消息更新自身的HW时发生了重启。

第二阶端:B重启后发现LEO和本身的HW不一致,则根据HW(这个值会存入本地的replication-offset-checkpoint)进行日志截断,这时会将M2的消息进行删除。此时的B中只有M1这条消息。从A中拉取消息

第三阶端:B从A中拉取消息时,此时A宕机,说明Leader挂了,选举出B为新的Leader,HW就是1。

第四阶端:A主机恢复,此时的A则是一个Follower副本,此时的HW是2,由于副本的HW不能比Leader的高,还会做一次日志截断,此时的HW调整为1。那么M2的消息就会丢失,即使A没有恢复正常同样M2消息还是丢失了。

2.2、分析数据不一致场景

分为四个阶端,灰色背景的为Leader

第一阶段:A节点的HW和LEO都是2,B的HW是1,LEO是2此时正要去Leader拉取数据,A/B两个节点都都宕机

第二阶端:B恢复后发现LEO和本身的HW不一致,则根据HW(这个值会存入本地的replication-offset-checkpoint)进行日志截断,这时会将M2的消息进行删除。此时的B中只有M1这条消息

第三阶端:此时B是Leader追加消息M2同步更新HW和LEO都是2

第四阶端:此时A恢复后自动成为Follower,此时的HW是2,从B(Leader)拉取消息时返回给A的HW同样是2,这样A不用做任何操作,此时我们发现A中有M1、M2然而B中却是M1和M3。

2.3、Leader Epoch

为了解决以上问题kafka从0.11.0.0开始引入Leader Epoch的概念,在需要截断数据的时候使用Leader Epoch作为参照而不是原来的HW。Leader Epoch代表Leader的纪元信息初始值为0。每当Leader变更一次Leader Epoch就会增加1,相当于为Leader增加一个版本号。于此同时每个副本中还是增设一个矢量<LeaderEpoch => StartOffset>,其中StartOffset表示当前的LeaderEpoch下写入第一条消息的偏移量。每个副本的Log下都有一个leader-epoch-checkpoint文件,在发生Leader Epoch 变更时,会将相应的矢量值追加到这个文件中。

下面通过动态过程分析引入Leader Epoch如何保证消息不丢失。

分为四个阶端

第一阶段:A是Leader,此时A的HW是2,B的HW是1,此时B携带自身的额LEO拉取A中的消息,此时B重启,B还没有从A中拉取消息更新自身的HW时发生了重启。

第二阶段:Follower 副本 B 重启回来后,需要向 A 发送一个特殊的请求去获取 Leader 的 LEO 值。在这个例子中,该值为 2。当获知到 Leader LEO=2 后,B 发现该 LEO 值不比它自己的 LEO 值小,而且缓存中也没有保存任何起始位移值 > 2 的 Epoch 条目,因此 B 无需执行任何日志截断操作。这是对高水位机制的一个明显改进,即副本是否执行日志截断不再依赖于高水位进行判断。

第三阶段:副本 A 宕机了,B 成为 Leader。此时B的LEO为2,HW为2。

第四阶段:当 A 重启回来后,执行与 B 相同的逻辑判断,发现也不用执行日志截断,至此位移值为 1 的那条消息M2在两个副本中均得到保留。后面当生产者程序向 B 写入新消息时,副本 B 所在的 Broker 缓存中,会生成新的 Leader Epoch 条目:[Epoch=1, Offset=2]。之后,副本 B 会使用这个条目帮助判断后续是否执行日志截断操作。这样,通过 Leader Epoch 机制,Kafka 完美地规避了这种数据丢失场景。

本文作者: 顾 明 训
本文链接: https://www.itzones.cn/2020/03/21/Kafka-HW与Leader-Epoch/
版权声明: 本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。转载请注明出处!
  • kafka HW
  • kafka Leader Epoch
  • kafka

扫一扫,分享到微信

微信分享二维码
Kafka消费者组重平衡
Kafka副本机制
  1. 1. 1、HW高水平
    1. 1.1. 1.1、相关的概念:
    2. 1.2. 1.2、高水位的作用
    3. 1.3. 1.3、高水位更新机制
  2. 2. 2、Leader Epoch引入
    1. 2.1. 2.1、分析数据丢失场景
    2. 2.2. 2.2、分析数据不一致场景
    3. 2.3. 2.3、Leader Epoch
© 2020 IT小栈
载入天数...载入时分秒... || 本站总访问量次 || 本站访客数人次
Hexo Theme Yilia by Litten
  • 所有文章
  • 友链

tag:

  • jvm
  • Java基础
  • kafka HW
  • kafka Leader Epoch
  • kafka
  • kafka位移主题
  • kafka位移提交
  • kafka副本机制
  • kafka ISR
  • zookeeper
  • kafka消息丢失
  • kafka日志存储
  • kafka Log Clean
  • kafka Log Compaction
  • kafka消费位移设置
  • kafka Rebalance
  • kafka分区算法
  • kafka生产者拦截器
  • kafka SASL/SCRAM
  • kafka ACL
  • redis
  • redis Ziplist
  • redis Hashtable
  • redis LinkedList
  • redis QuickList
  • redis intset
  • redis String
  • redis SDS
  • redis SkipList
  • redisDb
  • redisServer
  • redis 简介
  • Redis Cluster
  • 主从同步
  • RocketMQ高可用HA
  • 事务消息
  • 内存映射
  • MMAP
  • 同步刷盘
  • 异步刷盘
  • 消息存储文件
  • RocketMQ安装
  • 延迟消息
  • RocketMQ入门
  • 推拉模式
  • PushConsumer
  • 消费结果处理
  • rebalance
  • RocketMQ权限控制
  • RocketMQ ACL
  • 消息过滤
  • 消息重试
  • 消费位置
  • 集群消费
  • 广播消费
  • 运维命令
  • shiro源码分析
  • shiro入门
  • IOC和DI
  • Spring创建Bean
  • Bean生命周期
  • Sping属性注入
  • 异常
  • SpringMVC
  • springCloud
  • Eureka

    缺失模块。
    1、请确保node版本大于6.2
    2、在博客根目录(注意不是yilia根目录)执行以下命令:
    npm i hexo-generator-json-content --save

    3、在根目录_config.yml里添加配置:

      jsonContent:
        meta: false
        pages: false
        posts:
          title: true
          date: true
          path: true
          text: false
          raw: false
          content: false
          slug: false
          updated: false
          comments: false
          link: false
          permalink: false
          excerpt: false
          categories: false
          tags: true
    

  • 我的OSCHINA
  • 我的CSDN
  • 我的GITHUB
  • 一生太水