3. Kafka 核心概念:Topic、Partition、Consumer Group、Offset、Broker 详解

做量化交易系统,数据流就是你的生命线。行情数据、订单状态、成交回报……这些消息每秒成百上千条地往系统里灌。Kafka 就是用来扛住这种压力的。

但说实话,我刚接触 Kafka 时也被一堆概念搞晕过。Topic、Partition、Consumer Group、Offset、Broker……每个词都认识,连在一起就不知道它们在干嘛。今天咱们就把这些核心概念彻底捋清楚。


3.1 Broker —— 集群里的每个节点

Broker 是 Kafka 集群中的一台服务器。说白了,就是一台跑着 Kafka 进程的机器。

我习惯把 Broker 想象成「仓库管理员」。每个管理员管着几个货架(Partition),负责收消息、存消息、发消息。

  • 一个 Kafka 集群通常有 3 台以上的 Broker
  • 每个 Broker 有一个唯一的 ID(数字)
  • Broker 之间通过 Zookeeper 或 KRaft 协调
我的经验:生产环境至少部署 3 个 Broker。我见过有人图省事只部署 1 个,结果 Broker 宕机,整个交易系统直接瘫痪。量化交易最怕的就是单点故障。

3.2 Topic —— 消息的分类标签

Topic 是 Kafka 里最基础的概念。你可以把它理解成一个「消息队列的名字」。比如:

  • trade_orders —— 存放所有订单消息
  • market_data —— 存放行情数据
  • risk_alerts —— 存放风控告警

生产者往 Topic 里写消息,消费者从 Topic 里读消息。就这么简单。

但注意,Topic 只是一个逻辑概念。真正存数据的地方,是 Partition。


3.3 Partition —— 真正存数据的地方

每个 Topic 可以分成多个 Partition。Partition 是一个有序的、不可变的日志文件。

为什么要分区?

  • 并行处理:多个消费者可以同时读不同 Partition
  • 水平扩展:Partition 可以分布在不同的 Broker 上
  • 顺序保证:同一个 Partition 内的消息是有序的
关键点:Kafka 只保证 Partition 内的消息顺序,不保证 Topic 内跨 Partition 的顺序。如果你的业务要求全局有序,那就只能设 1 个 Partition——但性能会大打折扣。

我在做行情系统时踩过这个坑。当时把行情数据写进一个 Topic,分了 6 个 Partition。结果发现不同 Partition 的行情到达顺序乱了。后来我按股票代码做 Hash,同一只股票的消息进同一个 Partition,问题就解决了。


3.4 Offset —— 消息的唯一编号

每条消息写入 Partition 后,Kafka 会给它分配一个递增的编号,这就是 Offset。

Offset 从 0 开始,每条消息的 Offset 都是唯一的、单调递增的。

消费者读取消息时,需要告诉 Kafka:「我从哪个 Offset 开始读」。这就实现了「断点续传」——消费者挂了重启,只要记住上次的 Offset,就能接着读。

# 消费者指定 Offset 读取
# 从 Offset 100 开始读
consumer.assign(Arrays.asList(new TopicPartition("market_data", 0)));
consumer.seek(new TopicPartition("market_data", 0), 100);
我曾经犯过的错:手动管理 Offset 时,把 Offset 存到了本地文件。结果服务器磁盘坏了,Offset 丢了,消费者从 0 开始重读,把几百万条历史行情又处理了一遍……后来我改用 Kafka 自带的 Offset 提交机制,再也没出过问题。

3.5 Consumer Group —— 消费者的团队协作

Consumer Group 是 Kafka 实现「广播」和「单播」的关键。

  • 同一个 Group 内:每条消息只会被一个消费者处理(单播)
  • 不同 Group 之间:每个 Group 都能独立消费全部消息(广播)

举个例子:

我有一个 trade_orders Topic,分了 3 个 Partition。

  • Group A(订单处理组):3 个消费者,每人负责 1 个 Partition
  • Group B(风控组):2 个消费者,一个负责 2 个 Partition,另一个负责 1 个
  • Group C(日志归档组):1 个消费者,负责全部 3 个 Partition

你看,同一个 Topic 的消息,可以被不同 Group 独立消费,互不干扰。

我建议:Consumer Group 的消费者数量不要超过 Partition 数量。多出来的消费者会闲置,白白浪费资源。

3.6 核心关系一览

下面这张图帮你理清这些概念之间的关系:

Kafka 集群(Broker 集群) Broker 1 Partition 0 Offset: 0, 1, 2, 3, ... Partition 1 Offset: 0, 1, 2, 3, ... Partition 2 Offset: 0, 1, 2, 3, ... Broker 2 Partition 3 Offset: 0, 1, 2, 3, ... Partition 4 Offset: 0, 1, 2, 3, ... Broker 3 Partition 5 Offset: 0, 1, 2, 3, ... Topic: market_data(6 个 Partition) Consumer Group A(3 个消费者) Consumer Group B(2 个消费者) Consumer Group C(1 个消费者)

这张图展示了:一个 Topic 的 6 个 Partition 分布在 3 个 Broker 上,不同 Consumer Group 可以独立消费这些 Partition。


3.7 这些概念在量化交易中怎么用?

拿我们的实盘事件流监控系统来说:

Topic 名称 Partition 数量 用途 Consumer Group
market_data 6 存储实时行情(股票、期货、期权) 行情处理组、策略计算组、日志归档组
trade_orders 3 存储订单指令和成交回报 订单执行组、风控组、监控告警组
risk_alerts 2 存储风控告警事件 告警处理组、UI 推送组

你看,同一个 Topic 的数据可以被多个 Group 消费,各取所需。行情组做实时计算,日志组做离线分析,互不干扰。

注意:Partition 数量一旦确定,后期扩容很麻烦。我建议根据未来 1-2 年的数据量来预估。行情系统我一般按「每秒 10 万条消息,每条 1KB」来估算,每个 Partition 的吞吐量大约 10MB/s。

3.8 小结

这几个概念其实就一句话:

  • Broker:存数据的机器
  • Topic:数据的分类标签
  • Partition:真正存数据的文件
  • Offset:消息在 Partition 里的位置编号
  • Consumer Group:一组消费者,协作消费数据

理解这些,Kafka 的基本架构你就拿下了。下一节咱们聊聊生产者和消费者怎么跟这些概念打交道——也就是消息的发送和接收机制。


公众号:蓝海资料掘金营,微信deep3321