kafka控制器的作用(controller)(代码片段)

张志翔ۤ 张志翔ۤ     2023-01-02     732

关键词:

在Kafka集群中会有一个或者多个broker,其中有一个broker会被选举为控制器(Kafka Controller),它负责管理整个集群中所有分区和副本的状态。当某个分区的leader副本出现故障时,由控制器负责为该分区选举新的leader副本。当检测到某个分区的ISR集合发生变化时,由控制器负责通知所有broker更新其元数据信息。当使用kafka-topics.sh脚本为某个topic增加分区数量时,同样还是由控制器负责分区的重新分配。

Kafka中的控制器选举的工作依赖于Zookeeper,成功竞选为控制器的broker会在Zookeeper中创建/controller这个临时(EPHEMERAL)节点,此临时节点的内容参考如下:

"version":1,"brokerid":0,"timestamp":"1529210278988"

其中version在目前版本中固定为1,brokerid表示称为控制器的broker的id编号,timestamp表示竞选称为控制器时的时间戳。

在任意时刻,集群中有且仅有一个控制器。每个broker启动的时候会去尝试去读取/controller节点的brokerid的值,如果读取到brokerid的值不为-1,则表示已经有其它broker节点成功竞选为控制器,所以当前broker就会放弃竞选;如果Zookeeper中不存在/controller这个节点,或者这个节点中的数据异常,那么就会尝试去创建/controller这个节点,当前broker去创建节点的时候,也有可能其他broker同时去尝试创建这个节点,只有创建成功的那个broker才会成为控制器,而创建失败的broker则表示竞选失败。每个broker都会在内存中保存当前控制器的brokerid值,这个值可以标识为activeControllerId。

Zookeeper中还有一个与控制器有关的/controller_epoch节点,这个节点是持久(PERSISTENT)节点,节点中存放的是一个整型的controller_epoch值。controller_epoch用于记录控制器发生变更的次数,即记录当前的控制器是第几代控制器,我们也可以称之为“控制器的纪元”。controller_epoch的初始值为1,即集群中第一个控制器的纪元为1,当控制器发生变更时,没选出一个新的控制器就将该字段值加1。每个和控制器交互的请求都会携带上controller_epoch这个字段,如果请求的controller_epoch值小于内存中的controller_epoch值,则认为这个请求是向已经过期的控制器所发送的请求,那么这个请求会被认定为无效的请求。如果请求的controller_epoch值大于内存中的controller_epoch值,那么则说明已经有新的控制器当选了。由此可见,Kafka通过controller_epoch来保证控制器的唯一性,进而保证相关操作的一致性。

具备控制器身份的broker需要比其他普通的broker多一份职责,具体细节如下:

  1. 监听partition相关的变化。为Zookeeper中的/admin/reassign_partitions节点注册PartitionReassignmentListener,用来处理分区重分配的动作。为Zookeeper中的/isr_change_notification节点注册IsrChangeNotificetionListener,用来处理ISR集合变更的动作。为Zookeeper中的/admin/preferred-replica-election节点添加PreferredReplicaElectionListener,用来处理优先副本的选举动作。
  2. 监听topic相关的变化。为Zookeeper中的/brokers/topics节点添加TopicChangeListener,用来处理topic增减的变化;为Zookeeper中的/admin/delete_topics节点添加TopicDeletionListener,用来处理删除topic的动作。
  3. 监听broker相关的变化。为Zookeeper中的/brokers/ids/节点添加BrokerChangeListener,用来处理broker增减的变化。
  4. 从Zookeeper中读取获取当前所有与topic、partition以及broker有关的信息并进行相应的管理。对于所有topic所对应的Zookeeper中的/brokers/topics/[topic]节点添加PartitionModificationsListener,用来监听topic中的分区分配变化。
  5. 启动并管理分区状态机和副本状态机。
  6. 更新集群的元数据信息。
  7. 如果参数auto.leader.rebalance.enable设置为true,则还会开启一个名为“auto-leader-rebalance-task”的定时任务来负责维护分区的优先副本的均衡。
     

这个列表可能会让读者感到困惑,甚至完全不知所云。不要方~ 笔者这里只是用来突出控制器的职能很多,而这些功能的具体细节会在后面的文章中做具体的介绍。

