Debian 上 RabbitMQ 数据迁移实操指南
一 迁移总览与方案选择
- 迁移对象包含两类:
- 元数据:vhost、exchange、queue、binding、用户与权限;
- 消息数据:自 3.7.0 起,消息按 vhost 存放在 msg_stores/vhosts 目录中,可按 vhost 单独备份与恢复。
- 常用方案对比与适用场景:
| 方案 |
核心思路 |
停机/中断 |
适用场景 |
关键要点 |
| 仅迁移元数据 + 重放/双读 |
导出并导入定义;生产先切新集群,消费双读至清零后切消费端 |
可做到近零停机(取决于业务双读改造) |
允许重放或可接受短暂重复 |
用 Management UI 或 API 校验;观察 Ready/Unacked 为 0 再切换 |
| Shovel 在线迁移消息 |
在源/目的集群启用 Shovel,从源消费并发送到目的 |
建议离线或低峰,避免链路抖动 |
需尽量保留在途消息 |
选择 ack 模式(如 on publish / on confirm)、设置 Reconnect delay、必要时开启 Add forwarding headers |
| 离线拷贝 Mnesia 数据目录 |
停源/停目的,拷贝 /var/lib/rabbitmq/mnesia/ 目录到新集群同名节点 |
需停机 |
同版本、同 Erlang Cookie、同节点名 |
注意节点名一致;必要时用 rename_cluster_node;权限 rabbitmq:rabbitmq |
二 方案一 元数据迁移与双读切换(不停消息)
- 导出元数据
- Management UI:登录 http://<源IP>:15672 → Overview → Export definitions → 下载 JSON(可勾选单个 vhost 或 All)。
- 或 HTTP API:
curl -u user:pass http://<源IP>:<端口>/api/definitions > rabbit_definitions.json
- 导入元数据到目标(Debian 新集群)
- Management UI:登录 http://<目标IP>:15672 → Overview → Import definitions → 上传 JSON。
- 或 HTTP API:
curl -u user:pass -H “Content-Type: application/json” -X POST -d @rabbit_definitions.json http://<目标IP>:<端口>/api/definitions
- 切换步骤(零停机思路)
- 将生产者切到目标集群;
- 消费者同时消费源与目标(双读),直至源集群队列 Ready=0 且 Unacked=0;
- 将消费者切到目标集群,完成切换。
- 验证
- UI 查看 vhost/队列/绑定/用户是否一致;
- API 快速核查:curl -s -u user:pass -XGET http://:<端口>/api/overview。
三 方案二 Shovel 在线迁移消息(尽量保留在途消息)
- 前提
- 源与目标集群网络互通;
- 两边创建相同 vhost、用户与权限;
- 建议两边均启用插件:
rabbitmq-plugins enable rabbitmq_shovel rabbitmq_shovel_management
- 创建 Shovel(UI 或 API)
- Source:amqp://user:pass@源IP:5672/目标vhost
- Destination:amqp://user:pass@目标IP:5672/目标vhost
- 关键参数建议:
- Prefetch count:按带宽与内存调优;
- Acknowledgement mode:
- no ack(不确认,吞吐高,风险大);
- on publish(发到目的端即确认源端,吞吐与可靠性折中);
- on confirm(目的端持久化确认后再确认源端,最稳妥);
- Reconnect delay:如 5 秒;
- Add forwarding headers:设为 true,便于追踪。
- 运行与切换
- 观察 Shovel 状态为 running,待源端待迁移队列 Ready 接近 0;
- 将生产者与消费者切换到目标集群;
- 校验目的端消息量与业务正确性后,按需停止 Shovel。
- 说明
- Shovel 本质是“从源消费→发往目的”,迁移完成后源端消息会被消费;
- 可按 vhost 为最小单元逐个迁移,降低风险。
四 方案三 离线拷贝 Mnesia 数据目录(同版本同节点名)
- 适用前提
- 同版本 RabbitMQ、同 Erlang Cookie、节点名一致(如 rabbit@host);
- 可接受停机窗口。
- 操作步骤(Debian 路径示例)
- 停源与目标节点:
systemctl stop rabbitmq-server
- 在源节点确定数据目录:
rabbitmqctl eval ‘rabbit_mnesia:dir().’
常见路径:/var/lib/rabbitmq/mnesia/rabbit@
- 备份并拷贝到目标(保持目录名一致):
tar czf rabbit@.tar.gz rabbit@
在目标节点相同路径解压并修正权限
chown -R rabbitmq:rabbitmq rabbit@
- 如节点名不一致,先重命名(在目标节点执行):
rabbitmqctl rename_cluster_node
- 启动目标节点并校验:
systemctl start rabbitmq-server
- 重要提示
- 自 3.7.0 起,消息按 vhost 存放在 msg_stores/vhosts 下,拷贝时需确保目录结构完整;
- 跨版本/跨主机名迁移不建议直接拷贝 Mnesia,优先使用“元数据 + Shovel/双读”。
五 迁移前后校验与常见问题
- 校验清单
- 元数据一致性:vhost、exchange、queue、binding、用户与权限;
- 消息一致性:对比源/目的 队列消息数 与关键业务计数;
- 运行状态:Shovel 为 running,无错误日志;
- 监控指标:Management Overview 的 Ready/Unacked、消息速率等。
- 常见问题与处理
- 节点名变更导致启动异常:使用 rabbitmqctl rename_cluster_node 修正后再启动;
- 权限问题:导入定义前在目标集群预置用户/权限或使用具备管理员权限的账号;
- 版本/插件差异:跨版本或上云前评估功能差异与限制(如云托管版与开源 RabbitMQ 在集群/接口/特性上存在差异)。