3.6、Zookeeper 在 Kafka 中的作用

本文概述了Zookeeper在Kafka中的关键作用,包括Controller的角色、Broker与Topic的注册、分区管理、负载均衡以及选举流程。通过理解这些,读者能深入理解Kafka的分布式架构和协调机制。

kafka学习目录:kafka目录


3.6、Zookeeper 在 Kafka 中的作用

zk相当于是kafka的一个基础设施,了解zk在kafka中的作用,可以对kafka的原理有进一步的了解。

首先从controller看起,这是zk中一个重要的组成:Controller 作为 Kafka Server端一个重要的组件,它的角色类似于其他分布式系统Master的角色,跟其他系统不一样的是,Kafka集群的任何一台Broker都可以作为Controller,但是在一个集群中同时只会有一个 Controller是alive状态。在于分布式系统中,总会有一个地方需要对全局 meta 做一个统一的维护,Kafka 的 Controller 就是充当这个角色的。Controller 是运行在 Broker 上的,任何一台 Broker 都可以作为 Controller,但是一个集群同时只能存在一个 Controller,也就意味着 Controller 与数据节点是在一起的,Controller 做的主要事情如下:

  • Broker 的上线、下线处理;
  • 新创建的 topic 或已有 topic 的分区扩容,处理分区副本的分配、leader 选举;
  • 管理所有副本的状态机和分区的状态机,处理状态机的变化事件;
  • topic 删除、副本迁移、leader 切换等处理。

Broker在启动时,会尝试去ZK创建/controller节点,第一个成功创建/controller节点的Broker会被指定为为控制器。了解了controller之后,通过一个图看在controller在zk整体中的情况:

在这里插入图片描述

controller就是zk中的一个节点,谁创建成功了谁就成为控制器,除此之外,还有其他作用:

  • Broker注册:Broker在zookeeper中保存为一个临时节点,节点的路径是/brokers/ids/[brokerid],每个节点会保存对应broker的IP以及端口等信息.

  • Topic注册:在kafka中,一个topic会被分成多个区并被分到多个broker上,分区的信息以及broker的分布情况都保存在zookeeper中,根节点路径为/brokers/topics,每个topic都会在topics下建立独立的子节点,每个topic节点下都会包含分区以及broker的对应信息

  • partition状态信息:/brokers/topics/[topic]/partitions/[0…N] 其中[0…N]表示partition索引号

  • Controller epoch:此值为一个数字,kafka集群中第一个broker第一次启动时为1,以后只要集群中center controller中央控制器所在broker变更或挂掉,就会重新选举新的center controller,每次center controller变更controller_epoch值就会 + 1;

  • Controller注册信息:存储center controller中央控制器所在kafka broker的信息

  • 生产者负载均衡:当Broker启动时,会注册该Broker的信息,以及可订阅的topic信息。生产者通过注册在Broker以及Topic上的watcher动态的感知Broker以及Topic的分区情况,从而将Topic的分区动态的分配到broker上.

  • 消费者:kafka有消费者分组的概念,每个分组中可以包含多个消费者,每条消息只会发给分组中的一个消费者,且每个分组之间是相互独立互不影响的。Consumer注册信息:
    每个consumer都有一个唯一的ID(consumerId可以通过配置文件指定,也可以由系统生成),此id用来标记消费者信息./consumers/[groupId]/ids/[consumerIdString]是一个临时的znode,此节点的值为请看consumerIdString产生规则,即表示此consumer目前所消费的topic + partitions列表.

  • 消费者与分区的对应关系:对于每个消费者分组,kafka都会为其分配一个全局唯一的Group ID,分组内的所有消费者会共享该ID,kafka还会为每个消费者分配一个consumer ID,通常采用hostname:uuid的形式。在kafka的设计中规定,对于topic的每个分区,最多只能被一个消费者进行消费,也就是消费者与分区的关系是一对多的关系。消费者与分区的关系也被存储在zookeeper中节点的路劲为 /consumers/[group_id]/owners/[topic]/[broker_id-partition_id],该节点的内容就是消费者的Consumer ID

  • 消费者负载均衡:消费者服务启动时,会创建一个属于消费者节点的临时节点,节点的路径为 /consumers/[group_id]/ids/[consumer_id],该节点的内容是该消费者订阅的Topic信息。每个消费者会对/consumers/[group_id]/ids节点注册Watcher监听器,一旦消费者的数量增加或减少就会触发消费者的负载均衡。消费者还会对/brokers/ids/[brokerid]节点进行监听,如果发现服务器的Broker服务器列表发生变化,也会进行消费者的负载均衡

参考:

Kafka 源码解析之 Controller 选举及服务启动流程(十六)

Kafka – 控制器 | All In Infra (zhongmingmao.me)

Kafka Controller | 隔壁老王的Blog (gebilaowang.info)

apache kafka系列之在zookeeper中存储结构_李志涛的专栏-优快云博客_zookeeper存储结构

【zookeeper在kafka中的作用】 - ITeye博客




Kafka 集群中有一个 broker 会被选举为 Controller,负责管理集群 broker 的上下线,所有 topic 的分区副本分配leader 选举等工作。

