Confluent Kafka 业务分区数量评估笔记
目录
背景#
我们的项目使用 Confluent Cloud 托管 Kafka 集群,在上线前需要确定每个 topic 的分区(partition)数量。Kafka 的分区数只能增加不能减少,因此更适合在初始阶段先做一轮带假设前提的评估。
本文记录这一评估过程。
业务规模#
基础数据 (单 Topic)#
| 参数 | 数值 |
|---|---|
| 单 Topic 日均消息量 | 4 亿条 |
| 活跃用户数 | ~200 万 |
| 人均日均交易笔数 | 200 笔 |
| 每笔交易产生消息数 | 1 条 |
| Topic 数量 | 约 60 个 |
| 集群日均总消息量 | 约 240 亿条 |
单 Topic RPS 推导#
单 Topic 全天平均 RPS = 4亿 ÷ 86,400秒 ≈ 4,630
交易流量并非均匀分布。假设流量集中在约 8 小时的活跃窗口内:
单 Topic 活跃时段平均 RPS = 4亿 ÷ (8 × 3,600秒) ≈ 13,900
活跃窗口内还存在早晚高峰,峰值通常为活跃时段均值的 2–3 倍:
| 峰值系数 | 单 Topic 峰值 RPS |
|---|---|
| 2x | ~28,000 |
| 3x | ~42,000 |
以 3x 峰值系数估算,单 Topic 峰值约为 4.2 万 RPS。
消息规格#
| 参数 | 数值 |
|---|---|
| 消息格式 | JSON |
| 压缩前大小 | ~1 KB |
| 压缩算法 | Snappy |
| 压缩后大小 | ~0.5 KB |
分区数量评估#
评估公式#
Confluent 官方文档给出了分区数量的核心公式:
所需分区数 ≈ max(目标吞吐 / 单分区生产吞吐, 目标吞吐 / 单分区消费吞吐)
文档指出单分区吞吐量取决于 batch size、压缩算法、ack 配置、replication factor 等参数,建议在目标集群上实测。
参考来源:Choose and Change the Partition Count in Kafka — Confluent Documentation
Confluent 官方 benchmark 提供了一个参考数据点:在 3 个 Broker(i3en.2xlarge)、100 个分区、1 KB 消息、RF=3、acks=all 的配置下,集群总生产吞吐达到 605 MB/s,折合每分区约 6 MB/s。该测试的瓶颈在于磁盘 I/O,而非分区数量本身。
需要注意,Confluent Cloud 使用自研的 Kora 云原生引擎。Confluent 在自家材料里给出的结论是,其吞吐和延迟表现优于原生 Apache Kafka,因此上述 benchmark 更适合作为一个偏保守的下限参考。
参考来源:Kafka Latency Comparison: Confluent Cloud vs DIY Apache Kafka — Confluent Blog
吞吐量压力分析#
按单 Topic 峰值 4.2 万 RPS 计算吞吐量:
单 Topic 峰值吞吐 = 42,000 × 0.5 KB ≈ 21 MB/s
套用公式,以 Confluent benchmark 中的 6 MB/s/分区作为保守基准:
生产端:21 MB/s ÷ 6 MB/s ≈ 4 个分区
实际生产环境中,通过调优 batch.size 和 linger.ms,单分区吞吐还有继续提升的空间。因此 按这组假设来看,6 个分区在吞吐层面很可能已经有余量。
但分区数量不仅关乎吞吐,还决定了 Consumer 的最大并行度——一个 Consumer Group 中,最多只能有与分区数相同数量的 Consumer 实例同时消费。
同时需要注意,Confluent Cloud 文档指出分区数增加会带来延迟上升的 trade-off:更多分区意味着 broker 之间的 replication 耗时更长,消息 commit 时间变长,最终影响端到端延迟。因此分区数量不应无限制增加。
参考来源:Optimize Confluent Cloud Clients for Latency — Confluent Documentation
6 个 vs 12 个分区#
考虑到我们的消息处理逻辑(Consumer 端)可能存在复杂的 I/O 操作(如数据库写入),单实例的处理速度往往是瓶颈。
| 考量维度 | 6 个分区 | 12 个分区 |
|---|---|---|
| 吞吐量(按 6 MB/s/分区保守估算) | 36 MB/s(vs 21 MB/s 需求,余量 ~1.7x) | 72 MB/s(余量 ~3.4x) |
| Consumer 最大并发数 | 6 个实例 | 12 个实例 |
| Consumer 均匀分配(可整除的实例数) | 1, 2, 3, 6 | 1, 2, 3, 4, 6, 12 |
| 未来流量增长/波动容忍度 | 一般 | 相对更从容 |
12 个分区在保证吞吐余量的同时,提供了更灵活的 Consumer 扩容空间。
成本影响#
我们有约 60 个 Topic,每个 Topic 均配置 12 个分区:
| 方案 | 总分区数 |
|---|---|
| 6 分区 × 60 topics | 360 |
| 12 分区 × 60 topics | 720 |
| 12 分区 × 100 topics (预留扩充) | 1,200 |
Confluent Cloud 计费模式#
Confluent Cloud 存在两种计费模式(取决于账户创建时间):
旧模式(2024年4月16日前创建的账户): 按 partition 数量直接计费。Standard 套餐包含 500 个免费分区,超出部分按小时收费。720 个分区超出 220 个,会产生额外费用。
新模式(2024年4月16日后创建的账户): 改用 eCKU (Elastic CKU) 计费,不直接按分区数量收费。分区数量通过占用集群容量间接体现在 eCKU 消耗上。
以旧模式 Standard 套餐为例,额外 360 个分区(从 360 增加到 720)按 $0.0015/partition/小时估算,月增约 $238。而在日均 240 亿条消息的规模下,集群主要费用更可能集中在 eCKU 流量消耗、存储空间和跨可用区网络流量上,分区的边际成本在整体账单中的占比相对较小。
Consumer 连接模型#
一个常见误解是:1 个 Consumer 消费 12 个 partition 需要 12 个 TCP 连接。
实际上,Kafka Consumer 连接的是持有 partition leader 的 Broker。如果 12 个 partition 分布在 3 个 Broker 上,1 个 Consumer 实例只需要 3 个 TCP 连接即可轮询所有 12 个 partition。
我们的场景(每个 topic 1 个 Consumer,60 个 topic):
| 来源 | 估算连接数 |
|---|---|
| 60 个 Consumer × ~3 连接/Consumer | ~180 |
| Producer 连接 | ~60–180 |
| 管理/监控 | ~10–20 |
| 合计 | ~250–380 |
这一连接数对 Confluent Cloud 的 Basic 和 Standard 套餐来说通常不像主要瓶颈。分区从 6 增加到 12 也不太会显著增加连接数。
关于 Spring Boot 应用中 Kafka 连接数的详细计算逻辑和实测数据,可以参考本博客的另一篇文章:How Many Kafka Connections Does Your Spring Boot App Actually Use?。
结论#
在当前这组假设下,我会先从每个 Topic 12 个分区起步。
核心逻辑:
- 吞吐量满足单 Topic 需求:按 Confluent 官方公式和 benchmark(6 MB/s/分区保守基准),单 Topic 峰值 21 MB/s 仅需 4 个分区。12 个分区提供了约 3.4 倍的余量。
- 选 12 而非 6 的理由:分区数决定 Consumer 最大并行度。对于日均 4 亿消息量的 Topic,后续单 Consumer 处理能力很可能成为瓶颈,12 个分区允许我们水平扩容到 12 个实例,且支持 1/2/3/4/6/12 等多种均衡分配组合。
- 规模决定了成本权重:在日均 240 亿条消息的总规模下,数据传输和存储更像是主要的成本来源。相比之下,720 个分区的管理成本(无论是旧模式的固定费还是新模式的容量占比)在总账单中的权重会小一些。
- 一次性架构决策:分区只能增不能减。在这组业务假设下,初期配置 12 个分区更像一项偏保守的起步配置。
参考资料#
- Choose and Change the Partition Count in Kafka — Confluent Documentation
- Apache Kafka Performance — Confluent Developer
- Kafka Latency Comparison: Confluent Cloud vs DIY Apache Kafka — Confluent Blog
- Optimize Confluent Cloud Clients for Latency — Confluent Documentation
- Confluent Cloud Cluster Types — Confluent Documentation
- Apache Kafka Documentation