RocketMQNotes

第 29 章:性能调优

zjc 于 2026-01-29 发布

这是《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 逻辑分组

优化:

  1. 复用生产者实例;
  2. 控制消息大小;
  3. 大对象放对象存储;
  4. 合理压缩;
  5. 设置有限重试;
  6. 批量发送需业务允许;
  7. 避免发送线程内做慢 IO;
  8. 保存 SendStatus 和业务键。

29.3 Broker 写入调优

写入路径:

request decode
  -> validate
  -> append commitlog
  -> replicate
  -> flush
  -> response

可调方向:

  1. 独立高性能数据盘;
  2. 评估同步刷盘与异步刷盘;
  3. 评估同步复制与异步复制;
  4. 控制 Topic 队列总数;
  5. 限制超大消息;
  6. 均衡 Broker 写入;
  7. 避免冷读挤占页缓存;
  8. 确认线程池和请求队列;
  9. 使用合适的系统 IO 调度。

任何可靠性降低都必须经过业务确认,不能为了压测数字关闭必要保护。

29.4 消费调优

先定位单条耗时:

deserialize
  -> validate
  -> database operation
  -> rpc call
  -> local business transaction
  -> metrics

常见优化:

优化 适用
优化慢 SQL 数据库瓶颈
索引和唯一键 查询慢
下游批量提交 高吞吐导入
增加消费者实例 CPU 或并发不足
增加消费线程 单机仍有余量
旁路非核心逻辑 可异步处理
降级审计细节 故障窗口

消费线程增加前必须确认数据库连接池、下游限流和顺序性要求。

29.5 队列与热点

热点表现:

  1. 单队列消费 lag 明显更高;
  2. 单 Broker 磁盘和 CPU 更高;
  3. 单排序 key 消息集中;
  4. 局部顺序导致吞吐受限。

处理:

  1. 调整队列选择;
  2. 拆分热点 Topic;
  3. 拆分热点业务 key;
  4. 非顺序业务改并发消费;
  5. Broker 均衡;
  6. 顺序流程异步旁路;
  7. 预估促销热点。

29.6 索引与查询调优

查询慢的原因:

  1. 时间范围过大;
  2. Key 选择性低;
  3. 冷数据读取;
  4. 磁盘竞争;
  5. 并发查询过高;
  6. 轨迹全量开启。

建议:

  1. 缩小时间范围;
  2. 使用精确业务 Key;
  3. 查询走只读副本或备份;
  4. 管理查询限流;
  5. 关键链路采样;
  6. 高频业务查询放数据库或搜索引擎。

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

原则:

  1. 避免频繁 Full GC;
  2. 不盲目增大堆;
  3. 观察长尾延迟;
  4. 避免换页;
  5. 保持文件句柄余量;
  6. 不与其他重 IO 服务混部。

29.8 压测方法

压测维度:

  1. 固定消息大小;
  2. 阶梯提升 TPS;
  3. 写读混合;
  4. 故障注入;
  5. 事务消息;
  6. 顺序消息;
  7. 延迟消息;
  8. 冷查询;
  9. 长时间稳定;
  10. 重试风暴。

记录:

client latency
broker latency
disk throughput
network throughput
cpu
gc
error rate
lag

压测环境与生产磁盘、网络和副本策略越接近,结论越可信。

29.9 反模式

反模式 后果
盲目调大线程 压垮数据库
关闭刷盘换 TPS 断电丢数据
无限重试 放大故障
全量轨迹 磁盘和带宽暴涨
只看平均延迟 掩盖 P99
单队列全局顺序 吞吐瓶颈
压测后不固化配置 结果不可复现

本章小结

RocketMQ 性能调优要先定义延迟和可靠性目标,再分层定位客户端、Broker、磁盘、网络和下游瓶颈。生产端关注复用、消息大小和重试;Broker 关注顺序写、刷盘、复制、页缓存和负载均衡;消费端关注单条耗时、幂等、线程和下游容量。所有优化都要以可复现压测和持续监控收尾。

思考题

  1. 为什么平均延迟不能代表用户体验?
  2. 同步刷盘和同步复制对延迟有什么影响?
  3. 消费线程越多越好吗?
  4. 冷读为什么会影响写入?
  5. 压测配置为什么要固化?