Kafka 状态机模块(一):PartitionStateMachine分区状态机

        PartitionStateMachine 定义了 Kafka Controller 的分区状态机,用于管理集群中分区的状态信息,每个 Kafka Controller 都定义了自己的分区状态机,但只有在当前 Controller 实例成为 leader 角色时才会启动运行名下的状态机。

它启动逻辑如下:

  def startup(): Unit = {
    info("Initializing partition state")
    // // 初始化本地记录的所有分区状态
    initializePartitionState()
    info("Triggering online partition state changes")
    // 尝试将集群中所有 OfflinePartition 或 NewPartition 状态的可用分区切换成 OnlinePartition 状态
    triggerOnlinePartitionStateChange()
    debug(s"Started partition state machine with initial state -> ${controllerContext.partitionStates}")
  }
  private def initializePartitionState(): Unit = {
    // 遍历集群中的所有分区
    for (topicPartition <- controllerContext.allPartitions) {
      // check if leader and isr path exists for partition. If not, then it is in NEW state
      // 获取对应分区 leader 副本所在的 brokerId、ISR 集合,以及 controller 年代信息
      controllerContext.partitionLeadershipInfo.get(topicPartition) match {
        // 存在 leader 副本和 ISR 集合
        case Some(currentLeaderIsrAndEpoch) =>
          // else, check if the leader for partition is alive. If yes, it is in Online state, else it is in Offline state
          // 分区 leader 副本所在的 broker 可用,初始化分区为 OnlinePartition 状态
          if (controllerContext.isReplicaOnline(currentLeaderIsrAndEpoch.leaderAndIsr.leader, topicPartition))
          // leader is alive
            controllerContext.putPartitionState(topicPartition, OnlinePartition)
          else
          // 分区 leader 副本所在的 broker 不可用,初始化为 OfflinePartition 状态
            controllerContext.putPartitionState(topicPartition, OfflinePartition)
        case None =>
          // 如果不存在,则说明是一个新创建的分区,设置分区状态为 NewPartition
          controllerContext.putPartitionState(topicPartition, NewPartition)
      }
    }
  }

Kafka 为分区定义了 4 类状态。

  • NewPartition:分区被创建后被设置成这个状态,表明它是一个全新的分区对象。处于这个状态的分区,被 Kafka 认为是“未初始化”,因此,不能选举 Leader。
  • OnlinePartition:分区正式提供服务时所处的状态。
  • OfflinePartition:分区下线后所处的状态。
  • NonExistentPartition:分区被删除,并且从分区状态机移除后所处的状态。

分区 Leader 选举的场景及方法:分区 Leader 选举有 4 类场景。

  • OfflinePartitionLeaderElectionStrategy:因为 Leader 副本下线而引发的分区 Leader 选举。
  • ReassignPartitionLeaderElectionStrategy:因为执行分区副本重分配操作而引发的分区 Leader 选举。
  • PreferredReplicaPartitionLeaderElectionStrategy:因为执行 Preferred 副本 Leader 选举而引发的分区 Leader 选举。
  • ControlledShutdownPartitionLeaderElectionStrategy:因为正常关闭 Broker 而引发的分区 Leader 选举。

针对这 4 类场景,分区状态机的 PartitionLeaderElectionAlgorithms 对象定义了 4 个方法,分别负责为每种场景选举 Leader 副本,这 4 种方法是:offlinePartitionLeaderElection;reassignPartitionLeaderElection;preferredReplicaPartitionLeaderElection;controlledShutdownPartitionLeaderElection。

// 分区Leader选举策略接口
sealed trait PartitionLeaderElectionStrategy
// 离线分区Leader选举策略
final case class OfflinePartitionLeaderElectionStrategy(
  allowUnclean: Boolean) extends PartitionLeaderElectionStrategy
// 分区副本重分配Leader选举策略  
final case object ReassignPartitionLeaderElectionStrategy 
  extends PartitionLeaderElectionStrategy
// 分区Preferred副本Leader选举策略
final case object PreferredReplicaPartitionLeaderElectionStrategy 
  extends PartitionLeaderElectionStrategy
// Broker Controlled关闭时Leader选举策略
final case object ControlledShutdownPartitionLeaderElectionStrategy 
  extends PartitionLeaderElectionStrategy

offlinePartitionLeaderElection 方法的逻辑是这 4 个方法中最复杂的

  def offlinePartitionLeaderElection(assignment: Seq[Int], // 这是分区的副本列表
                                     isr: Seq[Int],
                                     liveReplicas: Set[Int], // 该分区下所有处于存活状态的副本
                                     uncleanLeaderElectionEnabled: Boolean, // 脏选举
                                     controllerContext: ControllerContext
                                    ): Option[Int] = {
    // 从当前分区副本列表中寻找首个处于存活状态的ISR副本
    assignment.find(id => liveReplicas.contains(id) && isr.contains(id))
      .orElse {
      // 如果找不到满足条件的副本,查看是否允许Unclean Leader选举
      // 即Broker端参数un
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值