- 作者:老汪软件技巧
- 发表时间:2024-09-26 15:01
- 浏览量:
简述
Kafka 官方支持两种服务端架构的部署,一种是 Zookeeper + Controller,第二种是 Kraft + Controller。两种架构主要区别是 Kafka 的元数据的管理方式不一样。想必大家对第一种架构 Zookeeper + Controller 肯定已经很熟悉了,这种架构在生产环境中是经常使用的,但是第二种 Kraft + Controller 架构模式用的还是比较少的 。
这两种服务端架构的主要区别在于元数据的存储方式不同。ZooKeeper + Controller 会把元数据保存在 外部组件 Zookeeper里。
而 Kraft + Controller 是把元数据仅仅保存 Kafka 服务端 Controller Broker 里,通过 Kraft 分布式算法来保证元数据的一致性和可用性。
Kafka官方为什么会提供两种服务端架构呢?
之所以出现 第二种架构 Kraft + Controller 是因为 第一种架构 Zookeeper + Controller 在生产环境出现了一些问题,而且必须通过架构层面的迭代才能解决,也就是说通过代码的优化已经无法克服 Zookeeper + Controller 架构带来的问题。按照 Kafka 官方最终的路线图是要把 ZooKeeper + Controller 淘汰掉,换成 Kraft + Controller,但是现在替换的时机并不是非常的成熟,需要一定时间的过度。
总体架构
大家可以看到 Zookeeper + Controller 架构模式的总体架构图,在这种架构下主要有三种节点。
一种节点是 Zookeeper 集群, 它的目的主要是保存 Kafka 的元数据。先给大家简单介绍一下 Kafka 元数据,元数据里面主要有哪些数据呢?主要包括两部分:第二种节点 Controller broker节点,除了 Zookeeper 用来保存 Kafka 元数据之外, Controller broker 也是来用来保存 Kafka 元数据的。 Controller Broker 这个角色主要是作为 Kafka 服务端集群的一个总控节点,它的目的一方面是来保存元数据。第二方面可以去执行一些命令,比如说新建主题、删除主题等,都可以通过这个节点来去给 Kafka 集群发号施令,也就是它是一个总控节点,而其它的 broker 节点就是常规的 broker 节点了。第三种节点就是常规 broker 节点。 常规 broker 节点不仅用来保存消息数据,同时也会保存一份元数据。当然 Controller 节点同时也可以是保存消息数据。
我们在看一下架构图,由架构图中,大家可以看到所有的节点都会保存元数据的。如果元数据发生了变化,元数据在各个节点是如何变化的呢?首先,Controller Broker会第一时间修改元数据,把修改后的元数据保存在 Controller Broker 的内存中,然后会把修改后元数据同步到 Zookeeper 中,最后其他的 broker 会主动的向 Controller Broker 节点去拉取最新的元数据,然后保存在broker 节点各自的内存中,也就是说所有的节点都会用来保存Kafka的元数据的。
这里会有一个问题,为什么会保存多份元数据?
首先,在生产环境中,Zookeeper 可能会管理多个 Kafka 集群,在生产环境中所有的客户端如果都去请求 Zookeeper 集群来获取元数据,势必会给Zookeeper 造成很多地 压力,并会造成不同 Kafka 集群间的相互影响。
一个 Kafka 集群会有一个 Controller Broker 节点,负责把元数据的变化同步到 Zookeeper 集群,这样Zookeeper 集群就成为了元数据的备份节点,如果当前 Controller Broker 节点挂了,新的Controller Broker 节点起来的时候,会从 Zookeeper 集群读取最新的元数据。
Controller Broker 把元数据同步到常规broker节点。常规的 Kafka broker 节点会从 Controller Broker 节点中拉取最新的元数据。也就是说所有的broker节点都会保存元数据。
客户端可以从所有 broker 节点获取元数据。也就是说,客户端可以随机的从任意 broker 节点获取元数据,这样可以将元数据请求打散,从而大大减轻获取元数据的请求对服务端单点的压力。
两个示例
接下来给大家举两个例子来更好地说明 Zookeeper + Controller 架构的工作模式。第一个例子是 Zookeeper + Controller 架构中的生产者创建主题的过程。
Zookeeper + Controller 架构中的生产者创建主题的过程
大家可以看到这幅图里有三个 broker 节点,其中的一个 broker 节点被选为Controller。生产者要新创建一个主题。我们知道在 Kafka 默认生产者是可以创建主题的。当然了,在生产环境中最好不要给予生产者自由创建主题的这种权限,这样对生产环境是不友好的,但是这里为了更好的说明架构的工作模式,就暂且把权限放开。
第一步,是生产者获取元数据。生产者会从 Brook 集群中随机的去选取一个 Broker 节点向它发送获取元数据的请求,然后会从元数据中会得到 Controller Broker的位置。
第二步,生产者得到 Controller broker 节点位置之后,向 Controller broker 节点发送创建主题分区的请求。
第三步,Controller Broker 收到创建主题请求之后, Controller Broker 会把主题分区任务发送给另外的两个broker。比如说一个主题 A 下面有 2 个partition,那么会把创建 partition 的任务下发到两个常规的 broker 节点里。
第四步, Controller Broker 创建主题任务成功之后,会把主题分区的信息同步到 zookeeper 里面。
第五步,Controller Broker向生产者返回主题创建的结果,是成功还是失败,这样就完成了一个主题的创建。
这里需要大家注意几点:
ZK + Controller 架构生产者发送消息的过程
第二个例子是 ZK 加 Controller 架构生产者发送消息的过程。这个例子的背景是什么呢?就是说我们新起来一个生产者 producer 的时候,producer 要向一个已存在的主题 topic A 发送消息,那么它是一个怎么样的一个流程?这个就比前面一个示例就简单了一些。
第一步,producer 首先会随机的向某一个 broker 发送获取元数据。
第二步,producer 从返回的元数据拿到主题 topic A 的路由信息之后,向 topic A 的 partition leader所在broker 发送消息,也就是向 topic A 的 partition 1 的 leader 所在的节点 broker 2 发送消息。
同样的也有几个要点。