Redis 升级操作指南:单机与主从模式

背景

Redis 是一个开源的使用 ANSI C 语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value 数据库,并提供多种语言的 API。

据官方描述,在 Redis 的 Lua 脚本引擎的垃圾回收机制中存在 Use After Free 漏洞,经过身份验证的远程攻击者可通过构造特殊的 Lua 脚本触发,从而最终可能导致远程任意代码的执行等。

Redis is an open-source, ANSI C-based, network-enabled, in-memory and persistent log-based Key-Value database that provides APIs in multiple languages.

According to the official description, there is a Use After Free vulnerability in the garbage collection mechanism of Redis's Lua script engine. Unauthenticated remote attackers can trigger it by constructing a specific Lua script, which may eventually lead to the execution of arbitrary code remotely.

Affected Versions:

  • Redis < 6.2.20
  • Redis < 7.2.11
  • Redis < 7.4.6
  • Redis < 8.0.4
  • Redis < 8.2.2
  • Valkey < 8.1.4

官方已发布漏洞补丁及修复版本,请评估业务是否受影响后,升级至安全版本

The official has released the vulnerability patch and the fix version. Please assess whether your business is affected and then upgrade to the secure version.

修复建议

Repair suggestion

官方已发布新版本修复了该漏洞,请受影响的用户尽快升级到安全版本:

The official has released a new version which has fixed this vulnerability. Affected users are advised to upgrade to the secure version as soon as possible:

  • Redis >= 6.2.20
  • Redis >= 7.2.11
  • Redis >= 7.4.6
  • Redis >= 8.0.4
  • Redis >= 8.2.2
  • Valkey >= 8.1.4

Refer: https://github.com/redis/redis/releases

需求

docker-compose.yml 中的 Redis 镜像版本升级至 redis:6.2.20,并以最小影响 方式完成操作。由于 Redis 是有状态服务(挂载了 /data/redis-dev/data:/data),升级过程中需特别关注数据兼容性服务中断时间

yaml 复制代码
# @Author: johnny

version: '3.9'
services:
  redis:
    image: redis:6.2.20
    ulimits:
      nofile: 65535
    container_name: redis-dev
    restart: always
    ports:
      - 36379:6379
    volumes:
      - /data/redis-dev/data:/data:rw
    environment:
      - TZ=Asia/Shanghai
    command: redis-server --masterauth shield --requirepass shield --port 6379

🖥️ 单机模式升级

✅ 前提确认

  • 使用 Redis 持久化(RDB 或 AOF) ,数据存储于 /data/redis-dev/data
  • 从旧版本升级至 redis:6.2.20 属于小版本更新,Redis 官方保证向后兼容 (参考:Redis 升级策略);
  • redis:6.2.20 为官方稳定镜像。

结论:支持原地升级,数据兼容性风险极低。


🔧 推荐操作步骤(最小影响)

步骤 1:【可选但推荐】备份 Redis 数据
bash 复制代码
# 进入容器并触发 RDB 快照(确保数据落盘)
# 将 your_redis_password 替换为实际密码
docker exec redis-dev redis-cli -a your_redis_password BGSAVE
# 等待快照完成
sleep 5

# 备份整个数据目录
cp -r /data/redis-dev/data /data/redis-dev/data.bak_$(date +%Y%m%d)

💡 即使升级失败,也可快速回滚数据。


步骤 2:拉取新镜像
bash 复制代码
docker pull redis:6.2.20

步骤 3:执行滚动升级
bash 复制代码
# 停止并删除旧容器(数据卷保留)
docker-compose down

# 启动新容器(使用新镜像并挂载原数据卷)
docker-compose up -d

⏱️ 停机时间 ≈ 1~3 秒(容器启动耗时),客户端将短暂断连,Redis 数据无丢失。


步骤 4:验证服务状态
bash 复制代码
# 检查容器运行状态
docker-compose ps

# 查看 Redis 日志,确认无报错
docker logs redis-dev

# 验证版本与数据
docker exec redis-dev redis-cli INFO SERVER | grep redis_version
docker exec redis-dev redis-cli DBSIZE

# 查看所有数据库键空间信息
docker exec redis-dev redis-cli -a shield --no-auth-warning INFO keyspace

🚫 避免的高风险操作

