这是《RocketMQ 零基础实战指南》的独立章节版。本章从概念、实操和生产排查三个视角展开,代码块保留了原书可直接运行的版本。 性能调优的目标是满足业务 SLA,而不是追求单点最高 TPS。RocketMQ 调优通常沿着链路推进:客户端发送、网络、Broker 写入、索引构建、消费处理、下游依赖和存储回收。先测基线,再改一个变量,最后保留结果。
29.1 调优流程
define SLA
-> build baseline
-> profile bottleneck
-> change one variable
-> verify result
-> document and monitor
SLA 示例:
| 指标 | 目标 |
|---|---|
| send P99 | < 10 ms |
| consume P99 | < 100 ms |
| end-to-end P99 | < 1 s |
| max lag | < 10,000 |
| recovery time | < 5 min |
没有延迟目标的压测容易得到“高吞吐但不可用”的结论。
29.2 生产者调优
常见参数:
| 参数 | 影响 |
|---|---|
| maxMessageSize | 单条消息上限 |
| sendMsgTimeout | 等待 Broker 时间 |
| retryTimesWhenSendFailed | 同步重试次数 |
| compressMsgBodyOverHowmuch | 压缩阈值 |
| producer group | 逻辑分组 |
优化:
- 复用生产者实例;
- 控制消息大小;
- 大对象放对象存储;
- 合理压缩;
- 设置有限重试;
- 批量发送需业务允许;
- 避免发送线程内做慢 IO;
- 保存 SendStatus 和业务键。
29.3 Broker 写入调优
写入路径:
request decode
-> validate
-> append commitlog
-> replicate
-> flush
-> response
可调方向:
- 独立高性能数据盘;
- 评估同步刷盘与异步刷盘;
- 评估同步复制与异步复制;
- 控制 Topic 队列总数;
- 限制超大消息;
- 均衡 Broker 写入;
- 避免冷读挤占页缓存;
- 确认线程池和请求队列;
- 使用合适的系统 IO 调度。
任何可靠性降低都必须经过业务确认,不能为了压测数字关闭必要保护。
29.4 消费调优
先定位单条耗时:
deserialize
-> validate
-> database operation
-> rpc call
-> local business transaction
-> metrics
常见优化:
| 优化 | 适用 |
|---|---|
| 优化慢 SQL | 数据库瓶颈 |
| 索引和唯一键 | 查询慢 |
| 下游批量提交 | 高吞吐导入 |
| 增加消费者实例 | CPU 或并发不足 |
| 增加消费线程 | 单机仍有余量 |
| 旁路非核心逻辑 | 可异步处理 |
| 降级审计细节 | 故障窗口 |
消费线程增加前必须确认数据库连接池、下游限流和顺序性要求。
29.5 队列与热点
热点表现:
- 单队列消费 lag 明显更高;
- 单 Broker 磁盘和 CPU 更高;
- 单排序 key 消息集中;
- 局部顺序导致吞吐受限。
处理:
- 调整队列选择;
- 拆分热点 Topic;
- 拆分热点业务 key;
- 非顺序业务改并发消费;
- Broker 均衡;
- 顺序流程异步旁路;
- 预估促销热点。
29.6 索引与查询调优
查询慢的原因:
- 时间范围过大;
- Key 选择性低;
- 冷数据读取;
- 磁盘竞争;
- 并发查询过高;
- 轨迹全量开启。
建议:
- 缩小时间范围;
- 使用精确业务 Key;
- 查询走只读副本或备份;
- 管理查询限流;
- 关键链路采样;
- 高频业务查询放数据库或搜索引擎。
29.7 JVM 与操作系统
JVM 观察:
GC pause
heap usage
thread count
thread blocked
direct memory
mapped memory
safepoint
系统观察:
CPU usage
run queue
iowait
disk util
network bandwidth
tcp retransmit
file descriptors
swap
原则:
- 避免频繁 Full GC;
- 不盲目增大堆;
- 观察长尾延迟;
- 避免换页;
- 保持文件句柄余量;
- 不与其他重 IO 服务混部。
29.8 压测方法
压测维度:
- 固定消息大小;
- 阶梯提升 TPS;
- 写读混合;
- 故障注入;
- 事务消息;
- 顺序消息;
- 延迟消息;
- 冷查询;
- 长时间稳定;
- 重试风暴。
记录:
client latency
broker latency
disk throughput
network throughput
cpu
gc
error rate
lag
压测环境与生产磁盘、网络和副本策略越接近,结论越可信。
29.9 反模式
| 反模式 | 后果 |
|---|---|
| 盲目调大线程 | 压垮数据库 |
| 关闭刷盘换 TPS | 断电丢数据 |
| 无限重试 | 放大故障 |
| 全量轨迹 | 磁盘和带宽暴涨 |
| 只看平均延迟 | 掩盖 P99 |
| 单队列全局顺序 | 吞吐瓶颈 |
| 压测后不固化配置 | 结果不可复现 |
本章小结
RocketMQ 性能调优要先定义延迟和可靠性目标,再分层定位客户端、Broker、磁盘、网络和下游瓶颈。生产端关注复用、消息大小和重试;Broker 关注顺序写、刷盘、复制、页缓存和负载均衡;消费端关注单条耗时、幂等、线程和下游容量。所有优化都要以可复现压测和持续监控收尾。
思考题
- 为什么平均延迟不能代表用户体验?
- 同步刷盘和同步复制对延迟有什么影响?
- 消费线程越多越好吗?
- 冷读为什么会影响写入?
- 压测配置为什么要固化?