一句话,kafka 的 controller 在 zookeeper 的协助下管理整个 kafka 集群。
首先回顾下 zookeeper 的目录结构:
Controller 的职责主要是:
- 集群成员管理
- 成员数量管理,监听 /brokers/ids 节点
- 成员信息管理,变更后更新所有 broker 元数据
- topic管理
- 主题的创建变更,监听 /brokers/topics 节点
- 主题删除,监听 /admin/delete_topics 节点
- 向其他broker提供元数据
- 分区重分配
- Prefered leader选举
Controller向broker发送三类请求:
- LeaderAndIsrRequest:最主要的功能是,告诉 Broker 相关主题各个分区的 Leader 副本位于哪台 Broker 上、ISR 中的副本都在哪些 Broker 上。在我看来,它应该被赋予最高的优先级,毕竟,它有令数据类请求直接失效的本领。试想一下,如果这个请求中的 Leader 副本变更了,之前发往老的 Leader 的 PRODUCE 请求是不是全部失效了?因此,我认为它是非常重要的控制类请求。
- StopReplicaRequest:告知指定 Broker 停止它上面的副本对象,该请求甚至还能删除副本底层的日志数据。这个请求主要的使用场景,是分区副本迁移和删除主题。在这两个场景下,都要涉及停掉 Broker 上的副本操作。
- UpdateMetadataRequest:顾名思义,该请求会更新 Broker 上的元数据缓存。集群上的所有元数据变更,都首先发生在 Controller 端,然后再经由这个请求广播给集群上的所有 Broker。在我刚刚分享的案例中,正是因为这个请求被处理得不及时,才导致集群 Broker 无法获取到最新的元数据信息。
Controller选举:
第一个成功创建 /controller 节点的 Broker 会被指定为控制器。一旦 Broker 与 ZooKeeper 的会话终止,该节点就会消失。集群上所有的 Broker 都在实时监听 ZooKeeper 上的这个节点。集群启动时;/controller 节点被删除时;/controller 节点数据变更时都会触发controller选举。