
某天中午休息,我被突然叫到会议室,原因是线上一个高频 topic 的延迟从 200ms 抖成了 3 秒。业务方火急火燎,说昨晚加班把分区从 24 提到 48,“网上都说分区越多越快嘛”。结果吞吐没上去,延迟倒是飞了。那一刻我意识到:分区到底开多少根本不是“迷信题”,而是一个被严重误解的工程学问题。
大家习惯用“分区越多并发越高”,但实际上分区数的决定因素有:
这些都是我实战里遇到的。
例如我们一个业务 topic,单条消息 2KB 左右,压缩后只有 1KB。broker 是 NVMe 盘,写盘可以轻松上到 500MB/s。结果业务方给我开了 128 分区。我看 segment 分布直接傻眼:每个分区的 segment 都太小,Page Cache 根本“暖”不起来,同时打开的文件句柄多到离谱(接近 20w),导致 IO 延迟飙升。
分区太多根本不是“多线程 = 快”的简单逻辑。
我能理解这个误解的来源,因为有几个前提条件成立时,确实“多分区效果好得不得了”:
也就是 producer 的吞吐受限于单分区写入速度。如果把分区开多,能让 batch 几乎每次都写满(比如 batch.size=512KB),吞吐立刻飞升。
你要是 SATA 盘、虚拟机、共享 IO,那多分区并不等于更高并发,只会等于更乱。
否则就是白浪费。
我遇过一个电商场景的 topic,单条消息近 20KB,producer 单分区写入只有 2w QPS。分区从 6 提到 18 后,写入吞吐直接翻倍。原因不是 Kafka 变快,而是 batch 被打满了三倍。
这就是为什么网上很多经验“看起来对”,但换一个场景立刻错。
这个部分我写得会比较情绪化,因为我确实被“分区过多”坑得很惨。
分区越多,消费者组 rebalance 时需要协调的 partition 数越多,耗时呈线性甚至指数增长。我们线上有一次 72 分区的 topic,rebalance 一次耗时几十秒,业务直接卡住。
更惨的是:生产环境 CPU 抖动也会触发 rebalance。根本不是 Kafka 的锅,是分区太多导致的敏感性过高。
Kafka 靠 Page Cache 吃饭,这是要命的点。
分区越多 = segment 文件越分散 = Page Cache 命中率越低 = Kafka 失去顺序写的优势。
我看过一个 broker 的内存使用:
Page Cache 是 Kafka 的黄金引擎,分区数直接决定你能不能吃上这个 buff。
Kafka 每个 partition 维护 index 文件:.index、.timeindex 以及 .log 本体。
分区越多 = index 文件数量越多。
一个 topic 48 分区时总 index 大约 300MB
业务方搞到 200 分区后直接破 1.6GB
而问题不是占空间,而是 index 文件打开过多增加 OS 句柄压力,任何一次 flush 都更慢。
producer 默认分区器通常会根据 key 或轮询。一旦分区太多,以下问题会冒出来:
我曾经在一个日志采集业务遇到 producer 端报警:
buffer exhausted 业务 QPS 只有 8w,却开了 100 分区。导致 producer 端有 80 个分区 batch 都在抢 32MB buffer。
把分区数降到 20 后,这个报警彻底消失。
消费者组是按分区维度分配线程的,你想并发高,确实要更多分区,但这个逻辑只对以下场景成立:
但我见过太多业务:
结果消费者线程在抢 CPU,反倒把整个 consumer group 的性能拉低。并发不是越多越好,是要看你的消费逻辑“能不能用得了更多并发”。
穷一般按这个思路来估算:
分区数 ≥ 峰值写入 QPS / 单消费者处理 QPS例如:
分区数 ≈ 生产端并发线程数 × 1~2一般用来确保批处理效果。
分区数 ≤ broker 数 × 200 (保守值)超过这个指标,broker 的 index 文件、句柄数量、page cache 命中率一般会崩。
最终分区数 = max(公式1, 公式2),但要满足公式3现实里我大部分 topic 都落在 12~32 分区之间,超出这个范围往往需要深度论证。
Kafka 的性能优势几乎都来自于顺序写 + Page Cache,这两点决定了分区数不能太多。
一次写 1MB 顺序 IO 和同时写 100 个小文件带来的磁头寻址开销完全不是一个量级,即使是 SSD 也一样——不是回 seek,但 Page Cache 分散后性能会掉。
分区增多后,很多人忘了一个点:
leader 多的 broker 才是瓶颈,不是 follower。
我遇过一个严重案例:一个 broker 上落了 60% 的 leader,写入延迟高达 800ms,而另外两个 broker 降到 50ms。
罪魁祸首:分区数上去了,leader 分布不均。后来强行做了 reassignment 才解决。这就是现实世界里的 Kafka。
我个人积累的一些经验,可能会有偏见,但确实是从失败里总结出来的:
这套配置我在多个项目里都跑出过百万 QPS 的吞吐。
我说一句实话:
小数据量完全没必要开太多分区。
你的 producer、consumer、broker 都不是瓶颈,运维团队也不希望那么多分区。我的通用建议是:
我最喜欢讲的一个真实坑点就是这个。
我们一个订单事件 topic,原来 48 分区。业务 QPS 大概 6w~7w。broker 三台,每台 24C 64GB 内存,NVMe SSD,配置不算差。
但系统有这些问题:
我们花了两周排查,最终把分区从 48 调到 12。
实际效果如下:
指标 | 调整前 | 调整后 |
|---|---|---|
broker CPU | 30–60% | 20–30% |
Page Cache 命中率 | 40–80% 波动 | 稳定在 95% |
写入延迟 | 偶发 500ms | 稳定 10ms |
消费端 RT | 30ms | 12ms |
rebalance 次数 | 平均每小时 1 次 | 3 天 1 次 |
吞吐不仅没下降,消费处理速度还提升了将近 2 倍。
我们当时非常懵逼,后来分析原因才确定是:
这是个很反直觉的坑,但真的发生过。
分区从来不是越多越快,而是一个需要结合 broker 能力、数据规模、生产消费模式、团队运维能力综合权衡的参数。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。