23 | Kafka副本机制详解
23 | Kafka副本机制详解
讲述:胡夕
时长12:08大小11.11M
副本定义
副本角色
In-sync Replicas(ISR)
Unclean 领导者选举(Unclean Leader Election)
小结
开放讨论
赞 26
提建议
精选留言(87)
- 你好旅行者2019-07-27老师讲的很好,我做一些补充吧。 Kafka在启动的时候会开启两个任务,一个任务用来定期地检查是否需要缩减或者扩大ISR集合,这个周期是replica.lag.time.max.ms的一半,默认5000ms。当检测到ISR集合中有失效副本时,就会收缩ISR集合,当检查到有Follower的HighWatermark追赶上Leader时,就会扩充ISR。 除此之外,当ISR集合发生变更的时候还会将变更后的记录缓存到isrChangeSet中,另外一个任务会周期性地检查这个Set,如果发现这个Set中有ISR集合的变更记录,那么它会在zk中持久化一个节点。然后因为Controllr在这个节点的路径上注册了一个Watcher,所以它就能够感知到ISR的变化,并向它所管理的broker发送更新元数据的请求。最后删除该路径下已经处理过的节点。 此外,在0.9X版本之前,Kafka中还有另外一个参数replica.lag.max.messages,它也是用来判定失效副本的,当一个副本滞后leader副本的消息数超过这个参数的大小时,则判定它处于同步失效的状态。它与replica.lag.time.max.ms参数判定出的失效副本取并集组成一个失效副本集合。 不过这个参数本身很难给出一个合适的值。以默认的值4000为例,对于消息流入速度很低的主题(比如TPS为10),这个参数就没什么用;对于消息流入速度很高的主题(比如TPS为2000),这个参数的取值又会引入ISR的频繁变动。所以从0.9x版本开始,Kafka就彻底移除了这一个参数。展开共 19 条评论194
- 张三丰2021-01-16replica.lag.time.max.ms,感觉老师对这个参数的解释有歧义。 应该是如果leader发现flower超过这个参数所设置的时间没有向它发起fech请求(也就是复制请求),那么leader考虑将这个flower从ISR移除。 而不是连续落后这么长时间
作者回复: 嗯,是的。你的解释更精准:)
共 4 条评论44 - Mick2019-08-02老师,LEO和HW这两个概念不理解,能不能详细说下,谢谢
作者回复: 一个分区有3个副本,一个leader,2个follower。producer向leader写了10条消息,follower1从leader处拷贝了5条消息,follower2从leader处拷贝了3条消息,那么leader副本的LEO就是10,HW=3;follower1副本的LEO是5。这样说清楚些吗
共 8 条评论29 - 凯2019-08-01请问一下,producer生产消息ack=all的时候,消息是怎么保证到follower的,因为看到follower是异步拉取数据的,难道是看leader和follower上面的offset吗?
作者回复: 通过HW机制。leader处的HW要等所有follower LEO都越过了才会前移
共 4 条评论28 - ideal sail2019-12-16老师,假设一个分区有5个副本,Broker的min.insync.replicas设置为2,生产者设置acks=all,这时是有2个副本同步了就可以,还是必须是5个副本都同步,他们是什么关系。
作者回复: Producer端认为消息已经成功提交的条件是:ISR中所有副本都已经保存了该消息,但producer并没有指定ISR中需要几个副本。这就是min.insync.replicas参数的作用。 正常情况下,如果5个副本都在ISR中,那么它们必须都同步才行,但如果4个副本不在ISR中了,不满足min.insync.replicas了,此时broker会抛出异常给producer,告诉producer这条消息无法正确保存
共 3 条评论25 - 咸淡一首诗2020-04-07老师,“这个标准就是 Broker 端参数 replica.lag.time.max.ms 参数值。这个参数的含义是 Follower 副本能够落后 Leader 副本的最长时间间隔,当前默认值是 10 秒” 这句话中的最长时间间隔是怎么计算的,以什么时间为基准?
作者回复: follower从leader拿到消息后会更新一个名为_lastCaughtUpTimeMs的字段。每当要检查follower是否out of ISR时就会用当前时间减去这个字段值去和replica.lag.time.max.ms 比较
共 3 条评论20 - 曹伟雄2019-12-16老师你好,有个问题请教一下,麻烦抽空看看,谢谢。 生产环境,因磁盘满了,所有broker宕机了,重启集群后,主题中的部分分区中,有1个副本被踢出ISR集合,只剩下leader副本了。 试了以下几种方法都没有自动加入进来: 1、等了3天后还是没有加入到ISR; 2、然后重启kafka集群; 3、用kafka-reassign-partitions.sh命令重新分配分区; 针对此情况,请问一下有什么办法让它自动加入进来? 或者手工处理加入进来也可以。 有什么命令可以查看follower落后多少吗? 麻烦老师给点建议或解决思路,谢谢。展开
作者回复: 试试到ZooKeeper中手动删除/controller节点。这通常都是因为Controller与ZooKeeper状态不同步导致的。 试试这个命令吧: rmr /controller 确保在业务低峰时刻执行这个命令
共 2 条评论15 - 注定非凡2019-11-071 副本机制的定义:所谓副本机制(Replication),也可以称之为备份机制,通常是指分布式在多台网络互连的机器上保存有相同的数据拷贝。 2 副本机制的价值:A :提供数据冗余 B :提供高伸缩性 C :改善数据局部性 但 Kafka的副本机制,只实现了提供数据冗余的价值。 3 副本定义: A :Kafka有主题的概念,每个主题又分为若干个分区。副本的概念是在分区层级下定义的,每个分区配置有若干个副本。 B :所谓副本(Replica),本质是一个只能追加写消息的提交日志。 根据Kafka副本机制的定义,同一个分区下的所有副本保存有相同的消息序列,这些副本分散保存在不同的Broker上,从而能够对抗部分Broker宕机带来的数据不可用。 4 副本角色: A :为解决分区下多个副本的内容一致性问题,常用方案就是采用基于领导者的副本机制。 B :在kafka中,副本分两类:领导者副本和追随者副本。每个分区在创建时都选举一个副本,称为领导者副本,其余的副本自动成为追随者副本。 C :Kafka的副本机制比其他分布式系统严格。Kafka的追随者副本不对外提供服务。所有的请求都要由领导者副本处理。追随者副本唯一的任务就是从领导者副本异步拉取消息,并写入到自己的提交日志中,从而实现与领导者副本的同步。 D :当领导者副本所在Broker宕机了,Kafka依托于Zookeeper提供的监控功能能够实时感知到,并立即开启新一轮的领导者选举,从追随者副本中选一个新的领导者。当老的Leader副本重启回来后,只能作为追随者副本加入到集群中。 4 Kafka副本机制的优点: A :方便实现“Read-your-writes” (1)含义:当使用生产者API向Kafka成功写入消息后,马上使用消息者API去读取刚才生产的消息。 (2)如果允许追随者副本对外提供服务,由于副本同步是异步的,就可能因为数据同步时间差,从而使客户端看不到最新写入的消息。 B :方便实现单调读(Monotonic Reads) (1)单调读:对于一个消费者用户而言,在多处消息消息时,他不会看到某条消息一会存在,一会不存在。 (2)如果允许追随者副本提供读服务,由于消息是异步的,则多个追随者副本的状态可能不一致。若客户端每次命中的副本不同,就可能出现一条消息一会看到,一会看不到。 5 In-sync Replicas(ISR)同步副本 A :追随者副本定期的异步拉取领导者副本中的数据,这存在不能和Leader实时同步的风险。 B :Kafka引入了In-sync Replicas。ISR中的副本都是于Leader同步的副本,相反,不在ISR中的追随者副本就是被认为是与Leader不同步的。 C :Leader 副本天然就在ISR中,即ISR不只是追随者副本集合,他必然包括Leader副本。甚至某些情况下,ISR只有Leade这一个副本。 D :follower副本是否与leader同步的判断标准取决于Broker端参数 replica.lag.time.max.ms参数值。默认为10秒,只要一个Follower副本落后Leader副本的时间不连续超过10秒,那么Kafka就认为该Follower副本与leader是同步的,即使此时Follower副本中保存的消息明显小于Leader副本中的消息。 E :如果同步过程持续慢于Leader副本消息的写入速度,那么replica.lag.time.max.ms时间后,此Follower副本就会被认为是与Leader副本不同步的,因此不能再放入ISR中。此时,kafka会自动收缩ISR的进度,将该副本“踢出”ISR。ISR是一个动态调整的集合,而非静态不变的。 6 Unclean 领导者选举(Unclean Leader Election) A :ISR是可以动态调整的,所以会出现ISR为空的情况,由于Leader副本天然就在ISR中,如果ISR为空了,这说明Leader副本也挂掉了,Kafka需要重新选举一个新的Leader。 B :Kafka把所有不在ISR中的存活副本都会称为非同步副本。通常,非同步副本落后Leader太多,如果让这些副本做为新的Leader,就可能出现数据的丢失。在kafka中,选举这种副本的过程称为Unclean领导者选举。 C :Broker端参数unclean.leader.election.enable 控制是否允许Unclean领导者选举。开启Unclean领导者选举可能会造成数据丢失,但它使得分区Leader副本一直存在,不至于停止对外提供服务,因此提升了高可用性。禁止Unclean领导者选举的好处是在于维护了数据的一致性,避免了消息丢失,但牺牲了高可用性。展开共 2 条评论14
- 云师兄2019-10-11ack=all时候,生产者向leader发送完数据,而副本是异步拉取的,那生产者写入线程要一直阻塞等待吗
作者回复: 不会阻塞,你可以认为是不断轮询状态
12 - Cv2020-03-13生产者acks=all使用异步提交, 如果ISR副本迟迟不能完成从leader的同步, 那么10s过后, 生产者会收到提交失败的回调吗? 还是一直不会有回调
作者回复: 会的,回调中会包含对应的错误码
共 2 条评论9 - 李先生2020-04-13胡哥:分区选举leader,是通过抢占模式来选举的。如果不开启unclean.leader.election.enable,是只能isr集合中的broker才能竞争吗?这个竞争的过程能具体说下是如何实现的吗?
作者回复: 目前选举leader的算法很简单,一般是选择AR中第一个处在ISR集合的副本为leader。比如AR的副本顺序是[1,2,3],ISR是[2,3],那么副本2就是leader
共 3 条评论8 - LJK2019-09-25老师好,请问ISR中的副本一定可以保证和leader副本的一致性吗?如果有一种情况是某个ISR中副本与leader副本的lag在ISR判断的边界值,这时如果leader副本挂了的话,还是会有数据丢失是吗?谢谢老师
作者回复: ISR中的follower副本非常有可能与leader不一致的。如果leader挂了,其他follower又都没有保存该消息,那么该消息是可能丢失的。如果你要避免这种情况,设置producer端的acks=all吧
共 5 条评论8 - 陈国林2020-01-18老师好,我觉得是否可以这样分场景。对于读新的数据可以从 leader replica 读取,对于老一些的数据从follower replica 读取,这样不懂是否可行
作者回复: 初衷是好的。难点在于我们如何区分什么数据是新的什么是老的:)
5 - 不能扮演天使2019-09-10老师,ack=all,是保证ISR中的follower同步还是所有的follower同步,还有消费者是只能消费到ISR中的HW处的offset么?
作者回复: acks=all保证ISR中的所有副本都要同步
5 - 外星人2019-07-28请问,关闭unclean后,有哪些方法可以保证available啊?谢谢
作者回复: 增加副本数:)
共 2 条评论5 - 球球2019-07-25胡夕老师好,replica.lag.time.max.ms配置follower是否处于isr中,那么是否存在,在这个时间段内数据写完leader,follower还没有完全同步leader数据,leader宕机,isr中follower提升为新leader,那这一部分数据是否就丢失呢?该如何避免呢?谢谢
作者回复: 不会丢失。还是那句话:Kafka只对已提交消息做持久化保证。如果你设置了最高等级的持久化需求(比如acks=all),那么follower副本没有同步完成前这条消息就不算已提交,也就不算丢失了。
共 4 条评论6 - 刘彬2019-07-25老师好,想请教您两个问题,如下: 如果某个follower副本同步持续慢于leader副本写入速度,repkica.lag.time.max.ms 是对于二者的同步时间做的判断,我理解就是如果一直检查10s follower都赶不上leader副本的进度! 但是,这个同步进度是用哪一块进行判别的呢?是通过index值吗? 另外,如果某个follower不在ISR中了,kafka如果维持副本数均衡呢?比如设置了副本数为3,其中一个副本不在ISR集合中了,那么就一直少了一个副本吗?前提是这个副本一直没有跟上leader的同步进度! 谢谢!展开
作者回复: 1. 通过比较follower和leader的最新消息位移或末端消息位移(Log End Offset, LEO) 2. 嗯,就一直少一个副本了
共 4 条评论5 - 风2020-11-24ack=all时候,生产者向leader发送完数据,而副本是异步拉取的,那生产者写入线程要一直阻塞等待吗 老师这个问题您是说不会阻塞,可以认为是生产会不断地轮询状态 那是否可能存在发送了两条消息,可能导致后发送的先写入分区(设置max.in.flight.requests.per.connection),如果不可能的话,此时生产者是否处于阻塞模式,无法再次发送消息
作者回复: 是可能出现消息乱序的情形
4 - thomas2020-04-30老师,请问以replica.lag.time.max.ms=10s为副本机制的判断依据,遇到以下场景的话,是如何解决? 比如 Leader-A LEO=1000 Follower-B LEO=800, 他们的差值是200, 那如何判断这200条消息是否会在10s内同步完?
作者回复: follower b leo追到1000时会更新一个时间戳。然后通过当前时间与这个时间戳的差值和10s进行判断
4 - Cv2020-03-13ISR中的数据也会落后leader, 那么leader挂了之后的重新选举, 一样会造成数据丢失, 为了避免这种请问, 我们是否需要把replica.lag.time.max.ms设置为0呢?
作者回复: 通常不需要。如果你在意这种情况,使用acks=all的producer吧
4