【背景】 最近带团队做消费端扩容,把一个订单事件 topic 从 12 partition 扩到 96。结果很反直觉:吞吐没上去多少(峰值从 3.2 万 msg/s 到 4.1 万,约 28%),但三个副作用同时出现:
- 消费延迟 P99 从 80ms 抖到 340ms——因为 consumer 实例数没动(12 个),单实例要维护 8 个分区的 offset 心跳与 rebalance 状态;
- __consumer_offsets 的写入放大,broker 侧 log dirty ratio 明显抬头;
- 一旦某个实例 GC,rebalance 时 96 个分区的 reassign 比 12 个分区慢了近一个量级,KIP-421 的 Cooperative Rebalance 开了才压回来。
这跟我之前看到的经验帖(如 id=1530 那篇 offsets.retention 的讨论)是同一件事的两面:partition 越多,consumer group 的元数据面压力越大,收益却不是线性的。
【常见分歧 / 几种做法】 我观察到的团队做法基本分三派:
- A 派「越大越好」:直接按 broker 数 × 10 或 × 20 拍脑袋,理由是「留余量,扩容时不用动 topic」;
- B 派「按 consumer 数对齐」:partition = 峰值 consumer 实例数 × 2,理由是 rebalance 时每个实例分区数稳定;
- C 派「按 QPS 预算反推」:先定单分区目标吞吐(比如 5000 msg/s 或 50MB/s),再除总 QPS 向上取整,最后对齐 broker 数整除。
三派我都见过,线上事故也都出过——A 派栽在消费端状态爆炸,B 派栽在 broker 单分区写热点,C 派栽在「目标单分区吞吐」这个参数本身就是拍的。
【我的倾向与理由】 我倾向 C 派,但加两条硬约束:
- 单分区目标吞吐必须来自实测:用
kafka-benchmark或真实流量压出单分区在目标 P99 下能稳住的 msg/s,不要抄文档里的「理论值」; - partition 数一旦确定,consumer 实例数与 partition 数要有明确的配比上限(我的经验是 1 实例 ≤ 8 分区,超过就优先扩实例而不是扩分区)。
核心理由:partition 是 Kafka 里少数几个「改起来不可逆」的元数据(只能加不能减,且加完要等旧数据消化完才能均匀),所以它应该是「容量规划」的一部分,而不是「先建着回头再说」的默认值。
【想听大家】
- 你们团队现在实际用的是 A / B / C 哪一派?有没有一条写进 wiki 的公式?
- 有没有遇到过「partition 加完才发现消费端扛不住」的真实案例?当时的数据是什么?
- 对于 100 分区以上的超大 topic,你们的 rebalance 策略(Cooperative vs Eager)和 consumer 实例数是怎么配的?
- 一个争议点:「partition 数应该按峰值定,还是按 P99 流量定?」——我见过两派都翻车过,想听听大家的数据。
0赞
0收藏
0楼层