RocketMQ 迁移上云实践方案分享

背景

自建的 RocketMQ 集群部署在虚拟机上,由业务团队自行运维。这种方式存在几个明显问题:运维团队不够专业、精力有限、性能调优和监控也不够精细。经过评估,决定将 RocketMQ 迁移到公司的云平台上,由专业运维团队统一管理。

场景分析

系统中有两套 RocketMQ 集群:

  1. 数据同步集群:用于 Canal 同步 binlog 数据。这套可以通过暂停 Canal 推送消息,等待老 MQ 消费完在途消息,然后切换到新 MQ。利用 binlog 位点记录,重启 Canal 继续推送,确保消息不丢失也不重复。

  2. 业务集群:处理业务消息。由于业务 SLA 要求 99.99%,消息不能暂停写入,而且部分 topic 是顺序消息,切换方案较为复杂。

下面重点讨论业务集群的迁移方案。

Broker 权限控制

RocketMQ 的 broker 节点有三种权限设置:

  • brokerPermission=2:只写权限
  • brokerPermission=4:只读权限
  • brokerPermission=6:读写权限

通过 updateBrokerConfig 命令可以动态修改 broker 权限。例如设置只读:

bash 复制代码
./mqadmin updateBrokerConfig -b x.x.x.x:10911 -n 'x.x.x.x:9876' -k brokerPermission -v 4

将 broker 设置为只读后,该 broker 的写入流量会自动分配到集群中的其他节点。

切换方案

方案一:整体切换

优点:全部 Topic 一起切换,周期短。

缺点:风险相对较高。

步骤

  1. 新 broker 节点同时注册到旧 NameServer 和新 NameServer,运行一段时间稳定
  2. 设置新 broker 为可写不可读,在控制台导入全部 topic 和 consumer group
  3. 设置老 broker 为只读不可写
  4. 观察老 broker 消费完成剩余消息
  5. 设置新 broker 为可读可写
  6. 运行稳定后下线老 broker
  7. 业务系统修改 NameServer 配置,重启容器
  8. 运行稳定后下线老 NameServer

回退:老 broker 改为可写不可读,新 broker 改为不可写可读,等新 broker 消费完,老 broker 改为可读可写。

方案二:按 Topic 分批切换

优点:按 topic 逐个切换,风险较低。

缺点:切换周期长。

步骤

  1. 新 broker 节点同时注册到旧 NameServer 和新 NameServer,运行一段时间稳定
  2. 在新 broker 创建 topic,设置为可写不可读,并创建对应的消费组(此时新老 broker 该 topic 双写)
  3. 将老 broker 的 topic 设置为只读不可写
  4. 观察老 broker 消费完成
  5. 新 broker 的 topic 设置为可读可写
  6. 每次切换 10% 的 topic,直到完成
  7. 全部切换完成后修改 NameServer 配置
  8. 运行稳定后下线老 NameServer

回退:老 broker 的 topic 设置为可写不可读,新 broker 的 topic 设置为不可写可读,等新 broker 消费完之后,老 broker 的 topic 设置为可读可写。

方案三:混合方案(最终采用)

结合前两个方案的优点,分阶段执行:

阶段一:新 broker 节点同时注册到旧 NameServer 和新 NameServer,运行一个星期。

阶段二:试点一个非顺序推送且消费的 topic,按方案二执行,运行一个星期。

阶段三 :筛选出顺序推送且顺序消费的 topic,在业务低峰期按方案二执行。这里有个细节:客户端默认 30 秒刷新一次 topic 配置(由 pollNameServerInterval 参数控制),切换期间可能会有相同 hash 的消息分别发送到新老 broker,导致顺序不正确。

顺序消息推送可以采取以下改善措施:

  • 评估是否可以临时减少顺序消息生产者节点数量
  • 如果是调度触发发送,可以先停止调度
  • 将生产者 pollNameServerInterval 设置为 3 秒,缩短刷新时间

阶段四:执行方案一,将剩余 topic、consumer 全量切换。此时顺序推送的 topic 已经完成切换,新 broker 不需要修改读写权限。

实操总结

试点 Topic 切换(非顺序消费场景)

  1. 在老集群查看 topic 的队列数和对应的 consumer
  2. 在新集群创建 topic
  3. 在新集群创建 consumer
  4. 老集群 topic 权限设置为只读不可写
  5. 老集群消费完之后 topic 权限设置为不可读不可写
  6. 监控确认无误

顺序消费场景

  1. 收集顺序消费场景的 topic
  2. 单独切换,使用缩短 pollNameServerInterval 等措施保证顺序性

全量切换

执行方案一,将剩余 topic、consumer 全量切换,剔除已经完成的顺序消费 topic。

注意事项

  1. NameServer 配置 :生产环境 NameServer 已经扩展到多个节点,各中台服务去掉自己的 rocketmq.name-server 配置,使用全局配置。如果是自定义 key,配置修改为 自定义key=${rocketmq.name-server}

  2. 客户端版本升级:择机升级客户端版本到 5+,解决顺序消费重置 offset 问题。

  3. 权限回收:切换完成后回收老 broker 管理员账号,防止在老 broker 创建 topic。

总结

RocketMQ 的迁移上云是一个需要仔细规划的过程。根据业务场景选择合适的切换方案,做好回退预案,并在每个阶段充分观察和验证,才能保证迁移的平滑和安全。对于顺序消息这类特殊场景,需要额外的措施保证消息顺序性,不能一刀切地采用统一的切换策略。

相关推荐
朱雨鹏2 天前
图解RocketMQ运行原理
后端·rocketmq
JWASX2 天前
【RocketMQ 生产者和消费者】- 事务消息的使用
java·rocketmq·java-rocketmq
爱吃山竹的大肚肚3 天前
RocketMQ 4.x + Spring Boot 生产级集成方案(完整笔记)
spring boot·rocketmq·java-rocketmq
小鸡脚来咯4 天前
RocketMQ 常见面试题汇总
rocketmq
隔叶听风4 天前
RocketMQ 与 Kafka 长轮询详解
数据库·kafka·rocketmq
C182981825754 天前
Rocketmq
java·rocketmq·java-rocketmq
czlczl200209254 天前
RocketMQ如何实现与其它事务的一致性
rocketmq
yyongsheng5 天前
微服务项目整合rocketMq
微服务·架构·rocketmq
阿里云云原生13 天前
秒触达、零资损:亲宝宝基于 RocketMQ 支撑千万家庭实时互动与成长记录
serverless·rocketmq