Kafka 核心概念与集群部署:Topic、Partition、Broker、Producer、Consumer
好,咱们正式开始啃 Kafka 这块硬骨头。这一章我打算把 Kafka 最核心的概念讲透,再带你把单机和集群都跑起来。你想想看,如果连 Broker、Topic、Partition 这些词都搞不清楚,后面写 Flink 作业肯定要踩坑。
2.1 五个核心概念,一个都不能少
Kafka 说白了就是一个「消息」。生产者往里扔消息,消费者从里面取消息。但中间这层怎么组织,全靠下面这五个角色。
| 概念 | 一句话解释 | 我见过的坑 |
|---|---|---|
| Broker | Kafka 服务器节点,一个进程就是一个 Broker | 有人把 Broker 和 Topic 搞混,其实 Broker 是跑程序的机器 |
| Topic | 消息的逻辑分类,好比数据库里的表 | Topic 命名不规范,后期运维想哭 |
| Partition | Topic 的分片,每个 Partition 是一个有序日志 | Partition 数设太多,文件句柄爆过 |
| Producer | 发送消息的客户端 | 没配 acks,丢消息都不知道 |
| Consumer | 拉取消息的客户端 | 消费组没规划好,重复消费严重 |
核心关系图:Producer 往 Topic 写消息,Topic 分成多个 Partition 分布在不同的 Broker 上,Consumer 从 Partition 拉数据。一个 Partition 只能被同一个消费组里的一个 Consumer 消费。
2.2 Topic 与 Partition 的底层逻辑
Topic 就是个标签。你发订单消息,Topic 就叫 order;发日志,就叫 app-log。但真正存数据的是 Partition。
每个 Partition 是一个追加写的日志文件,消息进来就往尾部追加。为什么 Kafka 快?顺序写磁盘,比随机写快几个数量级。我在项目里测过,机械盘顺序写都能跑到 100MB/s 以上。
Partition 还有个东西叫 Offset,就是消息在 Partition 里的位置编号。Consumer 消费时记住 Offset,下次从这继续读。嗯,这里要注意:Offset 不是全局唯一的,只在 Partition 内唯一。
我的习惯:Topic 的 Partition 数一般设成 Broker 数的整数倍。比如 3 台 Broker,Partition 设 6 或 9,这样负载最均匀。别设成质数,调度起来很别扭。
2.3 Producer 与 Consumer 的工作机制
Producer 发消息时,可以指定 key。Kafka 根据 key 的哈希值决定消息进哪个 Partition。不指定 key 就轮询。我建议业务消息都带 key,比如用订单 ID 做 key,这样同一个订单的消息永远进同一个 Partition,保证顺序。
Consumer 这边有个重要的概念——消费组(Consumer Group)。组内成员共同消费一个 Topic,每个 Partition 只能分配给组内的一个 Consumer。组多了,消息就能被广播给多个业务方。
举个例子:订单 Topic 有 6 个 Partition。你起一个消费组,里面 3 个 Consumer,每个 Consumer 分 2 个 Partition。再起另一个消费组,里面 2 个 Consumer,每个 Consumer 分 3 个 Partition。两组互不影响。
我曾经踩过的坑:Consumer 数量超过 Partition 数时,多出来的 Consumer 会空转,白白浪费资源。所以 Consumer 数最好小于等于 Partition 数。
2.4 单机部署实战
先别急着上集群,单机跑通再说。我习惯用 Docker 快速验证,但生产环境建议用二进制包。
# 下载 Kafka(里面自带 Zookeeper)
wget https://downloads.apache.org/kafka/3.5.0/kafka_2.13-3.5.0.tgz
tar -xzf kafka_2.13-3.5.0.tgz
cd kafka_2.13-3.5.0
# 启动 Zookeeper(单机测试用内置的就行)
bin/zookeeper-server-start.sh config/zookeeper.properties &
# 启动 Kafka Broker
bin/kafka-server-start.sh config/server.properties &
# 创建 Topic
bin/kafka-topics.sh --create --topic test-topic \
--bootstrap-server localhost:9092 \
--partitions 3 --replication-factor 1
# 查看 Topic 详情
bin/kafka-topics.sh --describe --topic test-topic \
--bootstrap-server localhost:9092
看到输出里有 PartitionCount: 3 就说明成功了。单机部署时 replication-factor 只能设 1,因为没有别的 Broker 可以同步数据。
2.5 集群部署实战
集群部署其实就是在多台机器上重复启动 Broker,然后让它们互相发现。我以 3 台机器为例,IP 分别是 192.168.1.10、192.168.1.11、192.168.1.12。
每台机器都要改 config/server.properties,关键参数如下:
| 参数 | Broker1 | Broker2 | Broker3 |
|---|---|---|---|
| broker.id | 1 | 2 | 3 |
| listeners | PLAINTEXT://192.168.1.10:9092 | PLAINTEXT://192.168.1.11:9092 | PLAINTEXT://192.168.1.12:9092 |
| log.dirs | /data/kafka/logs | /data/kafka/logs | /data/kafka/logs |
| zookeeper.connect | 192.168.1.10:2181,192.168.1.11:2181,192.168.1.12:2181 | 同上 | 同上 |
Zookeeper 也要搭集群,3 台机器各配一个。Zookeeper 的 myid 文件分别写 1、2、3,zoo.cfg 里加上所有节点地址。
# 在每台机器上启动 Zookeeper
bin/zkServer.sh start
# 在每台机器上启动 Kafka
bin/kafka-server-start.sh config/server.properties &
# 在任意一台机器上创建带副本的 Topic
bin/kafka-topics.sh --create --topic cluster-topic \
--bootstrap-server 192.168.1.10:9092 \
--partitions 6 --replication-factor 3
# 查看副本分布
bin/kafka-topics.sh --describe --topic cluster-topic \
--bootstrap-server 192.168.1.10:9092
输出里你会看到每个 Partition 有 3 个副本,分布在不同的 Broker 上。比如:
Topic: cluster-topic Partition: 0 Leader: 1 Replicas: 1,2,3 Isr: 1,2,3
Topic: cluster-topic Partition: 1 Leader: 2 Replicas: 2,3,1 Isr: 2,3,1
Leader 负责读写,Follower 负责同步。Leader 挂了,Controller 会从 ISR(In-Sync Replicas)里选一个新的 Leader。
我个人习惯:生产环境 replication-factor 至少设 2,关键 Topic 设 3。副本太多浪费磁盘,太少又怕丢数据。另外,ISR 里副本数少于 min.insync.replicas 时,Producer 写入会报错,这个参数要配合 acks=all 一起用。
2.6 集群架构总览
下面这张图把整个集群的流转关系画清楚了。你看一眼,后面写代码时脑子里就有画面了。
2.7 部署后的验证与常用命令
集群搭好了,怎么验证?我一般做三件事:
- 生产消费测试:开一个终端跑 Producer,另一个跑 Consumer,看消息能不能通。
- 故障模拟:手动 kill 一个 Broker,看 Leader 是否自动切换,Consumer 是否继续消费。
- 性能摸底:用 kafka-producer-perf-test.sh 和 kafka-consumer-perf-test.sh 压一下吞吐量。
# 生产测试
bin/kafka-console-producer.sh --topic cluster-topic \
--bootstrap-server 192.168.1.10:9092
# 消费测试
bin/kafka-console-consumer.sh --topic cluster-topic \
--bootstrap-server 192.168.1.10:9092 \
--from-beginning
# 查看消费组偏移量
bin/kafka-consumer-groups.sh --bootstrap-server 192.168.1.10:9092 \
--group my-group --describe
我曾经遇到过的生产事故:有一次集群 Broker 磁盘写满,Partition 变成 Offline 状态,整个 Topic 不可用。从那以后我养成了两个习惯:一是给 log.dirs 挂独立磁盘,二是配磁盘告警,使用率超过 80% 就报警。
好了,这一章的内容就到这。概念清楚了,集群也跑起来了,后面咱们就可以放心地往里面灌数据了。