Reference

Controller 的管理工作都是依赖于 Zookeeper 的。

  • Controller 的选举是,每个broker 都会监控当前Controller 是否挂掉,哪一个broker看到Controller挂掉了,就自己上位。

以下为 partition 的 leader 选举过程:

Leader选举流程

在 Kubernetes (k8s) 上部署 ZooKeeperKafka 以实现高可用性架构,通常需要考虑以下几个关键点:服务发现、持久化存储、副本机制以及合理的资源配置。以下是详细的部署方案: ### 部署架构设计 - **ZooKeeper**:作为 Kafka 的协调服务,ZooKeeper 通常部署为一个奇数节点的集群(如 3 或 5 节点),以实现高可用性和一致性。 - **Kafka**:Kafka 也部署为多副本集群,每个 Kafka Broker 对应一个独立的 Pod,并通过 StatefulSet 管理,以确保稳定的网络标识和持久化存储。 ### 使用 StatefulSet 进行部署 相较于 Deployment,StatefulSet 更适合有状态应用的部署,因为它可以确保每个 Pod 具有唯一的、稳定的网络标识和存储卷[^1]。 #### 1. ZooKeeper 集群部署 ZooKeeper 集群建议使用 StatefulSet 来部署,并结合 Headless Service 实现服务发现: ```yaml apiVersion: v1 kind: Service metadata: name: zk-headless spec: clusterIP: None ports: - port: 2181 name: client - port: 2888 name: server - port: 3888 name: leader-election selector: app: zookeeper --- apiVersion: apps/v1 kind: StatefulSet metadata: name: zk spec: serviceName: zk-headless replicas: 3 selector: matchLabels: app: zookeeper template: metadata: labels: app: zookeeper spec: containers: - name: zookeeper image: zookeeper:3.6 ports: - containerPort: 2181 name: client - containerPort: 2888 name: server - containerPort: 3888 name: leader-election env: - name: ZOO_SERVERS value: | server.1=zk-0.zk-headless.default.svc.cluster.local:2888:3888 server.2=zk-1.zk-headless.default.svc.cluster.local:2888:3888 server.3=zk-2.zk-headless.default.svc.cluster.local:2888:3888 volumeMounts: - name: data mountPath: /data - name: conf mountPath: /conf volumes: - name: conf configMap: name: zookeeper-config volumeClaimTemplates: - metadata: name: data spec: accessModes: [ "ReadWriteOnce" ] resources: requests: storage: 10Gi ``` 每个 ZooKeeper Pod 会使用 PVC 挂载持久化存储,确保数据持久性。 #### 2. Kafka 集群部署 Kafka 通常部署为一个 StatefulSet,每个 Broker 对应一个 Pod,并通过 Headless Service 实现服务发现: ```yaml apiVersion: v1 kind: Service metadata: name: kafka-headless spec: clusterIP: None ports: - port: 9092 name: server selector: app: kafka --- apiVersion: apps/v1 kind: StatefulSet metadata: name: kafka spec: serviceName: kafka-headless replicas: 3 selector: matchLabels: app: kafka template: metadata: labels: app: kafka spec: containers: - name: kafka image: bitnami/kafka:latest ports: - containerPort: 9092 name: server env: - name: KAFKA_CFG_PROCESS_ROLES value: "broker" - name: KAFKA_CFG_CONTROLLER_LISTENER_NAMES value: "CONTROLLER" - name: KAFKA_CFG_LISTENERS value: "CONTROLLER://:19091,PLAINTEXT://:9092" - name: KAFKA_CFG_ADVERTISED_LISTENERS value: "PLAINTEXT://kafka-0.kafka-headless.default.svc.cluster.local:9092" - name: KAFKA_CFG_ZOOKEEPER_CONNECT value: "zk-0.zk-headless.default.svc.cluster.local:2181,zk-1.zk-headless.default.svc.cluster.local:2181,zk-2.zk-headless.default.svc.cluster.local:2181" volumeMounts: - name: data mountPath: /bitnami/kafka volumes: - name: config configMap: name: kafka-config volumeClaimTemplates: - metadata: name: data spec: accessModes: [ "ReadWriteOnce" ] resources: requests: storage: 20Gi ``` Kafka 的每个 Pod 通过 PVC 挂载持久化卷,确保消息数据不会丢失。 ### 高可用配置要点 - **ZooKeeper 集群**:至少部署 3 个节点以实现高可用性和故障转移。 - **Kafka 集群**:建议至少部署 3 个 Broker,确保数据副本机制有效。 - **持久化存储**:使用 PVC 挂载持久卷,防止 Pod 重启导致数据丢失。 - **服务发现**:通过 Headless Service 为每个 Pod 提供稳定的 DNS 名称。 - **配置一致性**:确保 Kafka Broker 正确连接到 ZooKeeper 集群地址。 ### 数据管理与协调 ZooKeeperKafka 中的作用包括集群元数据管理、领导者选举、生产者与消费者的协调等[^2]。它还支持多种分布式协调功能,例如负载均衡、命名服务、分布式锁和队列等[^3]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

悬浮海

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值