控制器在选举成功之后会读取Zookeeper中各个节点的数据来初始化上下文信息(ControllerContext),并且也需要管理这些上下文信息,比如为某个topic增加了若干个分区,控制器在负责创建这些分区的同时也要更新上下文信息,并且也需要将这些变更信息同步到其他普通的broker节点中。不管是监听器触发的事件,还是定时任务触发的事件,亦或者是其他事件(比如ControlledShutdown)都会读取或者更新控制器中的上下文信息,那么这样就会涉及到多线程间的同步,如果单纯的使用锁机制来实现,那么整体的性能也会大打折扣。针对这一现象,Kafka的控制器使用单线程基于事件队列的模型,将每个事件都做一层封装,然后按照事件发生的先后顺序暂存到LinkedBlockingQueue中,然后使用一个专用的线程(ControllerEventThread)按照FIFO(First Input First Output, 先入先出)的原则顺序处理各个事件,这样可以不需要锁机制就可以在多线程间维护线程安全。

 

在Kafka的早期版本中,并没有采用Kafka Controller这样一个概念来对分区和副本的状态进行管理,而是依赖于Zookeeper,每个broker都会在Zookeeper上为分区和副本注册大量的监听器(Watcher)。当分区或者副本状态变化时,会唤醒很多不必要的监听器,这种严重依赖于Zookeeper的设计会有脑裂、羊群效应以及造成Zookeeper过载的隐患。在目前的新版本的设计中,只有Kafka Controller在Zookeeper上注册相应的监听器,其他的broker极少需要再监听Zookeeper中的数据变化,这样省去了很多不必要的麻烦。不过每个broker还是会对/controller节点添加监听器的,以此来监听此节点的数据变化(参考ZkClient中的IZkDataListener)。

当/controller节点的数据发生变化时,每个broker都会更新自身内存中保存的activeControllerId。如果broker在数据变更前是控制器,那么如果在数据变更后自身的brokerid值与新的activeControllerId值不一致的话,那么就需要“退位”,关闭相应的资源,比如关闭状态机、注销相应的监听器等。有可能控制器由于异常而下线,造成/controller这个临时节点会被自动删除;也有可能是其他原因将此节点删除了。

当/controller节点被删除时,每个broker都会进行选举,如果broker在节点被删除前是控制器的话,在选举前还需要有一个“退位”的动作。如果有特殊需要,可以手动删除/controller节点来触发新一轮的选举。当然关闭控制器所对应的broker以及手动向/controller节点写入新的brokerid的所对应的数据同样可以触发新一轮的选举。

一文理解kafka的controller领导选举!

导语 | Controller作为ApacheKafka的核心组件,本文将从背景、原理以及源码与监控等方面来深入剖析KafkaController,希望带领大家去了解Controller在整个Kafka集群中的作用。一、背景Controller,是ApacheKafka的核心组件非常重要... 查看详情

10分钟带你玩转kafka基于controller的领导选举!

导语 | Controller作为ApacheKafka的核心组件,本文将从背景、原理以及源码与监控等方面来深入剖析KafkaController,希望带领大家去了解Controller在整个Kafka集群中的作用。一、背景Controller,是ApacheKafka的核心组件非常重要... 查看详情

10分钟带你玩转kafka基于controller的领导选举!

导语 | Controller作为ApacheKafka的核心组件,本文将从背景、原理以及源码与监控等方面来深入剖析KafkaController,希望带领大家去了解Controller在整个Kafka集群中的作用。一、背景Controller,是ApacheKafka的核心组件非常重要... 查看详情

10分钟带你玩转kafka基于controller的领导选举!

导语 | Controller作为ApacheKafka的核心组件,本文将从背景、原理以及源码与监控等方面来深入剖析KafkaController,希望带领大家去了解Controller在整个Kafka集群中的作用。一、背景Controller,是ApacheKafka的核心组件非常重要... 查看详情

kafka问答

...属于自己的Leader/FollowerKafka架构中的主要角色有Zookeeper、Controller、Leader、Follower、Producer、ConsumerZookeeper在kafka中的作用?zookeeper在kafka中主要起分布式协调作用,比如争抢创建临时节点成为controller、当broker离开集群时watch... 查看详情

kafka源码分析9:controller控制器的原理(图解+秒懂+史上最全)(代码片段)

文章很长,建议收藏起来,慢慢读!Java高并发发烧友社群:疯狂创客圈奉上以下珍贵的学习资源:免费赠送经典图书:《Java高并发核心编程(卷1)》面试必备+大厂必备+涨薪必备加尼恩免费领免... 查看详情

