Kafka 的控制器信息存储在 Zookeeper 的 /controller 节点上,三个业务场景会触发 Controller 选举
集群从零启动/controller 节点消失/controller 节点数据发生变化
Kafka 节点启动,加入集群会进行以下两个操作
注册 brokers,创建临时节点 /brokers/ids/{broker.id}注册 controller,创建临时节点 /controller
第一步,通常会成功,如果失败,就说明 Kafka 集群中有两个节点的 broker.id 设置冲突了,修改 server.properties 配置文件中的 broker.id 配置。
第二步,将当前节点注册为集群的控制器,/controller 节点是一个临时节点,如果该节点不存在,则创建成功,如果该节点已存在,则创建失败,并创建一个 Watch,一旦该节点被删除,所有注册 Watch 的节点就会尝试重新创建 /controller 节点,当然只有一个会成功。
接下来演示一下整个过程
1、第一个节点 Broker-0 启动,注册到 Zookeeper,尝试创建 /controller 节点,因为此时集群中还没其它节点,创建成功,顺利成为集群的控制器。
2、第二个节点 Broker-1 启动,注册到 Zookeeper,尝试创建 /controller 节点,但是此时该节点已经由 Broker-0 创建,创建失败,Broker-1 在 /controller 节点创建一个 Watch,一旦 /controller 节点有变,Broker-1 就会被通知。
3、第三个节点 Broker-2 启动,注册到 Zookeeper,遭遇与 Broker-1 一样,Broker-2 也在 /controller 节点创建一个 Watch。
此时,由 Broker-0、Broker-1、Broker-2 三个节点共同组成的集群正常运行,控制器是 Broker-0。
4、某天,Broker-0 节点突发故障,宕机了,Broker-0 节点对应的临时节点 /controller 及 /brokers/ids/0 都会被删除
而 /controller 上的 Watch 则会被触发,Broker-1、Broker-2 两个节点开始竞争成为控制器
经过一番激烈的竞争,最终,Broker-2 胜出,Broker-1 只能在 /controller 节点重新创建一个 Watch,再次进入等待。
此时,由 Broker-1、Broker-2 两个节点组成的集群正常运行,控制器是 Broker-2。
5、经过运维人员一番操作,Broker-0 恢复了,重新启动,加入集群,同第二步、第三步一样,Broker-0 也尝试创建 /controller 节点,结果创建失败,于是在 /controller 节点创建一个 Watch,等待现任控制器 Broker-2 下台。



