Kafka学习(2) - Kafka之失效副本

本文根据原创整理而来
原创出处 https://blog.csdn.net/u013256816/article/details/78851989

Kafka之失效副本

Kafka从0.8.x版本开始引入副本机制,这样可以极大的提高集群的可靠性和稳定性。
通常情况下,Kafka中的每个分区(partition)都会分配多个副本(replica),具体的副本数量由Broker级别参数default.replication.factor(默认为1)指定,也可以在创建topic的时候通过 –replication-factor ${num}显式指定副本的数量(副本因子)。一般情况下,将前者default.replication.factor设置为大于1的值,这样在参数auto.create.topic.enabletrue的时候,自动创建的topic会根据default.replication.factor的值来创建副本数;或者更加通用的做法是使用后者而指定大于1的副本数。
每个分区的多个副本称之为AR(assigned replicas),包含至多一个leader副本和多个follower副本。与AR对应的另一个重要的概念就是ISR(in-sync-replicas)ISR是指与leader副本保持同步状态的副本集合,当然leader副本本身也是这个集合中的一员。而ISR之外,也就是处于同步失败或失效状态的副本,副本对应的分区也就称之为同步失效分区,即under-replicated分区。

失效副本的判定

Kafka0.9.x版本开始通过唯一的一个参数replica.lag.time.max.ms(默认为10,000)来控制,当ISR中的一个follower副本滞后leader副本的时间超过参数replica.lag.time.max.ms指定的值时即判定为副本失效,需要将此follower副本剔出除ISR之外。
具体实现原理很简单,当follower副本将leader副本的LEO(Log End Offset,每个分区最后一条消息的位置)之前的日志全部同步时,则认为该follower副本已经追赶上leader副本,此时更新该副本的lastCaughtUpTimeMs标识。Kafka的副本管理器(ReplicaManager)启动时会启动一个副本过期检测的定时任务,而这个定时任务会定时检查当前时间与副本的lastCaughtUpTimeMs差值是否大于参数replica.lag.time.max.ms指定的值。千万不要错误的认为follower副本只要拉取leader副本的数据就会更新lastCaughtUpTimeMs,当leader副本的消息流入速度大于follower副本的拉取速度时,follower副本一直不断的拉取leader副本的消息也不能与leader副本同步,如果还将此follower副本置于ISR中,那么当leader副本失效,而选取此follower副本为新的leader副本,那么就会有严重的消息丢失。

Kafka源码注释中说明了一般有两种情况会导致副本失效:
1.follower副本进程卡住,在一段时间内根本没有想leader副本发起同步请求,比如频繁的Full GC
2.follower副本进程同步过慢,在一段时间内都无法追赶上leader副本,比如IO开销过大。
如果通过工具增加了副本因子,那么新增加的副本在赶上leader副本之前也都是处于失效状态的。如果一个follower副本由于某些原因(比如宕机)而下线,之后又上线,在追赶上leader副本之前也是出于失效状态。

Kafka0.9.x版本之前还有另一个Broker级别的参数replica.lag.max.messages(默认为4000)也是用来判定失效副本的,当一个follower副本滞后leader副本的消息数超过replica.lag.max.messages的大小时则判定此follower副本为失效副本。它与replica.lag.time.max.ms参数判定出的失败副本去并集组成一个失效副本的集合,从而进一步剥离出ISR

不过这个replica.lag.max.messages参数很难给定一个合适的值,若设置的太大则这个参数本身就没有太多意义,若设置的太小则会让follower副本反复的处于同步、未同步、同步的死循环中,进而又会造成ISR的频繁变动。而且这个参数是Broker级别的,也就是说对Broker中的所有topic都生效,就以默认的值4000来说,对于消息流入速度很低的topic来说,比如TPS=10,这个参数并无用武之地;而对于消息流入速度很高的topic来说,比如TPS=20,000,这个参数的取值又会引入ISR的频繁变动,所以从0.9.x版本开始就彻底移除了这一参数

具有失效副本的分区可以从侧面洞悉出Kafka集群的很多问题,不夸张的说:如果用一个指标来衡量Kafka,那么必然是失效副本分区的个数。Kafka本身也提供了一个相关的指标,即UnderReplicatedPartitions,这个可以通过JMX访问 kafka.server:type=ReplicaManager,name=UnderReplicatedPartitions
如果获取的UnderReplicatedPartitions值大于0,就需要对其进行告警,并进一步诊断其背后的真正原因,有可能是某个Broker的问题,也有可能引申到整个集群的问题,也许还要引入其他一些信息、指标等配合找出问题之所在。注意:如果Kafka集群正在做分区迁移(kafka-reassign-partitions.sh)的时候,这个值也会大于0。

优先副本的选举

所谓的优先副本是指在KafkaAR列表中的第一个副本。理想情况下,优先副本就是该分区的leader副本,所以也可以称之为preferred leaderKafka要确保所有主题的优先副本在Kafka集群中均匀分布,这样就保证了所有分区的Leader均衡分布。保证Leader在集群中均衡分布很重要,因为所有的读写请求都由分区leader副本进行处理,如果leader分布过于集中,就会造成集群负载不均衡。试想一下,如果某分区的leader副本在某个很空闲的Broker上,而它的follower副本宿主于另一个很繁忙的Broker上,那么此follower副本很可能由于分配不到足够的系统资源而无法完成副本同步的任务,进而造成副本失效。

