Redis 主从在线切换记录

背景

由于 Redis Master 所在实例主机需要下线维护,需进行主从切换。目标是将对线上业务的影响降至最低。当前架构如下图所示:

切换前

技术方案对比

方案 1:引入 Redis Sentinel

步骤:

  1. 部署 Redis Sentinel。
  2. 修改业务配置及代码,接入 Sentinel。
  3. 停止原 Master 进程(kill master)。
  4. 检查 Sentinel 状态。
  5. 建立新的主从逻辑。

优点:

  1. 切换操作简单,只需停止主库,Sentinel 可自动将 Slave 提升为 Master。

缺点:

  1. 需要部署新的中间件(Redis Sentinel)。
  2. 需要改动业务代码以支持 Sentinel 模式。

方案 2:直接切换

步骤:

  1. 将从库设置为可写:redis-cli -h redis-slave -p 6379 CONFIG set slave-read-only no
  2. 修改业务侧配置,将 Redis 地址指向可写的 Slave 实例,并重启业务应用。
  3. 确保主从同步完成后,停止主从同步:redis-cli -h redis-slave -p 6379 slaveof no one
  4. 建立新的主从逻辑。

优点:

  1. 操作符合直觉。
  2. 无需修改业务逻辑代码(仅需调整配置)。

缺点:

  1. 若切换过程中出现问题,回滚配置及重新发布业务项目耗时较长。
  2. 切换期间可能导致数据丢失。

方案 3:引入 4 层代理(HAProxy)

步骤:

  1. 部署 HAProxy,作为当前 Master 的代理。
  2. 修改业务侧配置,将 Redis 地址指向 HAProxy 代理地址,重启业务应用。
  3. 将从库设置为可写。
  4. 修改 HAProxy 配置,将后端指向可写的从库,并 reload 配置。
  5. 确保主从同步完成后,停止主从同步。
  6. 建立新的主从逻辑。

优点:

  1. 引入中间层 HAProxy 后,利用其支持动态 reload 配置及优雅关闭连接的特性,业务侧可无感知 Redis 主从切换。
  2. 主从切换时间短,影响面小。

缺点:

  1. 引入了新的中间件(HAProxy)。

方案选定

综合考虑稳定性与对业务的影响,稳妥起见,最终选择 方案 3(引入 HAProxy)

实施步骤

  1. 引入 HAProxy 后的架构

    image.png

  2. 执行主从切换

    以下是具体的切换脚本流程:

    export redis-slave=REDIS_SLAVE_IP
    export redis-master=REDIS_MASTER_IP
    
    # 1. 从库可写
    redis-cli -h redis-slave -p 6379 CONFIG set slave-read-only no
    
    # 2. 修改 haproxy 配置
    sed -i 's/redis-master/redis-slave/g' haproxy.cfg
    
    # 3. reload haproxy (平滑重载)
    haproxy -f haproxy.cfg -p /tmp/haproxy.pid -sf `cat /tmp/haproxy.pid`
    
    # 4. 确定主从同步结束
    redis-cli -h redis-slave -p 6379 info | grep master_sync_in_progress
    # 值需为 0
    
    # 5. 停止主从同步
    redis-cli -h redis-slave -p 6379 slaveof no one
    
    # 6. 建立新主从 (原 Master 变为新 Slave)
    redis-cli -h redis-master -p 6379 slaveof redis-slave 6379
    
    # 7. 确定新主从同步结束
    redis-cli -h redis-master -p 6379 info | grep master_sync_in_progress
    # 值需为 0
  3. 切换后架构

    image.png

小结

本文记录了 Redis 主从切换的方案取舍与具体操作流程。通过引入 HAProxy 代理层,实现了业务无感知的平滑切换,降低了维护风险。

说明

  • 版本兼容性:文中使用的 slaveof 命令及 slave-read-only 配置项在 Redis 5.0.0 及更高版本中已废弃,分别替换为 replicaofreplica-read-only。请根据实际使用的 Redis 版本调整相应命令。
  • 时效性:本文架构与操作基于 2020 年左右的技术环境记录,适用于传统主从架构场景。