2. Kafka 核心概念:Topic、Partition、Producer、Consumer、Broker、Zookeeper 角色解析
说实话,我刚接触 Kafka 那会儿,最头疼的就是这一堆概念。
什么 Topic、Partition、Broker……听着都像,但各自管什么事儿?
后来我带团队做第一个实时数仓项目,踩了不少坑,才把这些角色彻底理清楚。
今天咱们就把它们一个个拆开,讲明白。
2.1 Broker:Kafka 集群的“工人”
Broker 是 Kafka 集群里的服务器节点。
你可以把它理解成一个工人,负责存数据、收数据、发数据。
一个集群通常有 3 台或更多 Broker,组成一个工作小组。
核心要点:Broker 是无状态的,它不记录“谁消费过什么”。
消费进度由 Consumer 自己维护,或者交给 Kafka 内部的 __consumer_offsets 主题。
我遇到过一个问题:有同事把 Broker 当数据库用,以为数据会永久保留。
其实 Broker 只按配置的保留时间(比如 7 天)或大小来清理数据。
过期就删,别指望它帮你长期存档。
2.2 Topic:数据的“分类标签”
Topic 就是消息的分类名。
比如订单数据发到 order_topic,用户行为发到 user_behavior。
生产者往 Topic 里写,消费者从 Topic 里读。
Topic 本身不存数据,它只是一个逻辑概念。
真正存数据的是 Partition。
我的习惯:Topic 命名用“业务域_数据用途”格式。
比如 order_payment、user_login,一看就懂。
别用拼音,也别用无意义的数字编号,后期维护会疯掉。
2.3 Partition:真正的“数据容器”
Partition 是 Kafka 实现高吞吐的核心。
一个 Topic 可以分成多个 Partition,每个 Partition 是一个有序的、不可变的日志文件。
数据写入 Partition 时,会分配一个唯一的偏移量(Offset)。
消费者按 Offset 顺序读取,保证分区内有序。
注意:Kafka 只保证分区内有序,不保证跨分区有序。
如果你需要全局有序,只能用一个 Partition——但那样吞吐量就下来了。
我曾经在金融项目中为了全局有序牺牲了性能,后来发现业务根本不需要,白折腾了。
Partition 的数量直接影响并行度。
生产者可以同时往多个 Partition 写,消费者也可以同时从多个 Partition 读。
| Partition 数量 | 优点 | 缺点 |
|---|---|---|
| 少(1-3) | 管理简单,顺序性好 | 吞吐量低,扩展性差 |
| 多(10+) | 吞吐量高,并行度好 | 文件句柄多,重平衡慢 |
我建议:Topic 的 Partition 数设为 Broker 数的整数倍。
比如 3 台 Broker,设 6 或 9 个 Partition,负载更均匀。
2.4 Producer:数据的“写入者”
Producer 负责把消息发到指定的 Topic。
它可以选择把消息发到哪个 Partition,也可以让 Kafka 自动分配。
Producer 有几个关键参数,直接影响性能和可靠性:
- acks:确认级别。0 表示不等待确认(最快,可能丢数据);1 表示等待 Leader 确认(默认);all 表示等待所有副本确认(最安全,但慢)。
- retries:重试次数。网络抖动时自动重发。
- batch.size:批量发送大小。攒够一批再发,提高吞吐。
// Producer 配置示例
Properties props = new Properties();
props.put("bootstrap.servers", "localhost:9092");
props.put("acks", "all");
props.put("retries", 3);
props.put("batch.size", 16384);
props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");
KafkaProducer<String, String> producer = new KafkaProducer<>(props);
producer.send(new ProducerRecord<>("order_topic", "order_123", "{\"amount\": 99.9}"));
producer.close();
我曾经在生产环境遇到过一个问题:acks 设成 0,结果 Broker 宕机时丢了上千条订单数据。
从那以后,核心业务我全用 acks=all,宁可慢一点,不能丢数据。
2.5 Consumer:数据的“读取者”
Consumer 从 Topic 拉取数据。
它属于 Consumer Group,组内每个 Consumer 负责处理不同的 Partition。
Consumer 的核心机制是“拉模式”(Pull)。
它主动去 Broker 拉数据,而不是 Broker 推给它。
这样做的好处是:Consumer 可以按自己的处理能力消费,不会被打满。
关键点:一个 Partition 只能被同一个 Group 内的一个 Consumer 消费。
如果 Consumer 数量多于 Partition,多余的 Consumer 会闲置。
如果 Consumer 数量少于 Partition,一个 Consumer 会处理多个 Partition。
我建议:Consumer 数量不要超过 Partition 数量。
否则就是资源浪费,白花钱。
2.6 Zookeeper:集群的“协调者”
Zookeeper 在 Kafka 里扮演“管家”的角色。
它负责:
- 管理 Broker 的元数据(谁活着,谁挂了)
- 选举 Controller Broker(集群的“老大”)
- 存储 Topic 和 Partition 的配置信息
- 通知 Consumer Group 的变化(触发重平衡)
不过,从 Kafka 2.8 开始,Kafka 可以脱离 Zookeeper 运行(KRaft 模式)。
但生产环境里,大部分公司还在用 Zookeeper 版本,因为更成熟。
避坑指南:Zookeeper 不是数据库,别往里面存业务数据。
我曾经见过有人把 ZK 当配置中心用,存了几万条配置项,结果 ZK 频繁 OOM。
ZK 只适合存小量、高频读写的元数据。
2.7 整体架构图
下面这张图,把上面所有角色的关系串起来了。
2.8 总结一下
这六个角色,各司其职:
- Broker:存数据、收数据、发数据
- Topic:消息的分类标签
- Partition:真正存数据的地方,支持并行
- Producer:写数据的人
- Consumer:读数据的人
- Zookeeper:管事的管家
理解这些概念,是玩转 Kafka 的第一步。
后面咱们会基于这些角色,搭建一个完整的实时数据管道。
到时候你会发现,这些概念其实就在手边,天天打交道。