服务器上的 Redis 是 3.0.504,装在 C:\Program Files\Redis。这个版本来自微软 MSOpenTech 的 Windows 移植分支,发布于 2016 年——微软把 Redis 做到 3.0 就停止维护 Windows 端口了。
升级前我用 rename-command EVAL "" 把 Lua 入口整个禁掉,用来缓解 CVE-2025-49844(RediShell,Lua 沙箱逃逸)。缓解是有效的,但代价是 Lua 脚本功能彻底废掉,属于"为了安全把功能砍了"。
这次趁着系统升到 Windows Server 2019,把 Redis 一次性换到 8.10.2,跨了整整五个大版本。整个过程零数据迁移、零停机事故,下面是完整步骤和踩到的坑。
一、先确认:你的 Redis 是不是纯缓存
这一步决定整个升级的复杂度,务必先看配置。
我的 redis.windows.conf 里是这样:
save ""
appendonly no
maxmemory 256mb
maxmemory-policy allkeys-lrusave "" 清空了所有 RDB 快照保存点,appendonly no 关闭 AOF。也就是说:这是个纯内存缓存,没有任何数据落盘。
如果你的配置也是这样,那么恭喜——升级极其简单:
- 不需要备份和迁移 RDB / AOF 文件
- 不需要考虑 Redis 8 的 RDB v10 新格式、多段 AOF 这些不兼容点
- 停服务、换程序、启服务,缓存自己重建即可
即便升级过程中 Redis 短暂不可用,WordPress 也只是慢几秒,数据在 MariaDB 里,不会丢。
反过来,如果你开了持久化、Redis 里存了会话或队列任务,那就必须先 dump 出来,升级方式完全不同,别照抄本文。
二、客户端兼容性:跨 5 个大版本为什么没事
WordPress 用的是 Predis v2.4.1,很多人的顾虑是"8.x 会不会不认"。结论是不会,两点原因:
1. 协议一致。 Redis 8 默认仍然使用 RESP2 协议,RESP3 需要客户端主动发 HELLO 3 才会切换,Predis 不会这么做。
2. 命令一致。 WordPress 对象缓存只用到 GET / SET / DEL / EXPIRE / FLUSHDB 这类基础命令,从 3.0 到 8.x 语义完全没变。
三、版本选择:别下错包
Windows 上能拿到新版本 Redis 的来源主要有几个,我对比后的结论:
- redis-windows/redis-windows:提供编译好的 Windows 二进制,版本跟得上官方,推荐
- tporadowski/redis:老牌社区移植,稳定,但停在 5.0.14.1(2021 年)
- Memurai:商业产品,兼容 Redis 6/7,要授权,个人小站不划算
- WSL2 + 官方 Redis:我的系统是 2019 Datacenter 17763,WSL2 支持不完整,这条路别走
MSYS2 和 Cygwin 选哪个
新版本的发布页里通常有四种包,名字带 msys2 或 cygwin:
- msys2:编译成原生 Windows 程序,直接调 Windows API,I/O 和内存表现正常,选这个
- cygwin:靠
cygwin1.dll做 POSIX 系统调用翻译,吞吐和 fork 性能明显差,内存占用也更高
建议下带 with-Service 的那个,里面带了服务安装脚本。
四、第一个坑:GitHub 上挂的可能是源码,不是程序
这是最容易白忙一场的地方。打开某个仓库的 Release 页,展开 Assets 看到的如果是:
源代码(zip) 源代码(tar.gz)
这两个是 GitHub 自动生成的源码归档,里面是 C 语言源文件,下载下来在 Windows 上没法直接跑,得自己编译。
要找的是形如 Redis-8.10.2-Windows-x64-msys2-with-Service.zip 这种编译好的二进制包。如果当前仓库只有源码,就换到提供二进制的那个仓库下载,版本号是一样的。
五、下载与校验:别用服务器上的 curl
这台服务器上用 curl 下载大文件反复出问题——之前下载 MariaDB 压缩包、VC++ 运行库都下出过 0 字节文件,白白浪费时间。
所以这次的做法是:在本地电脑用浏览器下载,再通过远程桌面的磁盘映射传进服务器。
远程桌面连接时勾选本地磁盘:mstsc → 显示选项 → 本地资源 → 详细信息 → 勾选驱动器,服务器上会出现 \\tsclient\C。
传完之后必须校验,这一步不要省:
dir C:\Redis-8.10.2-Windows-x64-msys2-with-Service.zip certutil -hashfile C:\Redis-8.10.2-Windows-x64-msys2-with-Service.zip SHA256
文件大小应该在几十 MB。如果是几 KB 或者 0 字节,说明下载失败了,重新下。SHA256 应与发布页给出的值一致。
六、处理旧版本:删服务注册,不卸载程序
Redis for Windows 没有传统意义上的"卸载"。它就是一个目录 + 一个 Windows 服务注册。所以处理方式是:
先查服务名:
sc query type= service state= all | findstr /i "redis"
然后停掉并删除服务注册:
sc query Redis sc stop Redis sc delete Redis
sc delete 只是删掉服务注册,程序文件原封不动留在 C:\Program Files\Redis。
这个目录千万别删,它是回滚保险。稳定运行一两周确认没问题后,再清理不迟。
为什么必须先删旧服务
新包里的 install_redis.cmd 内容大致是这样:
@echo on cd /d %~dp0 sc create redis binPath= "\"%CD%\redis-server.exe\" --service-run \"%CD%\redis.conf\"" DisplayName= "Redis" start= auto depend= TCPIP sc description redis "Redis Cache Service" net start redis
注意它创建的服务名是 redis。而 Windows 服务名不分大小写,如果旧的 Redis 服务还在,就会撞名导致装不上。所以第这一步不能跳。
七、改配置:一个致命项必须处理
新包自带的 redis.conf 已经调得不错(save ""、bind 127.0.0.1、protected-mode yes 都对),但有一项必须改。
坑一:requirepass '' 会让缓存全挂
默认配置里有这么一行:
requirepass ''空引号会被当成一个真实的空密码。而 WordPress 的 Predis 客户端没有配置密码,于是所有连接都被拒绝,对象缓存直接失效。
处理方式:注释掉或删掉这行。有 bind 127.0.0.1 加 protected-mode yes 已经足够安全了。
坑二:不要拿 3.0 的旧 conf 去改
3.0 时代的这些指令在 7.x / 8.x 已经改名或移除,直接拿来用会报 unknown directive 导致服务起不来:
slave-serve-stale-data(已改为 replica 系列命名)hash-max-ziplist-entries/zset-max-ziplist-entries(已改为*-max-listpack-*系列)
正确做法是:用新包自带的 conf 作为基础,只改需要的几项,不要从旧文件迁移。
一份可直接使用的配置
# Redis 8.10.2 for Windows - 站点对象缓存 # 纯内存缓存:无 RDB、无 AOF save "" port 6379 maxmemory 256mb appendonly no maxmemory-policy allkeys-lru bind 127.0.0.1 protected-mode yes tcp-backlog 511 timeout 0 tcp-keepalive 0 loglevel notice logfile "C:/redis-windows-8.10.2/redis.log" databases 16 stop-writes-on-bgsave-error no rdbcompression yes rdbchecksum no dir "C:/redis-windows-8.10.2/" # 无 requirepass:仅监听回环 + protected-mode # CVE-2025-49844 已在 8.10.2 修复,不再需要 rename-command EVAL
几点说明:
- maxmemory 用 256mb。新包默认可能给 512mb,我机器只有 4GB,旧版本一直用 256mb 跑得好好的,保持一致最稳
- dir 和 logfile 改成你的实际路径
- 旧配置里那三行
rename-command EVAL ""不要带过来,8.10.2 已修复该 CVE,Lua 功能可以正常用了
顺手检查一下有没有默认加载模块:
findstr /i "loadmodule" C:\redis-windows-8.10.2\redis.conf
Redis 8 的包可能默认带 RedisJSON、RedisSearch 之类的模块。WordPress 对象缓存用不到它们,4GB 内存的机器上别让它们白占资源,有就注释掉。
八、安装与启动
必须右键"以管理员身份运行"命令行,否则 sc create 会拒绝访问。
cd /d C:\redis-windows-8.10.2 install_redis.cmd
九、验证
cd /d C:\redis-windows-8.10.2 sc query redis redis-cli.exe ping redis-cli.exe info server | findstr redis_version
期望看到三样东西:
STATE: 4 RUNNINGPONGredis_version:8.10.2
最后去 WordPress 后台 → Redis Object Cache 插件状态页,确认显示的版本号已经变成 8.10.2,状态是"Redis 可访问"。
十、回滚:一分钟回到旧版
因为旧目录完整保留着,出问题随时可以退回去:
sc stop redis sc delete redis sc create Redis binPath= "\"C:\Program Files\Redis\redis-server.exe\" --service-run \"C:\Program Files\Redis\redis.windows.conf\"" DisplayName= "Redis" start= auto depend= TCPIP net start Redis
执行前先确认旧配置文件的实际名字:
dir "C:\Program Files\Redis\*.conf"
常见的是 redis.windows.conf 或 redis.windows-service.conf,按实际名字替换上面那条命令。
十一、可能遇到的两个问题
1. sc create 报"服务已存在":旧服务没删干净,回到第六步重新处理。
2. 服务启动后立刻停止:看日志文件找原因。如果报缺少 dll,多半是 VC++ 运行库的问题——Windows Server 2019 上 C:\Windows\System32\msvcp140.dll 有时会变成 0 字节或损坏,装一下 VC_redist.x64.exe 即可。msys2 版本通常自带 MinGW 运行库,一般碰不到。
小结
这次升级能这么顺利,核心原因是把 Redis 当纯缓存用:没有持久化数据,就绕开了所有跨版本的数据格式兼容问题;客户端只走最基础的命令,就绕开了协议演进问题。
真正需要注意的反而是几个很细节的地方:别下成源码包、别用服务器上不靠谱的 curl、别把 requirepass '' 留着、别拿 3.0 的旧 conf 去改、别忘了先 sc delete 旧服务。
升级完之后,那个禁用了很久的 rename-command EVAL "" 也终于可以退休了——8.10.2 已经修复 CVE-2025-49844,Lua 不再是敞开的入口。