Kafka副本机制之副本leader的选举?ISR、LEO、HW的概念?

内容分享2小时前发布
0 0 0

一、副本机制

每个分区可以有多个副本,并且在副本集合中会存在一个leader 的副本,所有的读写请求都是由 leader 副本来进行处理。剩余的其他副本都作为 follower 副本,follower 副本会从 leader副本同步消息日志。

Kafka副本机制之副本leader的选举?ISR、LEO、HW的概念?

如何知道那个各个分区中对应的 leader 是谁呢?

在 zookeeper 服务器上,通过如下命令去获取对应分区的信息, 列如下面这个是获取 secondTopic 第 1 个分区的状态信息。

get /brokers/topics/secondTopic/partitions/1/state

➢ {“controller_epoch”:12,”leader“:0,”version”:1,”leader_epoch”:0,”isr”:[0,1]}

leader 表明当前分区的 leader 是那个 broker-id。

二、副本leader的选举

如果 leader 发生故障或挂掉,新的 leader 被选举并接受客户端的消息成功写入。Kafka 确保从同步副本列表中选举一个副本为 leader,leader负责维护和跟踪 ISR(in-Sync replicas ,副本同步队列)中,所有 follower的状态。

三、kafka 副本机制中的几个概念

leader 副本:响应 clients 端读写请求的副本

follower 副本:被动的备份 leader 副本中的数据,不能响应 clients 端读写请求。

ISR 副本:包含了 leader 副本和所有与 leader 副本保持同步的 follower 副本

前面两个不用讲解,这里讲ISR副本。

ISR 表明目前”可用且消息量与Leader 相差不多的副本集合,这是整个副本集合的一个子集”。具体来说,ISR 集合中的副本必须满足两个条件:

1. 副本所在节点必须维持着与 zookeeper 的连接

2. 副本最后一条消息的 offset 与 leader 副本的最后一条消息的offset之间的差值不能超过指定的阈值(replica.lag.time.max.ms) 如果该 follower 在此时间间隔内一直没有追上过 leader 的所有消息,则该 follower 就会被剔除isr列表。

如何判定是否与 leader 同步?

会提到每个 Kafka 副本对象都有两个重大的属性:LEO和HW。注意是所有的副本,而不只是 leader 副本。

关于 follower 副本同步的过程中,还有两个关键的概念:HW&LEO

LEO:即日志末端位移(log end offset),记录了该副本底层日志(log)中下一条消息的位移值。注意是下一条消息!也就是说,如果 LEO=10,那么表明该副本保存了 10 条消息,位移值范围是[0, 9]。另外,leader LEO 和 follower LEO 的更新是有区别的。

HW:即上面提到的水位值。对于同一个副本对象而言,其HW 值不会大于 LEO 值。小于等于 HW 值的所有消息都被认为是”已备份”的(replicated)。同理,leader 副本和follower 副本的 HW 更新是有区别的。

但是如果一个 follower 副本出现异常,列如宕机、网络断开等缘由长时间没有同步到消息,那这个时候,leader 就会把它踢出去。kafka 通过 ISR集合来维护一个分区副本信息。

这两个参数跟 ISR 集合紧密关联。HW 标记了一个特殊的 offset,当消费者处理消息的时候,只能拉去到 HW 之前的消息,HW之后的消息对消费者来说是不可见的。也就是说,取partition 对应 ISR 中最小的 LEO 作为 HW,consumer 最多只能消费到 HW 所在的位置。

每个 replica 都有 HW,leader 和 follower 各自维护更新自己的 HW 的状态。一条消息只有被 ISR 里的所有 Follower 都从 Leader 复制过去才会被认为已提交。这样就避免了部分数据被写进了Leader,还没来得及被任何 Follower 复制就宕机了,而造成数据丢失(Consumer 无法消费这些数据)。

而对于Producer 而言,它可以选择是否等待消息 commit,这可以通过 acks 来设置。这种机制确保了只要 ISR 有一个或以上的 Follower,一条被 commit 的消息就不会丢失。

初始状态:

初始状态下,leader 和 follower 的 HW 和 LEO 都是 0,leader 副本会保存remote LEO,所有 follower LEO也会被初始化为 0,这个时候,producer 没有发送消息。

follower 会不断地给 leader 发送fetch请求,但是由于没有数据,这个请求会被 leader 寄存,当在指定的时间之后会强制完成请求,这个时间配置是(replica.fetch.wait.max.ms),如果在指定时间内 producer 有消息发送过来,那么 kafka 会唤醒 fetch 请求,让 leader 继续处理。

Kafka副本机制之副本leader的选举?ISR、LEO、HW的概念?

这里会分两种情况,第一种是 leader 处理完 producer 请求之后,follower 发送一个 fetch 请求过来、第二种是follower 阻塞在 leader 指定时间之内,leader 副本收到producer 的请求。这两种情况下处理方式是不一样的。

1、先来看第一种情况:leader 处理完 producer 请求之后,follower 发送一个fetch 请求过来

leader 副本收到请求后来,会做几件事情

1. 把消息追加到 log 文件,同时更新 leader 副本的 LEO

2. 尝试更新 leader HW 值。这个时候由于 follower 副本还没有发送 fetch 请求,那么 leader 的 remote LEO 依旧是 0。leader 会比较自己的 LEO 以及 remote LEO 的值发现最小值是 0,与 HW 的值一样,所以不会更新HW。

Kafka副本机制之副本leader的选举?ISR、LEO、HW的概念?

follower 发送 fetch 请求,leader 副本的处理逻辑是:

1. 读取 log 数据、更新 remote LEO=0(follower 还没有写入这条消息,这个值是根据 follower 的 fetch 请求中的offset 来确定的)

2. 尝试更新 HW,由于这个时候 LEO 和 remote LEO 还是不一致,所以依旧是 HW=0

3. 把消息内容和当前分区的 HW 值发送给 follower 副本。

follower 副本收到 response 后来

1. 将消息写入到本地 log,同时更新 follower 的 LEO

2. 更新 follower HW,本地的 LEO 和 leader 返回的 HW 进行比较取小的值,所以依旧是 0 第一次交互结束后来,HW 依旧还是 0,这个值会在下一次follower 发起 fetch 请求时被更新

Kafka副本机制之副本leader的选举?ISR、LEO、HW的概念?

follower 发第二次 fetch 请求,leader 收到请求后来

1. 读取 log 数据

2. 更新 remote LEO=1, 由于这次 fetch 携带的 offset 是 1。

3. 更新当前分区的 HW,这个时候 leader LEO 和 remote LEO 都是 1,所以 HW 的值也更新为 1

4. 把数据和当前分区的 HW 值返回给 follower 副本,这个时候如果没有数据,则返回为空

follower 副本收到 response 后来

1. 如果有数据则写本地日志,并且更新 LEO

2. 更新 follower 的 HW 值到目前为止,数据的同步就完成了,意味着消费端能够消费 offset=0 这条消息。

Kafka副本机制之副本leader的选举?ISR、LEO、HW的概念?

2、第二种情况:follower 的 fetch 请求是直接从阻塞过程中触发

当 leader 收到请求后来会唤醒处于阻塞的fetch 请求。处理过程基本上和前面说的一至。

1. leader 将消息写入本地日志,更新 Leader 的 LEO

2. 唤醒 follower 的 fetch 请求

3. 更新 HW

© 版权声明

相关文章

暂无评论

none
暂无评论...