1. 首页
  2. 大数据
  3. Kafka教程

剖析Kafka副本机制,你真的了解ISR吗?

温故:我们在【死磕kafka】(一) 入门必知必会的术语概念就了解到:

Topic、Partition、Replica是主题层三要素,每个Topic都有至少一个Partition,而Partition有副本机制,Kafka 定义了两类副本:领导者副本和追随者副本。只能有 1 个领导者副本和 N-1 个追随者副本。

这些都是你死记硬背出来的,因此你会有很多的疑问:

  • 为什么kafka要有副本机制?
  • 为什么要有领导者副本和追随者副本两种角色?
  • 领导者副本和追随者副本之间的关系是什么?
  • 当领导者副本挂了的时候,追随者副本会有怎样的操作?

今天我们就让它从概念变成你的玩物

副本优势

我们先不具体说kafka,而是广度的聊聊副本在分布式系统中,有什么优势?

首先你会毫不犹豫的说出:高可用性。这太容易理解了,就好像我们平时会把重要文件备份成两份放U盘一样。这样电脑万一被黑客入侵了,也不怕不怕啦。

分布式系统也是这么做的,通过提供数据冗余,即使系统部分组件失效,系统依然能够继续运转,增加了整体可用性以及数据持久性。

就这一个优势吗?显然不是的,你可能会联想到mysql的从库,mysql的从库可以帮助mysql抗压(抗读),一切写的操作都在主库进行,而读的操作则分摊到从库进行,这样一来的可以大大提高读取的效率。

没错,分布式系统副本机制也提供了高伸缩性,能够通过增加机器的方式来提升读性能,进而提高读操作吞吐量。

但是,很遗憾,kafka没有这个优势,因为kafka的副本是不对外提供服务的。。

我们等会再来聊聊为啥它要这么小气,有数据还不给别人用呢!

反正现在你只需要记住,kafka的副本机制只有一个好处:就是通过数据冗余保证高可用性。

副本定义

你已经知道,partition的数据会有多个副本。那么这个副本,到底是个啥呢?其实不神秘,它就是一个只能追加写消息的提交日志。同一个分区下的所有副本保存有相同的消息序列,这些副本分散保存在不同的 Broker 上,从而能够对抗部分 Broker 宕机带来的数据不可用。

如图所示:TopicA有三个分区,part0、part1、part2。其中part0有两个副本,一个领导者副本和一个跟随者副本。分别在broker1和broker2上。

剖析Kafka副本机制,你真的了解ISR吗?

副本角色

为什么Kafka要定义两类副本:领导者副本(Leader Replica)和追随者副本(Follower Replica)。并且只能有 1 个领导者副本和 N-1 个追随者副本呢?

要回答这个问题,先思考下,既然分区下能够配置多个副本,而且这些副本的内容还要一致,那么我们该如何确保副本中所有的数据都是一致的呢?

首先,我们得有个基准吧,以谁的数据为准呢?不然公说公有理,婆说婆有理可不好了。所以,kafka才有了领导者的角色。

好了,我们以领导者的数据为准,即基于领导者(Leader-based)的副本机制,那么领导者负责与生产者交互,而追随者就拉取它的数据就好了,这样就很清晰了吧?如下图所示:

剖析Kafka副本机制,你真的了解ISR吗?

关于这张图,你重点理解下以下内容:

1、副本分成两类:领导者副本(Leader Replica)和追随者副本(Follower Replica)。每个分区在创建时都要选举一个副本,称为领导者副本,其余的副本自动称为追随者副本。

2、在 Kafka 中,追随者副本是不对外提供服务的。任何一个追随者副本都不能响应消费者和生产者的读写请求。所有的请求都必须由领导者副本来处理,或者说,所有的读写请求都必须发往领导者副本所在的 Broker,由该 Broker 负责处理。追随者副本不处理客户端请求,它唯一的任务就是从领导者副本异步拉取消息,并写入到自己的提交日志中,从而实现与领导者副本的同步。

3、当领导者副本挂掉了,Kafka 依托于 ZooKeeper 提供的监控功能能够实时感知到,并立即开启新一轮的领导者选举,从追随者副本中选一个作为新的领导者。老 Leader 副本重启回来后,只能作为追随者副本加入到集群中。

注意标红的字眼,追随者副本是不对外提供服务的。还记得刚刚我们谈到副本机制的好处时,说过 Kafka 没能提供读操作横向扩展吗?具体的原因就在于此。总而言之,kafka的追随者副本除了保证高可用,没其他好处了。对于客户端用户而言,它就是一文不值。

既然如此,Kafka 为什么要这样设计呢?其实这种副本机制有两个方面的好处。

1.方便实现“Read-your-writes”。

所谓 Read-your-writes,顾名思义就是,当你使用生产者 API 向 Kafka 成功写入消息后,马上使用消费者 API 去读取刚才生产的消息。

举个例子,比如你平时发微博时,你发完一条微博,肯定是希望能立即看到的,这就是典型的 Read-your-writes 场景。如果允许追随者副本对外提供服务,由于副本同步是异步的,因此有可能出现追随者副本还没有从领导者副本那里拉取到最新的消息,从而使得客户端看不到最新写入的消息。

2.方便实现单调读(Monotonic Reads)。

什么是单调读呢?就是对于一个消费者用户而言,在多次消费消息时,它不会看到某条消息一会儿存在一会儿不存在。

如果允许追随者副本提供读服务,那么假设当前有 2 个追随者副本 F1 和 F2,它们异步地拉取领导者副本数据。倘若 F1 拉取了 Leader 的最新消息而 F2 还未及时拉取,那么,此时如果有一个消费者先从 F1 读取消息之后又从 F2 拉取消息,它可能会看到这样的现象:第一次消费时看到的最新消息在第二次消费时不见了,这就不是单调读一致性。但是,如果所有的读请求都是由 Leader 来处理,那么 Kafka 就很容易实现单调读一致性。

