【Kafka源码】broker被选为controller之后的连锁反应

本文详细探讨了Kafka Broker被选为Controller后的主要操作,包括更新controller epoch、注册各种监听器(如分区重新分配、ISR改变、首选副本选举监听器)、初始化分区和副本状态机、启动自动负载均衡定时器以及启动删除topic进程等。通过这些操作,Controller协调Kafka集群的管理和变更。
摘要由CSDN通过智能技术生成


今天我们主要分析下broker被选为controller之后,主要干了什么。门面代码先列出来:

def onControllerFailover() {
    if (isRunning) {
        info("Broker %d starting become controller state transition".format(config.brokerId))
        //read controller epoch from zk
        readControllerEpochFromZookeeper()
        // increment the controller epoch
        incrementControllerEpoch(zkUtils.zkClient)
        // before reading source of truth from zookeeper, register the listeners to get broker/topic callbacks
        registerReassignedPartitionsListener()
        registerIsrChangeNotificationListener()
        registerPreferredReplicaElectionListener()
        partitionStateMachine.registerListeners()
        replicaStateMachine.registerListeners()
        initializeControllerContext()
        replicaStateMachine.startup()
        partitionStateMachine.startup()
        // register the partition change listeners for all existing topics on failover
        controllerContext.allTopics.foreach(topic => partitionStateMachine.registerPartitionChangeListener(topic))
        info("Broker %d is ready to serve as the new controller with epoch %d".format(config.brokerId, epoch))
        brokerState.newState(RunningAsController)
        maybeTriggerPartitionReassignment()
        maybeTriggerPreferredReplicaElection()
        /* send partition leadership info to all live brokers */
        sendUpdateMetadataRequest(controllerContext.liveOrShuttingDownBrokerIds.toSeq)
        if (config.autoLeaderRebalanceEnable) {
            info("starting the partition rebalance scheduler")
            autoRebalanceScheduler.startup()
            autoRebalanceScheduler.schedule("partition-rebalance-thread", checkAndTriggerPartitionRebalance,
                5, config.leaderImbalanceCheckIntervalSeconds.toLong, TimeUnit.SECONDS)
        }
        deleteTopicManager.start()
    }
    else
        info("Controller has been shut down, aborting startup/failover")
}

一个门面,涉及到的监听器和其他内容比较多,我们一一分析。

一、controller epoch

首先从zk的节点/controller_epoch下获取之前的epoch,然后将其+1后持久化到zk中。

二、注册监听器

这块就是订阅zk的节点信息,如果节点信息有变化,会做出一些操作。

2.1 registerReassignedPartitionsListener

private def registerReassignedPartitionsListener() = {
    zkUtils.zkClient.subscribeDataChanges(ZkUtils.ReassignPartitionsPath, partitionReassignedListener)
}

这块订阅的路径是:/admin/reassign_partitions,表示的是分区的重新分配。如果有变化,会有下面的操作:

/**
    * Starts the partition reassignment process unless -
    * 1. Partition previously existed
    * 2. New replicas are the same as existing replicas
    * 3. Any replica in the new set of replicas are dead
    * If any of the above conditions are satisfied, it logs an error and removes the partition from list of reassigned
    * partitions.
    */
class PartitionsReassignedListener(controller: KafkaController) extends IZkDataListener with Logging {
   
    this.logIdent = "[PartitionsReassignedListener on " + controller.config.brokerId + "]: "
    val zkUtils = controller.controllerContext.zkUtils
    val controllerContext = controller.controllerContext

    /**
    * Invoked when some partitions are reassigned by the admin command
    * @throws Exception On any error.
    */
    @throws(classOf[Exception])
    def handleDataChange(dataPath: String, data: Object) {
        debug("Partitions reassigned listener fired for path %s. Record partitions to be reassigned %s"
            .format(dataPath, data))
        //解析zk节点上的数据
        val partitionsReassignmentData = zkUtils.parsePartitionReassignmentData(data.toString)
        //获取需要重新分配的分区列表
        val partitionsToBeReassigned = inLock(controllerContext.controllerLock) {
            partitionsReassignmentData.filterNot(p => controllerContext.partitionsBeingReassigned.contains(p._1))
        }
        partitionsToBeReassigned.foreach { partitionToBeReassigned =>
            inLock(controllerContext.controllerLock) {
            //首先判断topic是否正在等待被删除,如果是,就把相关的分区从列表中删除
                if (controller.deleteTopicManager.isTopicQueuedUpForDeletion(partitionToBeReassigned._1.topic)) {
                    error("Skipping reassignment of partition %s for topic %s since it is currently being deleted"
                        .format(partitionToBeReassigned._1, partitionToBeReassigned._1.topic))
                    controller.removePartitionFromReassignedPartitions(partitionToBeReassigned._1)
                } else {
  //进行重分配
                    val context = new ReassignedPartitionsContext(partitionToBeReassigned._2)
                    controller.initiateReassignReplicasForTopicPartition(partitionToBeReassigned._1, context)
                }
            }
        }
    }

    /**
        * Called when the leader information stored in zookeeper has been delete. Try to elect as the leader
        *
        * @throws Exception
        * On any error.
        */
    @throws(classOf[Exception])
    def handleDataDeleted(dataPath: String) {
    }
}

下面我们具体看下重新分配的过程,也就是initiateReassignReplicasForTopicPartition里面做了什么。

2.1.1 initiateReassignReplicasForTopicPartition

def initiateReassignReplicasForTopicPartition(topicAndPartition: TopicAndPartition,reassignedPartitionContext: ReassignedPartitionsContext) {
    val newReplicas = reassignedPartitionContext.newReplicas
    val topic = topicAndPartition.topic
    val partition = topicAndPartition.partition
    //获取存活的replica
    val aliveNewReplicas = newReplicas.filter(r => controllerContext.liv
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值