所谓的优先副本的选举是指通过自动或者手动的方式促使优先副本选举为leader,也就是分区平衡,这样可以促进集群的均衡负载,也就进一步的降低失效副本生存的几率。需要注意的是分区平衡并不意味着Kafka集群的负载均衡,因为这还要考虑到集群中的分区分配是否均衡。更进一步每个分区的leader的负载也是各不相同,有些leader副本的负载很高,比如需要承受TPS为3W的负荷,而有些leader副本只需承载个位数的负荷,也就是说就算集群中的分区分配均衡,leader分配也均衡也并不能确保整个集群的负载就是均衡的,还需要其他一些硬性的指标来做进一步的衡量

随着集群运行时间的推移,可能部分节点的变化导致leader进行了重新选举,若优先副本的宿主Broker在发生故障后由其他副本代替而担任了新的leader,就算优先副本的宿主Broker故障恢复而重新回到集群时若没有自动平衡的功能,该副本也不会成为分区的leader
Kafka具备分区自动平衡的功能,且默认情况下此功能是开启的,与此对应的参数是 auto.leader.rebalance.enable=true。如果开启分区自动平衡,则KafkaController会创建一个分区重分配检查及分区重分配操作(onPartitionReassignment)的定时任务,这个定时任务会轮询所有的Broker,计算每个Broker的分区不平衡率(Broker中的不平衡率=非优先副本的leader个数/分区总数)是否超过leader.imbalance.per.broker.percentage配置的比率,默认是10%,如果超过设定的比率则会自动执行优先副本的选举动作以求分区平衡。默认执行周期是leader.imbalance.check.interval.seconds=300,即5分钟。不过在生产环境中不建议将auto.leader.rebalance.enable设置为默认的true,因为这可能会引起负面的性能问题,也有可能会引起客户端一定时间的阻塞。因为执行的时间无法自主掌控,如果在关键时期(比如电商大促波峰期)执行关键任务的关卡摆上一道优先副本的自动选举操作,势必会有业务阻塞、频繁超时之类的风险。前面也分析过分区的均衡也不能确保集群的均衡,而集群一定程度上的不均衡也是可以忍受的,为防关键时期掉链子的行为

优先副本的选举是一个安全的(Kafka客户端可以自动感知分区leader的变更)并且也容易执行的一类操作。执行优先副本的选举是通过$KAFKA_HOME/bin/路径下的kafka-preferred-replica-election.sh脚本来实现的。
Kafka提供了更细粒度的优先副本的选举操作,它可以细化到某个topic的某个分区这个层级,这样在面对一次请求过大的问题时可以选择性的进行细粒度拆分,也可以在实现自定义的个性化优先副本的选举操作
在实现细粒度的优先副本的选举操作之前,首先要建立一个JSON文件,将所需要的topic以及对应的分区编号记录于其中,比如针对topic-1的编号为0的分区进行优先副本的选举操作,对应的JSON文件内容如下(假设此文件命名为partitions.json):

{
        "partitions":[
                {
                        "partition":0,
                        "topic":"topic-1"
                }
        ]
}

之后再执行kafka-preferred-replica-election.sh脚本时通过–path-to-json-file参数来指定此
JSON文件,相关细节如下:

[root@zzh kafka_2.12-0.10.2.1]# bin/kafka-preferred-replica-election.sh --zookeeper 192.168.0.2:2181,192.168.0.3:2181,192.168.0.3:2181/kafka --path-to-json-file partitions.json
Created preferred replica election path with {"version":1,"partitions":[{"topic":"topic-1","partition":0}]}
Successfully started preferred replica election for partitions Set([topic-1,0])

失效副本的诊断及预警

UnderReplicatedPartitions是一个Broker级别的指标,指的是leader副本在当前Broker上且具有失效副本的分区的个数,也就是说这个指标可以让我们感知失效副本的存在以及波及的分区数量。这一类分区也就是文中篇头所说的同步失效分区,即under-replicated分区。

  1. 如果集群中有多个BrokerUnderReplicatedPartitions保持一个大于0的稳定值时,一般暗示着集群中有Broker已经处于下线状态。这种情况下,这个Broker中的分区个数与集群中的所有UnderReplicatedPartitions(处于下线的Broker是不会上报任何指标值的)之和是相等的。通常这类问题是由于机器硬件原因引起的,但也有可能是由于操作系统或者JVM引起的,可以根据这个方向继续做进一步的深入调查。
  2. 如果集群中存在BrokerUnderReplicatedPartitions频繁变动,或者处于一个稳定的大于0的值(这里特指没有Broker下线的情况)时,一般暗示着集群出现了性能问题,通常这类问题很难诊断,不过我们可以一步一步的将问题的范围缩小,比如先尝试确定这个性能问题是否只存在于集群的某个Broker中,还是整个集群之上。如果确定集群中所有的under-replicated分区都是在单个Broker上,那么可以看出这个Broker出现了问题,进而可以针对这单一的Broker做专项调查,比如:操作系统、GC、网络状态或者磁盘状态(比如:iowait、ioutil等指标)
  3. 如果多个Broker中都出现了under-replicated分区,这个一般是整个集群的问题,但也有可能是单个Broker出现了问题,前者可以理解,后者有作何解释?想象这样一种情况,如果某个Broker在同步消息方面出了问题,那么其上的follower副本就无法及时有效与其他Broker上的leader副本上进行同步,这样一来就出现了多个Broker都存在under-replicated分区的现象。有一种方法可以查看是否是单个Broker问题已经是哪个Broker出现了问题,就是通过kafka-topic.sh工具来查看集群中所有的under-replicated分区
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值