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 字段区分。嗯,这种做法在数据量小的时候还能凑合,一旦日均消息量突破千万级,你就等着头疼吧。

核心要点:Topic 是逻辑上的分类容器,它不直接存储数据,数据实际存储在它下面的 Partition 里。

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(或者自己管理),下次重启时接着往下读。

避坑指南:我曾经踩过一个坑——把 Offset 提交逻辑写在了业务处理之前。结果消息处理到一半程序挂了,重启后 Offset 已经提交了,那些没处理完的消息就永远丢了。记住:先处理后提交,除非你能接受丢数据。

1.4 Topic 在 Kafka 中的角色定位

Topic 在 Kafka 架构里处于什么位置?我画了张图,你看一眼就明白了。

Kafka Topic 核心架构图 Producer Producer Topic: order_topic Partition 0 Offset: 0,1,2,... Partition 1 Offset: 0,1,2,... Partition 2 Offset: 0,1,... Broker 1 Broker 2 Broker 3 Consumer Group A Consumer Group B 角色说明 • Producer:写入数据 • Topic:逻辑分类 • Partition:物理存储 • Broker:服务节点 • Consumer:读取数据 • Offset:消息坐标 每个 Partition 内的 Offset 独立递增,不同 Partition 之间 Offset 不互通

从这张图你能看到几个关键点:

  • Producer 只管往 Topic 里写数据,它不关心数据落到哪个 Partition
  • Topic 是逻辑上的分类,它把多个 Partition 组织在一起
  • Partition 分布在不同的 Broker 上,实现水平扩展
  • Consumer Group 里的每个消费者负责消费一个或多个 Partition
特别注意:Partition 的数量决定了 Topic 的并行处理能力。但也不是越多越好——每个 Partition 在 Kafka 集群里都有对应的文件句柄和内存开销。我见过有人把 Partition 数设成 1000,结果 Broker 的句柄数直接爆了。一般建议 Partition 数不超过 Broker 总核心数的 2-3 倍。

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 是每个格子里消息的编号