Kafka集群架构(ZK + Kafka)
本文为个人学习笔记整理,仅供交流参考,非专业教学资料,内容请自行甄别。
文章目录
- 概述:如何理解Kafka集群架构
- 复制因子
- 副本分布规则
- 角色分工
- 一、Kafka集群搭建
- 1.1、搭建集群
- 1.2、创建Topic
- 1.3、查看Topic详情
- 1.4、发送接收消息
- 总结
- 核心误区再强调
概述:如何理解Kafka集群架构
Kafka的集群,和ZK, MySQL等传统主从架构的集群,是有所区别的。从宏观来看,整体的系统架构应该是包含了生产者、消费者、Kafka集群三大部分,其中消费者,是以消费者组的形式存在的,一个消费者组可以有多个消费者,但是同一个消费者,不能存在于多个消费者组中,这一块在上一篇中已经有所提及。
而在Kafka的集群中,也可以分为以下的角色:
- Broker:可以理解成具体的服务实例。是运行在部署了Kafka的不同虚拟机上的,一台虚拟机上也可以部署多个 Broker 进程(只要端口、存储目录不冲突)。
- Topic:同样是一个逻辑概念,一个Broker中可以有多个Topic。不同的Topic之间是隔离的。
- Partition:是Topic中存储数据的核心单元,同一个Topic中可以包含多个Partition,Partition中的数据也是隔离的。
以上的三个角色,是和单体架构下是一致的。集群和单体架构的区别,主要体现在Partition的具体实现上,集群架构下的Partition,支持多副本(复制因子≥2),副本会尽量分布在不同 Broker 上,通过 leader/follower 机制实现数据高可用和请求负载均衡。
复制因子
这里又引入了一个复制因子的概念,复制因子是在创建Topic时显式指定的,也可以在配置文件中进行配置,但是显式指定的优先级,要高于配置文件的优先级。

复制因子的含义是,每个 Partition 在集群中有 复制因子 个副本。如上图,假设目前集群中有3台机器。
- 复制因子(replication factor)= 2 → 每个 partition 有 2 个副本(1 个 leader + 1 个 follower)。
- 总 partition 数 = 4 → 总副本数 = 4×2=8 个,这 8 个副本会均匀分布在 3 个 broker 上(Kafka 的默认分配策略)。
副本分布规则
同一 partition 的 2 个副本(leader 和 follower)必须放在不同的 broker 上,这一块可以列表说明一下:
| partition 编号 | leader 所在 broker | follower 所在 broker |
|---|---|---|
| p0 | broker0 | broker1 |
| p1 | broker1 | broker2 |
| p2 | broker2 | broker0 |
| p3 | broker0 | broker2 |
角色分工
leader副本,主要用于处理该Partition 的读写请求,客户端拉取数据,服务器写入数据,都是找该Partition 的leader节点。follower 副本,仅仅是用于同步leader副本的数据,不处理读写请求,当leader宕机时,进行选举成为新的leader。这里的选举,可以是通过外部挂载的ZK集群,也可以是新版Kafka的KRAFT进行。
一、Kafka集群搭建
1.1、搭建集群
首先同样需要准备三台虚拟机,这里需要利用到ZK,所以需要先搭建一个ZK的集群。搭建ZK集群。
三台虚拟机上都安装Kafka,首先在Kafka的根目录下,创建一个data文件夹,用于持久化数据

修改server.properties配置文件:
# 1. Broker 唯一标识(三台必须不同:0、1、2)
broker.id=0# 2. 监听地址(本机 IP:端口,默认 9092,必须写本机真实 IP,否则跨服务器连不上)
listeners=PLAINTEXT://本机:9092# 3. 数据存储目录(对应之前创建的目录)
log.dirs=/usr/local/kafka/data# 4. ZK 集群地址(指定你的 ZK 集群,末尾加 /kafka 是为了在 ZK 中隔离 Kafka 数据,避免冲突)
zookeeper.connect=服务器1:2181,服务器2:2181,服务器3:2181/kafka# 5. 其他优化配置(可选,建议添加)
num.partitions=3 # 创建 Topic 时默认分区数(与 Broker 数一致,负载均衡)
default.replication.factor=2 # 默认复制因子(2 份副本,高可用)
log.retention.hours=72 # 日志保留时间(3 天,可自定义)
message.max.bytes=1048576 # 单条消息最大大小(1MB,默认即可)
先启动ZK集群,然后启动Kafka集群:

