一个副本就是一个备份日志,多个副本提供冗余保持系统高可用性,多个副本均匀分布在所有broker上,从这些副本中选一个leader出来对外提供服务,其他的副本叫做follower,被动的向leader请求数据,保持同步,如果leader没问题,就用不到follower,如果leader崩溃了,就从follower中选举一个新的leader出来,竞选leader也是需要资格的,如果follower与leader的进度差距比较大,那就不能参加竞选,哪些follower可以竞选?这就引出了ISR概念。
ISR是一组follower,是一组同步副本集合。每个分区都有自己的一个ISR列表,ISR中的副本都与leader保持同步。leader就在ISR中。producer写入一条消息时,只有被ISR成员都接收到,才是为写入成功。
重要概念
- 起始位置(base offset):该副本第一条消息的 offset。
- 高水印值(HW,high watermark):高位水印,指该副本最新一条已提交消息的 offset。超过 HW 的消息都是“未完全备份的”,consumer 是看不到的。
- 末端位置(LEO,log end offset):结束位移,就是副本日志中下一条代写入消息的 offset。
同步流程说明
假设一个 topic,只要一个分区,有3个副本(1个leader, 2个follower),ISR中也是这3个副本,目前 topic 是空的,3个副本的 LEO 和 HW 的值都是 0。
现在 producer 向 leader 副本发送了一条消息,下面看一下消息的整个同步流程:
(1)leader 接收到消息,把自己的 LEO 值更新为 1。
(2)2个 follower 各自发请求给 leader。
(3)leader 把消息推送给 follower。
(4)follower 接收到消息后,更新自己的 LEO 为 1。
(5)leader 接收到 follower 的响应之后,HW 值更新为 1,此时 offset 为 0 的这条消息可以被 consumer 消费了。
对于设置了 acks=-1
的 producer,只有这5步都完成了,producer 才能正常返回,标志着这条消息发送成功。