操作 风险
直接执行 docker-compose up -d(未先执行 down 可能因镜像缓存仍使用旧版本
手动执行 docker stop + docker run 易遗漏端口、卷或 ulimit 配置
未备份直接升级 数据损坏时无法回退

🔄 回滚方案(如遇问题)

bash 复制代码
# 1. 在 docker-compose.yml 中回退至旧镜像版本
# 2. 恢复数据目录(如新版本损坏数据)
rm -rf /data/redis-dev/data
cp -r /data/redis-dev/data.bak_20251021 /data/redis-dev/data

# 3. 重启服务
docker-compose down && docker-compose up -d

✅ 本方案的优势

优势 说明
数据零丢失 持久化文件兼容,直接复用
停机时间短 仅容器重启时间(秒级)
配置一致 通过 Compose 文件确保环境一致性
快速回滚 备份 + 可控镜像版本

💡 长期维护建议

  1. 使用语义化标签 :避免 latest,采用 6.26.2.20(✅ 已满足)
  2. 监控升级过程 :配合健康检查(如 redis-cli PING
  3. 定期测试备份恢复:确保备份有效性
  4. 考虑主从架构:未来支持无感升级(先升从节点,再切换)

📘 单机模式命令汇总

bash 复制代码
# 检查键空间
docker exec redis-dev redis-cli -a shield --no-auth-warning INFO keyspace

# 备份数据
docker exec redis-dev redis-cli -a shield BGSAVE && sleep 10
cp -r /data/redis-dev/data /data/redis-dev/data.bak_$(date +%Y%m%d)
ll data/
ll data.bak_20251021/

# 拉取镜像并重启
docker pull redis:6.2.20
docker-compose down && docker-compose up -d

# 验证数据
docker exec redis-dev redis-cli -a shield --no-auth-warning INFO keyspace

🔁 主从模式升级

适用于 Redis 主从架构(Master-Slave) 的安全升级流程,假设两台主机分别运行 Master 与 Slave 实例,均通过 docker-compose 管理。

✅ 环境假设:

  • Master:容器名 redis-master,数据目录 /data/redis-master/data
  • Slave:容器名 redis-slave,数据目录 /data/redis-slave/data
  • 密码:shield
  • 镜像已更新为 redis:6.2.20(各主机 docker-compose.yml 中)

🚀 升级流程(先 Slave,后 Master)

🔁 阶段 1:升级 Slave 节点
  1. 确认主从同步正常
bash 复制代码
docker exec redis-slave redis-cli -a shield --no-auth-warning INFO replication
# 预期输出:role:slave, master_link_status:up, master_sync_in_progress:0
  1. 记录当前复制偏移量(用于回滚验证)
bash 复制代码
SLAVE_OFFSET=$(docker exec redis-slave redis-cli -a shield --no-auth-warning INFO replication | grep slave_repl_offset | cut -d: -f2)
echo "Slave offset before upgrade: $SLAVE_OFFSET"
  1. 备份数据
bash 复制代码
docker exec redis-slave redis-cli -a shield --no-auth-warning BGSAVE
sleep 10
cp -r /data/redis-slave/data /data/redis-slave/data.bak_$(date +%Y%m%d)
ls -lh /data/redis-slave/data*
  1. 升级 Slave 服务
bash 复制代码
docker-compose up -d redis-slave

⚠️ 请勿使用 docker-compose down && up -d,否则将影响所有服务。

  1. 验证升级结果
bash 复制代码
# 检查版本
docker exec redis-slave redis-cli -a shield --no-auth-warning INFO SERVER | grep redis_version

# 检查主从同步
docker exec redis-slave redis-cli -a shield --no-auth-warning INFO replication

# 检查数据完整性
docker exec redis-slave redis-cli -a shield --no-auth-warning INFO keyspace

✅ 预期状态:role:slavemaster_link_status:up,数据量与升级前一致。


🔁 阶段 2:升级 Master 节点
  1. 确认 Slave 已正常同步(Master 仍为旧版)
bash 复制代码
docker exec redis-slave redis-cli -a shield --no-auth-warning INFO replication
# 确保 master_link_status:up
  1. 备份 Master 数据
bash 复制代码
docker exec redis-master redis-cli -a shield --no-auth-warning BGSAVE
sleep 10
cp -r /data/redis-master/data /data/redis-master/data.bak_$(date +%Y%m%d)
ls -lh /data/redis-master/data*
  1. 升级 Master 服务
bash 复制代码
docker-compose up -d redis-master
  1. 验证主从同步与数据
bash 复制代码
# 检查 Master 版本
docker exec redis-master redis-cli -a shield --no-auth-warning INFO SERVER | grep redis_version

# 检查 Master 角色
docker exec redis-master redis-cli -a shield --no-auth-warning INFO replication
# 预期:role:master, connected_slaves:1

# 检查 Slave 连接状态
docker exec redis-slave redis-cli -a shield --no-auth-warning INFO replication
# 预期:master_link_status:up

# 测试读写同步
docker exec redis-master redis-cli -a shield --no-auth-warning SET upgrade_test "ok"
docker exec redis-slave redis-cli -a shield --no-auth-warning GET upgrade_test

✅ 返回 "ok" 表示主从同步正常,升级成功。


🔄 主从模式回滚方案

前提 :已按上述步骤完成数据备份(data.bak_YYYYMMDD

📌 回滚原则
  • 如 Master 已升级,先回滚 Master;
  • 再回滚 Slave;
  • 恢复旧镜像版本。

🔁 回滚 Slave 节点(如升级失败)
  1. 停止服务
bash 复制代码
docker-compose stop redis-slave
  1. 恢复数据
bash 复制代码
rm -rf /data/redis-slave/data
cp -r /data/redis-slave/data.bak_20251021 /data/redis-slave/data
chown -R 999:999 /data/redis-slave/data  # Redis 容器用户 UID 一般为 999
  1. 回退镜像版本

docker-compose.yml 中恢复旧版本:

yaml 复制代码
services:
  redis-slave:
    image: redis:6.0.20  # 回退版本
  1. 重启服务
bash 复制代码
docker-compose up -d redis-slave
  1. 验证状态
bash 复制代码
docker exec redis-slave redis-cli -a shield --no-auth-warning INFO replication

🔁 回滚 Master 节点(如升级失败)
  1. 停止服务
bash 复制代码
docker-compose stop redis-master
  1. 恢复数据
bash 复制代码
rm -rf /data/redis-master/data
cp -r /data/redis-master/data.bak_20251021 /data/redis-master/data
chown -R 999:999 /data/redis-master/data
  1. 回退镜像版本
yaml 复制代码
services:
  redis-master:
    image: redis:6.0.20  # 回退版本
  1. 重启服务
bash 复制代码
docker-compose up -d redis-master
  1. 验证主从同步
bash 复制代码
# Master
docker exec redis-master redis-cli -a shield --no-auth-warning INFO replication

# Slave
docker exec redis-slave redis-cli -a shield --no-auth-warning INFO replication

📋 主从升级注意事项

项目 说明
数据目录路径 使用 docker inspect redis-slave 确认实际挂载路径
权限控制 Redis 容器用户为 redis(UID 999),需确保备份目录权限正确
升级顺序 先 Slave,后 Master,避免双节点不可用
客户端配置 确保应用连接策略为 Master 写、Slave 读,升级期间避免写入失败
监控复制延迟 升级后持续关注 INFO replication 中的 offset 差距

✅ 主从升级成功标志

  • ✅ 主从角色正确(Master: role:master,Slave: role:slave
  • master_link_status:up
  • master_repl_offsetslave_repl_offset
  • ✅ 客户端读写正常
  • INFO keyspace 数据量与升级前一致

📘 主从模式命令汇总

升级 Slave 服务
bash 复制代码
# 检查数据完整性
docker exec redis-slave redis-cli -a shield --no-auth-warning INFO keyspace

# 检查主从同步
docker exec redis-slave redis-cli -a shield INFO replication

# 检查复制偏移量与延迟
docker exec redis-slave redis-cli -a shield --no-auth-warning INFO replication | grep slave_repl_offset
docker exec redis-slave redis-cli -a shield --no-auth-warning INFO replication | grep master_sync_in_progress

# 检查版本
docker exec redis-slave redis-cli -a shield --no-auth-warning INFO SERVER | grep redis_version

# 备份数据
docker exec redis-slave redis-cli -a shield BGSAVE && sleep 10
cp -r /data/redis/data /data/redis/data.bak_$(date +%Y%m%d)

# 检查备份
ll data/
ll data.bak_20251021/

# 更新服务
docker-compose down && docker-compose up -d
升级 Master 服务
bash 复制代码
# 检查数据完整性
docker exec redis-master redis-cli -a shield --no-auth-warning INFO keyspace

# 检查主从同步
docker exec redis-master redis-cli -a shield INFO replication

# 检查复制偏移量与延迟
docker exec redis-master redis-cli -a shield --no-auth-warning INFO replication | grep slave_repl_offset
docker exec redis-master redis-cli -a shield --no-auth-warning INFO replication | grep master_sync_in_progress

# 检查版本
docker exec redis-master redis-cli -a shield --no-auth-warning INFO SERVER | grep redis_version

# 备份数据
docker exec redis-master redis-cli -a shield BGSAVE && sleep 10
cp -r /data/redis/data /data/redis/data.bak_$(date +%Y%m%d)

# 检查备份
ll data/
ll data.bak_20251021/

# 升级服务
docker-compose down && docker-compose up -d

按照上述流程操作,Redis 单机或主从升级将实现安全、可控、可回滚,对业务影响最小。

相关推荐
不爱洗脚的小滕4 小时前
【Redis】三种缓存问题(穿透、击穿、双删)的 Golang 实践
redis·缓存·golang
源力祁老师4 小时前
ODOO数据文件(XML、CSV、SQL)是如何转换并加载到 Odoo 数据库
xml·数据库·sql
提笔了无痕4 小时前
什么是Redis的缓存问题,以及如何解决
数据库·redis·后端·缓存·mybatis
苏小瀚4 小时前
[MySQL] 索引
数据库·mysql
lang201509284 小时前
Spring Boot缓存机制全解析
spring boot·后端·缓存
lang201509284 小时前
Spring Boot SQL数据库全攻略
数据库·spring boot·sql
EndingCoder5 小时前
MongoDB基础与Mongoose ODM
服务器·javascript·数据库·mongodb·中间件·node.js
赋能大师兄5 小时前
SQLITE数据库完成数据增删改查
数据库·sqlite
一个天蝎座 白勺 程序猿6 小时前
深度解析:通过ADO.NET驱动Kdbndp高效连接与操作Kingbase数据库
数据库·.net·wpf·kingbase·金仓数据库