1. Topic 基础认知:什么是 Topic、Partition 与 Offset
好,咱们直接进入正题。Topic 这个词,你在 Kafka 文档里翻来覆去都能看到。但说实话,很多人用了两三年,对它的理解还停留在「就是个消息队列的名字」。
我个人习惯把 Topic 比作一个数据分类的文件夹。你想想看,操作系统里为什么要有文件夹?就是为了把不同用途的文件分开存放。Topic 在 Kafka 里干的是同一件事——把不同业务的数据隔离开。
1.1 Topic 的本质
Topic 是 Kafka 里最顶层的消息分类单元。每个 Topic 代表一类数据流。比如订单数据进 order_topic,用户行为日志进 user_behavior_topic,监控指标进 metrics_topic。
我见过不少新手把几十个业务的数据全塞进一个 Topic,然后靠消息里的 type 字段区分。嗯,这种做法在数据量小的时候还能凑合,一旦日均消息量突破千万级,你就等着头疼吧。
1.2 Partition——真正的存储单元
每个 Topic 可以拆成多个 Partition。Partition 才是 Kafka 真正存数据的地方。你可以把 Partition 理解成一个有序的、不可变的日志文件。
为什么要有 Partition?说白了就是为了水平扩展。一个 Topic 的数据量太大,单台机器扛不住,那就分到多台机器上。每个 Partition 可以落在不同的 Broker 上,这样读写压力就分散开了。
| 概念 | 类比 | 关键特性 |
|---|---|---|
| Topic | 文件夹 | 逻辑分类,不存实际数据 |
| Partition | 文件 | 物理存储,有序追加写 |
| Offset | 文件中的行号 | 唯一标识每条消息的位置 |
我在项目中遇到过一个问题:某团队把 Topic 的 Partition 数设成了 1,结果消费端有 10 个消费者,9 个闲着。为什么?因为一个 Partition 只能被一个消费者线程消费。你想想看,这资源浪费得多严重。
1.3 Offset——消息的坐标
每条消息进入 Partition 时,Kafka 会给它分配一个递增的序号,这就是 Offset。Offset 从 0 开始,单调递增,不会重复。
消费者怎么知道自己该从哪条消息开始读?就是靠 Offset。消费者把当前消费到的 Offset 提交给 Kafka(或者自己管理),下次重启时接着往下读。
1.4 Topic 在 Kafka 中的角色定位
Topic 在 Kafka 架构里处于什么位置?我画了张图,你看一眼就明白了。
从这张图你能看到几个关键点:
- Producer 只管往 Topic 里写数据,它不关心数据落到哪个 Partition
- Topic 是逻辑上的分类,它把多个 Partition 组织在一起
- Partition 分布在不同的 Broker 上,实现水平扩展
- Consumer Group 里的每个消费者负责消费一个或多个 Partition
1.5 为什么 Offset 这么重要
Offset 是 Kafka 实现消息顺序性和消费进度管理的基础。同一个 Partition 内的消息是有序的,Offset 小的先写入,Offset 大的后写入。消费者按 Offset 递增的顺序读取,就能保证消息的顺序。
但注意,这个顺序性只在 Partition 级别有效。不同 Partition 之间的消息顺序,Kafka 不做任何保证。如果你的业务要求全局有序,那就只能把 Partition 数设为 1——代价是吞吐量大幅下降。
我记得有一次帮一个金融客户排查问题,他们的交易数据要求严格有序。结果发现开发人员把 Partition 数设成了 6,交易流水乱得一塌糊涂。后来改成 1 个 Partition,问题解决了,但吞吐量从 10 万/s 降到了 2 万/s。这就是顺序性和吞吐量之间的取舍。
1.6 小结
这一章我们聊了 Topic、Partition 和 Offset 这三个最基础的概念。说白了:
- Topic 是分类的筐
- Partition 是真正存数据的格子
- Offset 是每个格子里消息的编号