Leader挂了怎么办?

刚刚我们反复强调,只有Leader副本才可提供服务。消费者和生产者的读写请求都是由Leader副本来完成的。

那么Leader挂了怎么办?不假思索就可以回答出:老大挂了老二上。可是老二要怎么上位?尤其在有很多Follow副本的时候,kafka应该如何选择?

也不难回答出,肯定是选择优质的备胎。

不是说所有副本都保存一样的消息吗?还怎么区分优质啊?

所有副本都一样,那只是在正常情况下。既然追随者只是定期地异步拉取领导者副本中的数据,异步的,就存在着不可能与 Leader 实时同步的风险。

默认情况下(注意只是默认),只有被认定为是实时同步的Follower副本,才可能被选举成Leader。

一个副本与 leader 失去实时同步的原因有很多,比如:

  • 慢副本(Slow replica):follower replica 在一段时间内一直无法赶上 leader 的写进度。造成这种情况的最常见原因之一是 follower replica 上的 I/O瓶颈,导致它持久化日志的时间比它从 leader 消费消息的时间要长;
  • 卡住副本(Stuck replica):follower replica 在很长一段时间内停止从 leader 获取消息。这可能是以为 GC 停顿,或者副本出现故障;

刚启动副本(Bootstrapping replica):当用户给某个主题增加副本因子时,新的 follower replicas 是不同步的,直到它跟上 leader 的日志。

如果你是个细心的人,抠一下刚刚那几段话的字眼,

“在一段时间内一直无法赶上 leader 的写进度”

你会产生这样的疑问:一段时间到底是指多久呢?

比如我们知道小学生优秀的标准是80分,那么Follow副本,你要确认它是否优质,也得给个标准吧?

这个标准就是 Broker 端参数 replica.lag.time.max.ms 参数值。这个参数的含义是 Follower 副本能够落后 Leader 副本的最长时间间隔,当前默认值是 10 秒。这就是说,只要一个 Follower 副本落后 Leader 副本的时间不连续超过 10 秒,那么 Kafka 就认为该 Follower 副本与 Leader 是同步的。反之,当副本落后于 leader 分区时,这个副本被认为是不同步或滞后的。

说到这里,可以引出kafka中大名鼎鼎的一个名词,叫做ISR

In-sync Replicas(ISR)

ISR 中的副本都是与 Leader 同步的副本,相反,不在 ISR 中的追随者副本就被认为是与 Leader 不同步的。

不过首先要明确的是,Leader 副本天然就在 ISR 中。也就是说,ISR 不只是追随者副本集合,它必然包括 Leader 副本。甚至在某些情况下,ISR 只有 Leader 这一个副本。

至于怎么认定Follower是否同步,刚刚已经说过了,Broker 端参数 replica.lag.time.max.ms 参数值。

如果这个同步过程的速度持续慢于 Leader 副本的消息写入速度,那么在 replica.lag.time.max.ms 时间后,此 Follower 副本就会被认为是与 Leader 副本不同步的,因此不能再放入 ISR 中。此时,Kafka 会自动收缩 ISR 集合,将该副本“踢出”ISR。

值得注意的是,倘若该副本后面慢慢地追上了 Leader 的进度,那么它是能够重新被加回 ISR 的。这也表明,ISR 是一个动态调整的集合,而非静态不变的。

Unclean Leader Election

unclean领导者选举。再回去看看刚刚我们说Leader挂了怎么办,有句话重点标粗,”默认情况下(注意只是默认),只有被认定为是实时同步的Follower副本,才可能被选举成Leader”。

这是由Broker 端参数 unclean.leader.election.enable 控制的。默认为false,即只有被认定为是实时同步的Follower副本(在ISR中的),才可能被选举成Leader。如果你设置为true,则所有副本都可以被选举。

开启 Unclean 领导者选举可能会造成数据丢失,但好处是,它使得分区 Leader 副本一直存在,不至于停止对外提供服务,因此提升了高可用性。反之,禁止 Unclean 领导者选举的好处在于维护了数据的一致性,避免了消息丢失,但牺牲了高可用性。

如果你听说过 CAP 理论的话,你一定知道,一个分布式系统通常只能同时满足一致性(Consistency)、可用性(Availability)、分区容错性(Partition tolerance)中的两个。显然,在这个问题上,Kafka 赋予你选择 C 或 A 的权利。

你可以根据你的实际业务场景决定是否开启 Unclean 领导者选举。不过,我强烈建议你不要开启它,毕竟我们还可以通过其他的方式来提升高可用性。如果为了这点儿高可用性的改善,牺牲了数据一致性,那就非常不值当了。

总结

剖析Kafka副本机制,你真的了解ISR吗?

1、kafka副本只有一个好处:保证高可用性。

2、副本其实就是只能追加写消息的提交日志,kafka中副本分为领导者副本和追随者副本。每个partition都只能有一个领导者副本和N-1追随者副本。

3、仅领导者副本对外提供服务,追随者副本唯一做的事情就是异步同步领导者副本的消息。

4、ISR是与Leader副本以及与Leader同步的Follower副本的集合,如何判断是否同步,是依据broker端参数replica.lag.time.max.ms

5、你可以自行选择unclean领导者选举,如果要保证高可用性,则设为true,允许不同步的Follower被选举,如果要保证一致性,则设为False。

BDStar原创文章。发布者:Liuyanling,转载请注明出处:http://bigdata-star.com/archives/2411

发表评论

登录后才能评论

联系我们

562373081

在线咨询:点击这里给我发消息

邮件:562373081@qq.com

工作时间:周一至周五,9:30-18:30,节假日休息

QR code