Redis 版本升级与数据迁移实战

问题与适用环境

Redis 5.x、6.0 这类老版本服役多年后,通常会遇到三个问题:官方不再维护、安全漏洞无人修补;新版本的数据结构与命令用不上;老机器要下线,数据必须搬到新实例。直接停机拷贝 RDB 虽然简单,但业务停摆时间长;操作顺序不当,还可能把从库先升成主库、切流后丢数据,甚至被高版本 RDB 卡住无法回滚。

本文以 Redis 7.x 为目标版本,适用于单机、主从、哨兵(Sentinel)和集群(Cluster)四种形态,覆盖两件事:同机或同集群内的版本升级,以及跨实例、跨机房的数据迁移。示例主机为 redis-old(192.0.2.10)与 redis-new(192.0.2.20),端口 6379,哨兵端口 26379。

前置条件

  • 已阅读目标版本的 release notes,确认命令废弃与配置项变更(如旧版 SLAVEOF 已被 REPLICAOF 取代)。
  • 全量备份:每个节点执行一次 BGSAVE 并把 RDB 拷贝到异机保存,这是所有操作的回滚底线。
  • 确认 RDB 兼容方向:高版本 Redis 可以加载低版本的 RDB,低版本读不了高版本的 RDB。这意味着一旦用 7.x 持久化出新 RDB,就不能再回退到 6.x 二进制启动,回滚只能靠迁移前的旧备份。
  • 梳理大键:迁移前用 redis-cli --bigkeys 摸清大键分布,大键会阻塞全量同步与 MIGRATE,是后面几个坑的源头。
  • 应用侧确认连接方式:直连地址、哨兵服务名还是集群节点列表,切流动作完全不同。

分步操作一:滚动升级,先从后主

主从形态下升级的铁律是先升从库、最后升主库。从库升级重启期间只是少一个副本,主库对外服务不受影响;如果先升主库,主库重启会触发故障转移或直接中断写入,而且旧版本从库可能无法同步新版本主库的复制流。

逐台替换二进制并重启验证

在每一台从库上依次执行:替换二进制为 7.x,核对配置文件中已变更的配置项,重启后立刻验证版本与复制状态。确认该从库同步追平(master_link_status:up 且复制偏移量差值收敛)之后,再处理下一台。

# 从库上:确认当前角色与同步状态后再动手
redis-cli -h redis-old INFO replication | grep -E "role|master_link_status"
# 换二进制(示例为源码安装路径),重启服务
cp redis-7.2/bin/redis-server /usr/local/bin/
systemctl restart redis
# 重启后验证版本与角色
redis-cli INFO server | grep redis_version
redis-cli INFO replication | grep -E "role|master_link_status|slave_repl_offset"

主库升级:先切换再替换

所有从库升完后,不要直接重启主库。先把主库角色切换到一台已升级的从库上(哨兵形态执行故障转移、手动形态用 REPLICAOF 重新编排),等旧主库降为从库、同步追平后,再按从库流程升级它。这样整个过程中始终有一个新版本主库在提供服务,停机时间只剩切换瞬间的秒级抖动。

分步操作二:哨兵与集群形态的注意事项

  • 哨兵本身也要升级:顺序建议先升哨兵、再按「先从后主」升数据节点;新旧哨兵混跑期间不要同时改动 sentinel.conf 的监控配置,避免 quorum 判断不一致。
  • 手动触发故障转移前,确认目标从库 slave_priority 与数据延迟,用 SENTINEL failover <master-name> 优雅切换,不要靠杀进程碰运气。
  • 集群形态逐节点升级:先升全部从节点,再逐个对主节点执行 CLUSTER FAILOVER 切走主角色后升级。混跑期间不要执行 reshard、不要增删节点,等全部节点版本一致后再做拓扑变更。
  • 集群升级后用 CLUSTER NODES 核对每个节点的版本与状态,出现 handshake、fail 状态先排查网络与版本兼容再继续。
# 哨兵形态优雅切换主库
redis-cli -p 26379 SENTINEL master mymaster | grep -E "num-slaves|flags"
redis-cli -p 26379 SENTINEL failover mymaster
# 集群形态对单个主节点优雅切换(在其从节点上执行)
redis-cli -h redis-new CLUSTER FAILOVER

分步操作三:跨实例数据迁移四种方法对比

方法一:主从复制迁移(首选,停机最短)

把新实例挂为老实例的从库,借助 PSYNC 断点续传完成全量加增量同步,数据追平后在低峰期切流。同步期间老实例照常服务,真正停写只有切换的那几秒,适合绝大多数生产迁移。

# 在新实例上执行:挂为老实例的从库
REPLICAOF 192.0.2.10 6379
# 老实例带密码时先配置
CONFIG SET masterauth <老实例密码>
# 观察同步进度,直到 master_link_status 为 up 且偏移量差为 0
INFO replication

方法二:DUMP / RESTORE(小数据量)

