集群的成员关系
集群的成员关系
Kafka 使用 zookeeper 来维护集群成员的信息。每个 broker 都有个唯一标识符, 这个标识符可以在配置文件里指定, 也可以自动生成。 在 broker 启 动的时候, 它通过创建临时节点把自己的 ID 注册到 zoo-keeper。 Kafka 组件订阅 Zookeeper 的/brokers/ids 路径(broker 在 zookeeper 上的注册路径) , 当 有 broker 加入集群或退出集群时, 这些组件就可以获得通知 。
如果你要启动另一个具有相同 ID 的 broker, 会得到一个错误。新 broker 会试着进行注册,但不会成功, 因为 zookeeper 里已经有一个具有相同 ID 的 broker。
在broker 停机、 出现网络分区或长时间垃圾回收停顿时, broker 会从 Zookeeper 上断开连接, 此时 broker 在启动时创建的临时节点会自动从 Zookeeper 上移除。 监听 broker 列表的 Kafka 组件会被告知该 broker 已移除。
在关闭broker 时, 它对应的节点也会消失, 不过它的 ID 会继续存在于其他数据结构中。 例如,主题的副本列表里就可能包含这些 ID。在完全关闭一 个 broker 之后, 如果使用相同的 ID 启动另一个全新的 broker, 它会立刻加入集群, 并拥有与旧 broker 相同的分区和主题
什么是控制器
控制器其实就是一个 broker, 只不过它除了具有一般 broker 的功能之外, 还负责分区首领的选举。 集群里第一个启动的 broker 通过在 Zookeeper 里创建一个临时节点/controuer 让自己成为控制器。 其他 broker 在启动时也会尝试创建这个节点,不过它们会收到一个“节点已存在”的异常,然后“意 识”到控制器节点已存在, 也就是说集群里已经有一个控制器了 。 其他 broker 在控制器节点上创建 Zookeeperwatch 对象,这样它们就可以收到这个节点 的变更通知。这种方式可以确保集群里一次只有一个控制器存在。
如果控制器被关闭或者与 Zookeeper 断开连接, zookeeper 上的临时节点就会消失。 集群里的其他 broker 通过 watch 对象得到控制器节点消失的通 知, 它们会尝试让自己成为新的控制器。 第一个在 Zookeeper 里成功创建控制器节点的 broker 就会成为新的控制器, 其他节点会收到“节点已存在”的 异常,然后在新的控制器节点上再次创建 watch 对象。
当控制器发现一个 broker 已经离开集群,它就知道,那些失去首领的分区需要一个新首领 (这些分区的首领刚好是在这个 broker 上)。 控制器遍历这 些分区, 并确定谁应该成为新首领 (简单来说就是分区副本列表里的下一个副本) , 然后向所有包含新首领或现有跟随者的 broker 发送请求。该请求消息 包含了谁是新首领以及谁是分区跟随者的信息。随后,新首领开始处理来自生产者和消费者的情求,而跟随者开始从新首领那里复制消息。
当控制器发现一个 broker 加入集群时, 它会使用 broker ID 来检査新加入的 broker 是否包含现有分区的副本。 如果有, 控制器就把变更通知发送给 新加入的 broker 和其他 broker, 新 broker 上的副本开始从首领那里复制消息。
简而言之, Kafka 使用 Zookeeper 的临时节点来选举控制器,并在节点加入集群或退出集群时通知控制器。控制器负责在节点加入或离开集群时进行分 区首领选举。