kafka之四----状态机与分区leader选举

每个Broker启动时,都会创建对应分区状态机和副本状态机实例,但只有Controller所在的Broker才会调用startup方法启动它们,若Controller变更了,老的Controller需要调用状态机shutdown方法进行关闭。

1、ReplicaStateMachine

副本状态机,用于管理集群中副本的状态信息

副本状态

  • NewReplica:副本被创建之后所处的状态。
  • OnlineReplica:副本正常提供服务时所处的状态。
  • OfflineReplica:副本服务下线时所处的状态。
  • ReplicaDeletionStarted:副本被删除时所处的状态。
  • ReplicaDeletionSuccessful:副本被成功删除后所处的状态。
  • ReplicaDeletionIneligible:开启副本删除,但副本暂时无法被删除时所处的状态。
  • NonExistentReplica:副本从副本状态机被移除前所处的状态。

流转规则

在这里插入图片描述

2、PartitionStateMachine

分区状态机保存了每个topic的分区状态及定义流转规则

分区状态

  • NewPartition:代表分区刚被创建,并且包含了AR,但是此时Leader或者ISR还没有被创建。这种状态下不能竞选Leader
  • OnlinePartition:代表分区的Leader已经被选举出来,并且此时已经产生了对应的ISR,分区能提供服务时的状态
  • OfflinePartition:代表了分区的Leader由于某种原因下线时导致分区暂时不可用的状态。
  • NonExistentPartition:代表分区被删除,并且从分区状态机移除后所处的状态

PartitionStateMachine的启动过程会初始化各个partition的状态
(初始化为三种状态:NewPartition、OnlinePartition、OfflinePartition),

  • 首先会根据Leader Replica是否在线初始化为OnlinePartition或者OfflinePartition,
  • 其次如果没有被分配Leader Replica,则初始化为NewPartition,
  • 接着尝试将状态为OfflinePartition或者NewPartition的partition转换为OnlinePartition,
  • 最后将Partition的状态通过ControllerChannelManager同步给其它剩余的Broker Server

执行分区状态转换的 handleStateChanges 方法,在方法调用时,不在【元数据缓存】中的所有分区的状态被初始化为NonExistentPartition

private def initializePartitionState() {
    for((topicPartition, replicaAssignment) <- controllerContext.partitionReplicaAssignment) {
      controllerContext.partitionLeadershipInfo.get(topicPartition) match {
        case Some(currentLeaderIsrAndEpoch) =>
          // partition已经被分配了Leader和ISR
          controllerContext.liveBrokerIds.contains(currentLeaderIsrAndEpoch.leaderAndIsr.leader) match {
            case true => // leader在线,状态为OnlinePartition
              partitionState.put(topicPartition, OnlinePartition)
            case false =>  //leader不在线,状态为OfflinePartition
              partitionState.put(topicPartition, OfflinePartition)
          }
        //没有被分配Leader和ISR
        case None =>
          partitionState.put(topicPartition, NewPartition)
      }
    }
  }

流转规则

在这里插入图片描述

原始状态状态切换条件切换状态
NonExistentPartition监听到zk节点/brokers/topics/目录上的数据变化,读取对应的topic的信息、分区数、AR列表,并保存到Controller内存NewPartition
NewPartition将AR列表中的第一个Live Brokers作为Leader,且Live Brokers作为ISROnlinePartition
OfflinePartitionLeader Replica选举出Leader和ISROnlinePartition
OnlinePartitionLeader Replica选举出Leader和ISROnlinePartition
NewPartition无leaderOfflinePartition
OnlinePartition无leaderOfflinePartition
OfflinePartition无leaderOfflinePartition
OfflinePartition主题被成功删除NonExistentPartition

3、partition leader Election

只有Controller的broker才会触发Partition Leader Election

选举策略

当前 Kafka 有 4 种分区 Leader 选举策略。

  • OfflinePartition Leader 选举

因为 Leader 副本下线而引发的分区。这是最常见的分区 Leader 选举场景

  • ReassignPartition Leader 选举

手动运行 kafka-reassign-partitions 命令,或者调用Admin 的alterPartitionReassignments 方法执行分区副本重分配时

  • PreferredReplicaPartition Leader 选举

为了避免分区副本分配不均匀,kafka引入了preferred副本概念,提供分区自动平衡解决分区不均匀问题。

  • 设置broker端参数auto.leader.rebalance.enable为true(默认值),这样controller定时自动调整preferred leader

Kafka 的控制器会启动一个定时任务,这个定时任务会轮询所有的 broker 节点,计算每个 broker 节点的分区不平衡率(broker 中的不平衡率=非优先副本的 leader 个数/分区总数)是否超过 leader.imbalance.per.broker.percentage 参数配置的比值(默认值为10%),如果超过设定的比值则会自动执行优先副本的选举动作以求分区平衡。执行周期由参数 leader.imbalance.check.interval.seconds 控制,默认值为300秒

优先副本的自动选举执行时间不可控,可能引起负面的性能问题,所以实际生产上一般都会关闭参数,监控相关告警后进行人工触发

  • 通过kafka-preferred-repica-election脚本手动触发。
  • ControlledShutdownPartition Leader 选举

当 Broker 正常关闭时,该 Broker 上 的所有 Leader 副本都会下线,因此,需要为受影响的分区执行相应的 Leader选举

在这里插入图片描述

分区leader选举逻辑简而言之:
当前分区副本列表(AR)中首个存活且处于 ISR 列表中的副本作为 Leader 副本

OfflinePartition Leader 选举 会再次判断是否可进行Unclean Leader 选举:
如果没找到,则看是否允许Unclean Leader 选举, 如果不允许返回 None,表示没有选出 Leader;如果允许,则寻找分区副本列表中第一个存活的副本作为 Leader 副本

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值