Partition 设计原则:数量、消费关系与吞吐量
Topic 的 Partition,说白了就是 Kafka 并行能力的「天花板」。很多新手上来就问「Partition 设多少个合适?」,我一般会反问一句:「你期望的吞吐量是多少?你 Consumer 准备开几个线程?」——这两个问题答清楚了,Partition 数量基本就定了。
这一节,我带你从三个角度把 Partition 设计吃透:数量怎么定、Consumer 怎么对应、吞吐量到底受什么影响。
Partition 数量如何确定
先给个结论:Partition 数量 = max(期望吞吐量 / 单 Partition 吞吐量, 期望 Consumer 并行度)。但实际落地时,要考虑的因素远不止这个公式。
核心原则:Partition 是 Kafka 并行度的最小单位。一个 Partition 只能被同一个 Consumer Group 内的一个 Consumer 线程消费。所以,Partition 数量决定了 Consumer 的最大并行度。
我个人习惯按以下步骤来估算:
- 先测单 Partition 的吞吐量——在测试环境压一把,看看单 Partition 的写入和消费极限。一般单 Partition 每秒能处理 10-50 MB 的写入(取决于硬件和配置)。
- 再算总吞吐量需求——比如你业务峰值是 500 MB/s,单 Partition 能扛 20 MB/s,那至少需要 25 个 Partition。
- 考虑 Consumer 并行度——如果你只有 5 个 Consumer 实例,每个开 2 个线程,那最大并行度是 10。Partition 设多了也没用,反而浪费。
- 留余量——我建议按峰值需求的 1.5-2 倍来设。为什么?因为 Partition 只能增加,不能减少(除非重建 Topic)。
避坑指南:我曾经在一个日志采集项目里,把 Partition 设成了 200 个,结果 Broker 上文件句柄数暴涨,Leader 选举时花了将近 2 分钟。Partition 不是越多越好,每个 Partition 对应一个日志段目录,元数据也会膨胀。一般建议单 Broker 上的 Partition 总数不超过 2000。
下面这张图帮你理清 Partition 数量决策的完整链路:
Partition 与 Consumer 的对应关系
这个对应关系,其实就一句话:一个 Partition 只能被同一个 Consumer Group 内的一个 Consumer 实例消费。但反过来,一个 Consumer 可以消费多个 Partition。
你想想看,如果 Consumer 数量大于 Partition 数量,多出来的 Consumer 会闲置。如果 Consumer 数量小于 Partition 数量,那有些 Consumer 就要扛多个 Partition 的流量。
| 场景 | Consumer 数 vs Partition 数 | 结果 |
|---|---|---|
| Consumer 数 = Partition 数 | 1:1 | 最理想,每个 Consumer 处理一个 Partition,负载均衡 |
| Consumer 数 < Partition 数 | 1:N | 部分 Consumer 处理多个 Partition,吞吐量可能成为瓶颈 |
| Consumer 数 > Partition 数 | N:1 | 多余 Consumer 闲置,浪费资源 |
实战建议:我一般把 Consumer 数量设为 Partition 数量的 0.8-1 倍。比如 10 个 Partition,开 8-10 个 Consumer。这样既能充分利用并行度,又留了容错空间——某个 Consumer 挂了,其他 Consumer 能快速接管。
这里有个容易踩的坑:同一个 Consumer Group 内的 Consumer 会触发 Rebalance。Rebalance 期间,所有消费都会暂停。我记得有一次线上环境,Consumer 频繁上下线,导致 Rebalance 反复触发,消费延迟从 10 秒飙到了 5 分钟。后来排查发现,是 Consumer 心跳超时设置得太短。
Partition 对吞吐量的影响
Partition 对吞吐量的影响,可以从「写入端」和「消费端」两个维度来看。
写入端吞吐量
Kafka 的写入是追加到 Partition 的日志段文件。多个 Partition 可以并行写入,所以理论上 Partition 越多,写入吞吐量越高。但有个前提:Producer 端要开启多线程或异步发送,否则单线程写多个 Partition 也快不起来。
实际项目中,我见过一个场景:Partition 从 3 个扩到 12 个,写入吞吐量从 50 MB/s 涨到了 180 MB/s。但再往上扩到 24 个,吞吐量只涨到了 200 MB/s。为什么?因为磁盘 IO 成了瓶颈。
关键公式:写入吞吐量 ≈ min(网络带宽, CPU 处理能力, 磁盘 IOPS × 单次写入大小, Partition 数 × 单 Partition 吞吐量)
消费端吞吐量
消费端的吞吐量,直接受 Partition 数量限制。一个 Consumer 线程处理一个 Partition,如果你只有 1 个 Partition,那 Consumer 开 100 个线程也没用——只有 1 个线程在干活。
我建议你记住这个经验值:
- 单 Partition 消费吞吐量:一般 5-20 MB/s(取决于消息大小和业务逻辑)
- 单 Consumer 实例:建议处理 2-5 个 Partition,再多容易导致线程竞争
- 总吞吐量:≈ Partition 数 × 单 Partition 消费吞吐量
避坑指南:我曾经在一个实时数仓项目里,把 Partition 设了 64 个,Consumer 只开了 4 个。结果每个 Consumer 要处理 16 个 Partition,线程上下文切换开销巨大,CPU 飙到 90%,吞吐量反而比 32 个 Partition 时还低。后来我把 Consumer 扩到 16 个,每个处理 4 个 Partition,问题才解决。
最后,给你一个 Partition 数量速查表,方便日常参考:
| 业务场景 | 推荐 Partition 数 | 说明 |
|---|---|---|
| 日志采集(低吞吐) | 3-6 | 单 Broker,Consumer 少,够用就行 |
| 业务消息(中吞吐) | 6-12 | 多 Broker 集群,考虑 Consumer 并行度 |
| 实时数仓(高吞吐) | 12-48 | 需要压测确定,留余量 |
| 物联网/传感器(超高吞吐) | 48-200 | 注意 Broker 文件句柄和元数据膨胀 |