# 进入 Kafka 安装目录
# 后台启动 Kafka(-daemon 表示后台运行)
bin/kafka-server-start.sh -daemon config/server.properties
通过jps命令验证是否三台服务器都启动完成:

1.2、创建Topic
在任意一台服务器,执行集群相关的操作,同样是首先创建一个Topic:
bin/kafka-topics.sh --create \
--topic test-cluster-topic \
--partitions 3 \
--replication-factor 2 \
--bootstrap-server 服务器1:9092,服务器2:9092,服务器3:9092

1.3、查看Topic详情
bin/kafka-topics.sh --describe \
--topic test-cluster-topic \
--bootstrap-server 192.168.198.128:9092
会输出以下的信息。

代表了:
- Leader: 0 → 该分区的读写请求由 broker.id=0(192.168.198.128)处理;
- Replicas: 0,2 → 该分区的副本组包含 2 个副本(复制因子 = 2),分别存储在 broker0(128) 和 broker2(131) 上(0 是 Leader,2 是Follower);
- Isr: 0,2 → 副本组中 2 个副本都与 Leader 完全同步(无数据延迟),同步状态正常。
1.4、发送接收消息
在其中一台服务器上启动生产者,发送消息
bin/kafka-console-producer.sh \
--topic test-cluster-topic \
--bootstrap-server 服务器Ip:9092

在另一台服务器上启动消费者脚本,接收消息:
bin/kafka-console-consumer.sh --topic test-cluster-topic --from-beginning --bootstrap-server 服务器Ip:9092

如果需要停止Kafka集群,直接运行bin/kafka-server-stop.sh即可。
总结
- 生产者发送消息到 topic(逻辑数据容器),topic 的物理数据拆分为多个 partition,每个 partition 有 N 个副本(N = 复制因子),副本会尽量分布在不同 broker 上,避免单点故障;
- 每个 partition 的副本组中,仅 1 个副本作为 leader,负责处理该 partition 的所有读写请求(生产者写、消费者读都直接访问 leader);follower 副本仅后台同步 leader 的数据,保持数据一致,当 leader 宕机时,会从 follower 中选举新 leader;
- 消费者按「消费者组」划分消费范围:同一消费者组内的消费者实例共享 topic 的消费权限(但各自消费topic的不同 partition,避免重复),不同消费者组可独立消费 topic 的全量消息(互不干扰);
- 消费模式为「消费者主动拉取」:消费者实例向对应 partition 的 leader 发起 pull 请求,leader 查询该消费者组的 offset(存储在__consumer_offsets 主题),返回 “从 offset 之后未消费的消息”;
- 同一消费者组内,Kafka 会通过「消费分配策略」建立「1 个 partition ↔ 1 个消费者实例」的绑定关系(同一消费者组内,1 个消费者实例(Consumer Instance)可以绑定多个 partition,但 1 个 partition 不能绑定多个同组消费者),实现负载均衡;
- leader 选举的协调者:老版本依赖 Zookeeper,新版本(KRaft 模式)由集群选举的 Controller Broker 负责,无需 Zookeeper。
核心误区再强调
- 消费模式:永远是「消费者拉取(poll)」,无主动推送;
- offset 存储:新版本在「__consumer_offsets 主题」,不在 ZK / 单个 broker;
- 选举协调:新版本用 Controller Broker,KRaft 模式已弃用 ZK,但是依然可以用户自己启动ZK集群。
- 消费者组与副本:不是 “共享副本”,而是 “共享 topic 数据源,独立消费进度”。