用 DUMP 导出键的序列化值、RESTORE 写入新实例,可逐键搬运并保留 TTL。实现简单、可脚本化,但逐键串行、速度慢,且单键过大时容易超时,只适合键数量少、需要挑选着搬的场景。

方法三:MIGRATE 命令(中等规模、整库搬运)

MIGRATE 在实例间原子地搬运指定键,本质是 DUMP/RESTORE 的封装并支持批量键。常用选项:COPY 表示搬运后不删除源键(默认是移动,源键会被删),REPLACE 表示目标已存在同名键时覆盖。整个搬运过程会阻塞相关键,大键慎用。

# 把 session:1001 从老实例搬到新实例,保留源键、目标冲突时覆盖
MIGRATE 192.0.2.20 6379 "session:1001" 0 5000 COPY REPLACE
# 分批搬运前先估算键的体积,避免大键长时间阻塞
MEMORY USAGE session:1001

方法四:redis-shake(跨版本、跨云、需过滤转换)

redis-shake 是开源的 Redis 数据同步迁移工具,支持全量加增量同步,能在源与目标版本差异较大、需要按 key 前缀过滤、或跨云跨机房搬迁时使用,还支持断点续传与限速。代价是引入了额外组件,需要单独部署和监控其同步延迟。

四种方法取舍速记:同版本或相邻版本、追求最短停机用主从复制;少量键精细搬运用 DUMP/RESTORE;整库中等规模且可接受源键删除用 MIGRATE;跨大版本、要过滤或转换数据用 redis-shake。

分步操作四:切换流程清单

  1. 降低 TTL 影响:切流前排查热点键的 TTL,避免大量键恰好在切换窗口集中过期,在新实例上形成缓存雪崩;必要时提前错峰续期。
  2. 同步追平确认:新实例 INFO replication 显示连接正常、偏移量与老实例一致。
  3. 老实例置只读或停写入口(按业务方式:改配置中心、摘负载均衡或 CONFIG SET 配合应用停写),确认无新写入。
  4. 新实例执行 REPLICAOF NO ONE 提升为主库。
  5. 切流:修改应用连接地址(或哨兵服务名指向、集群节点列表),滚动重启应用。
  6. 观察 15–30 分钟:错误率、慢查询、新实例命中率与内存曲线正常后,再拆除老实例的复制关系。
  7. 回滚预案:观察期内若新实例异常,把流量切回老实例即可(老实例数据仍完整);注意一旦新实例已产生独立写入,回滚前必须评估这部分增量数据的处理方式,不能无脑切回。

验证:迁移后对账校验

  • 总量对账:两边分别执行 DBSIZE 与 INFO keyspace,逐库比对键数量,误差应为零或在停写窗口可解释的范围内。
  • 抽样比对:随机抽取各类数据结构的键,比对类型、长度与关键字段;哈希、集合类可比对元素个数加抽样成员。
  • 文件校验:新实例执行一次 BGSAVE,用 redis-check-rdb 检查生成的 RDB 是否完好,确认持久化链路可用再交付。
  • 业务验证:跑一遍核心读路径的冒烟用例,并观察一个完整业务高峰再下结论。
# 对账:分别在老、新实例上执行后逐库比对
redis-cli -h redis-old INFO keyspace
redis-cli -h redis-new INFO keyspace
redis-cli -h redis-new DBSIZE
# 持久化文件完整性校验(对新实例刚生成的 RDB 执行)
redis-check-rdb /data/redis/dump.rdb

常见问题

  • 全量同步迟迟不完成:多半是大键或老实例磁盘、网络带宽不足。先查大键清单与 INFO replication 的同步状态;必要时调大 repl-backlog-size,避免增量积压溢出后反复全量重传。
  • 回滚时低版本起不来:高版本写出的 RDB 低版本无法加载,这是兼容方向决定的,不是文件损坏。回滚只能恢复迁移前的旧 RDB 备份,或反向用主从复制把数据同步回老版本实例。
  • 切流后应用大面积报错:常见原因是客户端连接池仍持有老实例的长连接。切换后要滚动重启应用或主动刷新连接池;使用哨兵、集群模式的客户端要确认其能感知拓扑变化并重连。
  • MIGRATE 执行超时:目标键是大键时单次搬运会长时间阻塞。用 COPY 分批小步搬运,或改走主从复制、redis-shake 这类流式方案。
  • 从库升级完迟迟追不平:检查 masterauth、复制积压与磁盘空间,并确认没有误把 replica-read-only 之外的写保护配置带进新版本。

小结

升级记住顺序:备份先行、先从后主、主库先切换再替换、逐台重启逐台验。迁移先选对工具:主从复制停机最短,MIGRATE 与 DUMP/RESTORE 适合小步搬运,redis-shake 面向跨版本与复杂场景。最后切流要留回滚窗口,收尾用 DBSIZE、抽样比对和 redis-check-rdb 三重对账确认数据一键不差,再拆除老实例。

发表回复

后才能评论