先说结论

分区数至少要支撑目标生产吞吐和消费者并行度,可分别用总吞吐除以单分区实测能力估算并取较大值,再留合理增长余量。分区并非越多越好,过多会增加文件、元数据、选举、复制和故障恢复成本。

同一消费者组内,一个分区同一时刻最多分配给一个消费者;消费者数量超过分区数不会增加并行度。

规划维度

用接近生产的消息大小、压缩、acks、副本数和磁盘配置压测单分区能力。还要考虑峰值、保留周期、Broker 数量、每节点分区与副本分布以及故障时剩余容量。

用容量模型做初步估算

假设目标生产峰值为 200 MB/s,实测单分区在同等 acks、压缩和副本条件下可稳定写 10 MB/s,则生产维度至少需要 20 个分区;若消费组每个分区稳定处理 5 MB/s,消费维度需要至少 40 个分区。取较大值后再预留增长与故障余量,而不是照搬固定“每台机器 N 个分区”的经验。

这个模型只是起点。实际还会受消息大小分布、热点 key、Broker 磁盘、网络、复制、保留时长和消费者业务耗时影响,必须通过压测和线上监控持续校正。

分区过多的成本

每个分区和副本都有日志文件、索引、内存状态、复制 fetch、选举和恢复成本。大量小分区会增加 controller 元数据、Broker 启动时间、故障恢复时长和文件句柄压力;一次 broker 故障后,成千上万分区同时迁移或选举也会造成控制面风暴。

分区规划要保证任意一台 Broker 故障后,剩余节点仍能承受副本流量与分区数量。只按正常状态平均分布设计,故障时往往出现磁盘或网络过载。

消费者并行与业务耗时

消费者数上限受分区数约束,但增加消费者不一定提高吞吐:如果下游数据库连接池只有 20 个、每条消息需调用慢 HTTP,40 个消费者可能只会增加竞争和超时。并发规划需同时包含每分区拉取、应用处理线程、下游连接与限流。

若单个 key 极热,增加总分区无效,因为该 key 仍落在一个分区。需要拆分业务 key、分段聚合、单独 Topic 或改变处理模型。

扩分区前的检查清单

  1. 该 Topic 是否强依赖同 key 的历史顺序?
  2. 默认分区器扩容后 key 映射变化是否可接受?
  3. 客户端、ACL、配额、监控和副本均衡是否已准备?
  4. 新分区创建后消费者组如何再均衡,是否会造成短暂停顿?
  5. 是否有更直接的瓶颈,例如慢消费者、下游连接池或热点 key?

分区只能增加不能轻易减少,预留应适度而不是无限大。需要改变分区模型时,创建新 Topic、双写/回放并切换消费者通常更安全。

运维监控

持续观察每分区 bytes in/out、records、Lag、leader 分布、under-replicated partitions、磁盘、网络和请求延迟。平均 Topic Lag 健康不代表没有一个热点分区持续积压;应该按分区看 max、分位数与倾斜度。

扩容影响

Kafka 可以增加分区但通常不能直接减少。默认 Key 哈希取模在分区数变化后会重新映射,新旧消息可能不再处于同一分区,影响按 Key 顺序;需要版本化 Topic 或业务版本控制。

容易踩坑的地方

只按当前消费者数量定分区会忽略生产吞吐和增长,预设极大分区数又会制造长期运维成本。分区不均还可能来自 Key 倾斜,单纯加分区不一定修复热点。

常见问题

追问:积压时临时增加消费者为什么没效果?

如果消费者数已达到分区数,新增实例没有分区可分;还需评估单条处理耗时、下游容量,必要时增加分区并调整 Key 与顺序策略。

追问:分区数应该等于消费者数吗?

不必相等。分区还受生产吞吐、未来扩容、故障恢复和多个消费者组影响;消费者数可按当前处理能力伸缩,分区是更长期的存储与并行边界。

追问:为什么大消息会降低单分区吞吐?

大消息占用网络、页缓存、批处理和 GC,复制与重试成本也更高。应控制消息大小,把大对象放对象存储并发送引用,或调整批量与限制。

追问:如何处理分区倾斜?

分析 key 分布和分区流量,必要时给热点实体加二级分片、独立 Topic 或异步聚合;不能只反复重平衡 Broker,因为同 key 路由仍会形成热点。