kafka--07---kafka集群中的controllerrebalancehw和kafka-eagle监控平台(代码片段)

...f0c;如何生成可参考右边的帮助文档文章目录kafka集群中的controller、rebalance、HW1.controller1.1集群中谁来充当controller每个broker启动时会向zk创建⼀个临时序号节点,获得的==序号最⼩==的那个broker将会作为集群中的contr... 查看详情

kafka--07---kafka集群中的controllerrebalancehw和kafka-eagle监控平台(代码片段)

...f0c;如何生成可参考右边的帮助文档文章目录kafka集群中的controller、rebalance、HW1.controller1.1集群中谁来充当controller每个broker启动时会向zk创建⼀个临时序号节点,获得的==序号最⼩==的那个broker将会作为集群中的contr... 查看详情

MVC模型中Controller的作用是啥?

...在这里浏览了一些答案和一些关于MVC的文章,但我仍然对控制器在MVC应用程序中的角色感到困惑。我在一本书中读到,模型是自包含的,并且功能独立于视图和控制器。并且模型包含业务逻辑和数据访问代码。So 查看详情

控制器controller与指令中的linkcontroller中同名变量作用域的关系

...中的函数嵌套原理一致,都是存在作用域的继承。若在子控制器(同样包括在指令中的link或是controllerding中定义变量,此时指令中必须未使用scope独立作用域)未定义相关变量,那么它会向父控制器一层层查找,直到找到位为止... 查看详情

kafka-控制器作用及选举策略(代码片段)

一、KafKa控制器作用在kafka中分为broker和partition分区,其中分区副本在前几篇文章中都进行了讲解,本篇文章针对broker进行分析,其中在kafka集群中,一个broker一般就表示一台物理机器,那机器之间的协作是怎... 查看详情

kafka核心组件之控制器和协调器

...个broker就是一个kafka的实例或者称之为kafka的服务。其实控制器也是一个broker,控制器也叫leaderbroker。他除了具有一般broker的功能外,还负责分区leader的选取,也就是负责选举partition的leaderreplica。kafka每个broker启动的时候,都会... 查看详情

详解apachepulsar的topic绑定broker

...数对集群的影响主要有两点:ZooKeeper上存储的元数据量和控制器变动效率。Kafka集群依赖于一个单一的Controller节点来处理绝大多数的ZooKeeper读写和运维操作,并在本地缓存所有ZooKeeper上的元数据。分区数增加,ZooKeeper上需要存储... 查看详情

我的控制器在 laravel 项目中不起作用我面临这个错误“Class App\Http\Controllers\HelloController 不存在”

】我的控制器在laravel项目中不起作用我面临这个错误“ClassApp\\\\Http\\\\Controllers\\\\HelloController不存在”【英文标题】:MyControllerisnotworkinginlaravelprojectIamfacingthiserror"ClassApp\\Http\\Controllers\\HelloControllerdoesnotexist"我的控制 查看详情

kafka控制器,复制与存储小结(代码片段)

【README】1,本文主要总结kafka复制,存储细节;2,本文的kafka集群版本是3.0.0,有3个broker,分别是centos201,centos202,centos203对应的brokerid为1,2,3;【1】kafka内部原理【1.1】broker-消息中心点1)broker&#... 查看详情

4.控制器

1.概述AngularJS中的控制器是一个函数,用来给视图的作用域添加额外的功能,我们用它来给作用域对象设置初始状态,并添加自定义行为。当在页面上创建一个新的控制器时,AngularJS会生成并传递一个新的$scope给这个controller,可... 查看详情

kafkakafkadefaultrecordbatch.theoldermessageformatclassesonlysupportconversionfromclass(代(代码片段)

1.概述今天想写一个事务的kafka生产者和消费者,然后我在本地开了一个Kafka,kafka版本为kafka_2.11-1.1.0[lcc@lcc~/soft/kafka/kafka_2.11-1.1.0]$bin/kafka-console 查看详情

kafka学习征途:不再依赖zk的kraft

...ookeeper的依赖。在此模式下,一部分KafkaBroker被指定为Controller,另一部分则为Broker。这些Controller的作用就是以前由Zookeeper提供的共识服务,并且所有的元数据都将存储在Kafka主题中并在内部进行管理。总体而言,... 查看详情