「Kafka」核心概念必知必会(四)
一、集群启动流程
1. 代理:Broker
使用Kafka前,我们都会启动Kafka服务进程,这里的Kafka服务进程我们一般会称之为Kafka Broker
或Kafka Server
。因为Kafka是分布式消息系统,所以在实际的生产环境中,是需要多个服务进程形成集群提供消息服务的。所以每一个服务节点都是一个broker,而且在Kafka集群中,为了区分不同的服务节点,每一个broker都应该有一个不重复的全局ID,称之为broker.id
,这个ID可以在kafka软件的配置文件server.properties
中进行配置
############################# Server Basics #############################
# The id of the broker. This must be set to a unique integer for each broker
# 集群ID
broker.id=0
主机 | kafka-broker1 | kafka-broker2 | kafka-broker3 |
---|---|---|---|
broker.id | 1 | 2 | 3 |
2. 控制器:Controller
Kafka
是分布式消息传输系统,所以存在多个Broker服务节点,但是它的软件架构采用的是分布式系统中比较常见的主从(Master - Slave)
架构,也就是说需要从多个Broker中找到一个用于管理整个Kafka集群的Master节点
,这个节点,我们就称之为Controller
。它是Apache Kafka
的核心组件非常重要。它的主要作用是在Apache Zookeeper的帮助下管理和协调控制整个Kafka集群
。
如果在运行过程中,Controller节点出现了故障,
那么Kafka会依托于ZooKeeper软件选举其他的节点作为新的Controller,让Kafka集群实现高可用
。
二、Controller的基本功能
1. Broker管理
- 监听 /brokers/ids节点相关的变化:
- Broker数量增加或减少的变化
- Broker对应的数据变化
2. Topic管理
- 新增:监听 /brokers/topics节点相关的变化
- 修改:监听 /brokers/topics节点相关的变化
- 删除:监听 /admin/delete_topics节点相关的变化
3. Partation管理
- 监听 /admin/reassign_partitions节点相关的变化
- 监听 /isr_change_notification节点相关的变化
- 监听 /preferred_replica_election节点相关的变化
4. 数据服务
5. 启动分区状态机和副本状态机
三、 启动ZooKeeper
Kafka集群中含有多个服务节点,而分布式系统中经典的主从(Master - Slave)
架构就要求从多个服务节点中找一个节点作为集群管理Master,Kafka集群中的这个Master,我们称之为集群控制器Controller
如果此时Controller节点出现故障,它就不能再管理集群功能,那么其他的Slave节点该如何是好呢?
如果从剩余的2个Slave节点中选一个节点出来作为新的集群控制器是不是一个不错的方案,我们将这个选择的过程称之为:选举(elect)
。方案是不错,但是问题就在于选哪一个Slave节点呢?不同的软件实现类似的选举功能都会有一些选举算法,而Kafka是依赖于ZooKeeper软件实现Broker节点选举功能。
四、ZooKeeper如何实现Kafka的节点选举
这就要说到我们用到ZooKeeper的3个功能
:
- 一个是在ZooKeeper软件中创建节点Node,创建一个Node时,我们会设定这个节点是持久化创建,还是临时创建。所谓的持久化创建,就是Node一旦创建后会一直存在,而临时创建,是根据当前的客户端连接创建的临时节点Node,一旦客户端连接断开,那么这个临时节点Node也会被自动删除,所以这样的节点称之为临时节点。
- ZooKeeper节点是不允许有重复的,所以多个客户端创建同一个节点,只能有一个创建成功。
- 另外一个是客户端可以在ZooKeeper的节点上增加监听器,用于监听节点的状态变化,一旦监听的节点状态发生变化,那么监听器就会触发响应,实现特定监听功能。
有了上面的三个知识点,我们这里就介绍一下Kafka是如何利用ZooKeeper实现Controller节点的选举的:
- 第一次启动Kafka集群时,会同时启动多个Broker节点,每一个Broker节点就会连接ZooKeeper,并尝试创建一个临时节点 /controller
- 因为ZooKeeper中一个节点不允许重复创建,所以多个Broker节点,最终只能有一个Broker节点可以创建成功,那么这个创建成功的Broker节点就会自动作为Kafka集群控制器节点,用于管理整个Kafka集群。
- 没有选举成功的其他Slave节点会创建Node监听器,用于监听 /controller节点的状态变化。
- 一旦Controller节点出现故障或挂掉了,那么对应的ZooKeeper客户端连接就会中断。ZooKeeper中的 /controller 节点就会自动被删除,而其他的那些Slave节点因为增加了监听器,所以当监听到 /controller 节点被删除后,就会马上向ZooKeeper发出创建 /controller 节点的请求,一旦创建成功,那么该Broker就变成了新的Controller节点了。
现在我们能明白启动Kafka集群之前,为什么要先启动ZooKeeper集群了吧。就是因为ZooKeeper可以协助Kafka进行集群管理。
五、 启动Kafka
ZooKeeper已经启动好了,那我们现在可以启动多个Kafka Broker节点构建Kafka集群
了。构建的过程中,每一个Broker节点就是一个Java进程
,而在这个进程中,有很多需要提前准备好,并进行初始化的内部组件对象。
1. 初始化ZooKeeper
Kafka Broker启动时,首先会先创建ZooKeeper客户端(KafkaZkClient)
,用于和ZooKeeper进行交互
。客户端对象创建完成后,会通过该客户端对象向ZooKeeper发送创建Node的请求,注意,这里创建的Node都是持久化Node。
2. 初始化服务
2.1 初始化服务
Kafka Broker中有很多的服务对象,用于实现内部管理和外部通信操作
。
2.1 启动任务调度器
每一个Broker在启动时都会创建内部调度器(KafkaScheduler)
并启动,用于完成节点内部的工作任务。底层就是Java中的定时任务线程池ScheduledThreadPoolExecutor
2.2 创建数据管理器
每一个Broker在启动时都会创建数据管理器(LogManager)
,用于接收到消息后,完成后续的数据创建,查询,清理等处理。
2.3 创建远程数据管理器
每一个Broker在启动时都会创建远程数据管理器(RemoteLogManager)
,用于和其他Broker节点进行数据状态同步。
2.4 创建副本管理器
每一个Broker在启动时都会创建副本管理器(ReplicaManager)
,用于对主题的副本进行处理。
2.5 创建ZK元数据缓存
每一个Broker在启动时会将ZK的关于Kafka的元数据进行缓存,创建元数据对象(ZkMetadataCache)
2.6 创建Broker通信对象
每一个Broker在启动时会创建Broker之间的通道管理器对象(BrokerToControllerChannelManager)
,用于管理Broker和Controller之间的通信。
2.7 创建网络通信对象
每一个Broker在启动时会创建自己的网络通信对象(SocketServer)
,用于和其他Broker之间的进行通信,其中包含了Java用于NIO通信的Channel、Selector对象。
2.8 注册Broker节点
Broker启动时,会通过ZK客户端对象向ZK注册当前的Broker 节点ID
,注册后创捷的ZK节点为临时节点。如果当前Broker的ZK客户端断开和ZK的连接,注册的节点会被删除。
3. 启动控制器
控制器(KafkaController)
是每一个Broker启动时都会创建的核心对象,用于和ZK之间建立连接并申请自己为整个Kafka集群的Master管理者
。如果申请成功
,那么会完成管理者的初始化操作,并建立和其他Broker之间的数据通道接收各种事件,进行封装后交给事件管理器,并定义了process方法,用于真正处理各类事件。
3.1 初始化通道管理器
创建通道管理器(ControllerChannelManager)
,该管理器维护了Controller和集群所有Broker节点之间的网络连接,并向Broker发送控制类请求及接收响应。
3.1 初始化事件管理器
创建事件管理器(ControllerEventManager)
维护了Controller和集群所有Broker节点之间的网络连接,并向Broker发送控制类请求及接收响应。
3.1 初始化状态管理器
创建状态管理器(ControllerChangeHandler)
可以监听 /controller 节点的操作,一旦节点创建(ControllerChange),删除(Reelect),数据发生变化(ControllerChange),那么监听后执行相应的处理。
3.1 启动控制器
控制器对象启动后,会向事件管理器发送Startup事件,事件处理线程接收到事件后会通过ZK客户端向ZK申请 /controller 节点,申请成功后,执行当前节点成为Controller的一些列操作。主要是注册各类 ZooKeeper 监听器、删除日志路径变更和 ISR 副本变更通知事件、启动 Controller 通道管理器,以及启动副本状态机和分区状态机。