这是《RocketMQ 零基础实战指南》的独立章节版。本章从概念、实操和生产排查三个视角展开,代码块保留了原书可直接运行的版本。 RocketMQ 的扩缩容不只是加减机器。Broker、Topic 队列、消费者、Proxy 和存储都有不同伸缩边界。目标是让写入容量、消费并行度、磁盘保留和网络带宽与业务负载匹配,并在变更中保持路由、位点和高可用状态可控。
20.1 容量瓶颈分层
| 层 | 瓶颈信号 |
|---|---|
| Producer | 发送超时、线程阻塞、本地事件积压 |
| Broker | 写入延迟、磁盘繁忙、请求堆积 |
| 存储 | 磁盘水位、文件增长过快 |
| Consumer | lag 增长、消费耗时高、死信增加 |
| Network | 带宽、重传、跨机房延迟 |
| Proxy | 连接数、请求队列、转发延迟 |
先判断瓶颈层级,再决定扩容对象。盲目扩消费者无法解决磁盘满,扩 Broker 也无法解决下游数据库慢。
20.2 Broker 扩容
新增 Broker 后,新 Broker 默认主要承接新 Topic 或新队列,已有 Topic 数据不会自动迁移。
变更步骤:
prepare capacity
-> install broker
-> configure replication and acl
-> register to nameserver
-> create or move queues
-> validate route
-> gradual traffic
检查项:
- Broker 版本一致;
- 副本分布合理;
- 磁盘目录独立;
- 告警和指标接入;
- Topic 权限同步;
- 管理工具可达;
- 高可用仲裁健康。
20.3 队列扩容
队列数影响:
- 写入分散度;
- 消费最大并行度;
- 顺序消息路由;
- 位点管理复杂度;
- 索引文件数量。
示例:
before: 4 queues
after: 8 queues
新增队列从末尾开始写入,消费者重平衡后可以分配新队列。减少队列要确认旧队列消费完成,且顺序业务不会受影响。
20.4 消费者扩容
消费者有效并行度受队列数限制:
8 queues
4 consumer instances -> useful
10 consumer instances -> at least 2 idle
扩容顺序:
- 先确认是消费处理瓶颈;
- 优化慢 SQL 和下游调用;
- 增加消费实例;
- 增加消费线程;
- 最后考虑增加队列;
- 观察重平衡和重复。
20.5 存储扩容
方式:
| 方式 | 特点 |
|---|---|
| 扩磁盘 | 简单,适合云盘 |
| 增加 Broker | 分散新写入 |
| Topic 队列迁移 | 需要治理旧数据 |
| 降低保留时间 | 减少容量,但影响回溯 |
| 归档冷数据 | 适合审计场景 |
磁盘满的处理顺序:
stop risky growth
-> confirm oldest data requirement
-> clean expired files
-> expand disk
-> rebalance traffic
-> review capacity model
不能在未确认消费位点前删除旧数据。
20.6 缩容流程
Broker 缩容:
- 确认节点是否仍有主副本;
- 迁移或等待 Topic 队列不再写入;
- 确认消费者位点完成;
- 摘除路由;
- 停止流量;
- 保留数据备份;
- 最后下线节点。
顺序:
readiness check
-> route change
-> drain
-> shutdown
-> backup
-> delete
缩容最容易出问题的不是停机,而是路由残留和数据仍被依赖。
20.7 自动伸缩
适合自动伸缩:
- Proxy 无状态层;
- 消费应用实例;
- 云主机规格调整;
- 前置网络带宽。
谨慎自动伸缩:
- Broker 有状态节点;
- 副本仲裁拓扑;
- Topic 队列数;
- 存储目录。
自动策略应以 lag、消息年龄、消费耗时、磁盘水位等多指标组合判断,避免单指标抖动引发频繁变更。
20.8 变更验证
扩缩容后检查:
route correctness
broker disk balance
queue assignment
consumer lag
send latency
consume latency
retry and dead letter
replica sync state
business reconciliation
保留回滚窗口:
- 原配置可恢复;
- 原节点可重新加入;
- 旧路由可回滚;
- 监控对比扩容前后;
- 业务指标确认正常。
20.9 常见错误
| 错误 | 后果 |
| 消费者超过队列数 | 实例空转 |
| 直接减少队列 | 历史消息漏消费或顺序破坏 |
| Broker 版本不一致 | 兼容性问题 |
| 新 Broker 无权限配置 | 生产失败 |
| 存储与日志混盘 | 扩容后仍磁盘瓶颈 |
| 未演练重平衡 | 变更窗口消费抖动 |
| 磁盘满后立即删文件 | 数据不可恢复 |
本章小结
弹性扩缩容要区分接入层、计算层、队列并行度和有状态存储层。消费者和 Proxy 可以较容易水平扩展,Broker、队列和副本拓扑则需要严谨的数据与路由治理。所有变更都应有容量评估、灰度窗口、验证清单和回滚方案。
思考题
- 为什么新增 Broker 后旧 Topic 流量通常不会自动迁移?
- 消费者实例数和队列数是什么关系?
- 减少队列前要确认什么?
- 哪些层适合自动伸缩,哪些不适合?
- 磁盘满时为什么不能直接删除最旧文件?