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
下台。