实战记录:WordPress 多站点共用 Redis 导致缓存冲突的终极解决方法
› 社区话题 › wordpress开发 › 实战记录:WordPress 多站点共用 Redis 导致缓存冲突的终极解决方法
- 该话题为空。

- 作者帖子
- 2025年9月13日 - 下午5:22 #1078
追光管理员? 实战记录:WordPress 多站点共用 Redis 导致缓存冲突的终极解决方法
作者:NewVFX 开发组
发布日期:2025年9月
标签:WordPress Redis 多站点 缓存冲突 实战踩坑?️ 问题背景
我们在服务器上部署了两个完全独立的 WordPress 多站点(Multisite)实例:
站点 A:/www/wwwroot/NewVFX
站点 B:/www/wwwroot/Multiple两个站点共用同一个 Redis 服务器(127.0.0.1:6379),并都安装了官方推荐的 Redis Object Cache 插件(v2.6.3)。
结果:灾难性的缓存污染!
用户在站点 A 登录,却跳转到站点 B 的后台
站点 A 的文章页面显示站点 B 的内容
后台设置互相覆盖,主题、插件状态混乱
诊断页显示一切正常,但实际数据写到同一个 DB 0,互相覆盖? 为什么会出现这个问题?
Redis Object Cache 插件默认使用相同的缓存 key 结构,例如:
wp:1:options
wp:1:transient:xxx其中 1 是当前站点的 blogid 但两个独立的 WordPress 安装,主站点 blogid 都是 1!
? 于是,两个站点生成了完全相同的缓存 key,写入同一个 Redis DB 0,导致数据互相覆盖、污染。
?️ 官方推荐方案(我们试过,但失败了)
根据 [插件官方文档](https://github.com/rhubarbgroup/redis-cache/configuration),我们尝试了所有“正规军”方案:
方案 1:设置 WPCACHEKEYSALT
在 wp-config.php 中添加:
define(\'WPCACHEKEYSALT\', \'newvfx\'); define(\'WPCACHEKEYSALT\', \'multiple\');
→ ❌ 失败原因:插件加载太早,常量未生效,或被多站点机制干扰。
方案 2:设置 WPREDISDATABASE
define(\'WPREDISDATABASE\', 1); // 站点 A define(\'WPREDISDATABASE\', 2); // 站点 B
→ ❌ 失败原因:无论放在 wp-config.php 哪个位置(顶部、中部、底部),诊断页永远显示 Database: 0,数据仍然写入 DB 0。
? 我们甚至修改了插件源码 object-cache.php 中的:
‘database’ => 0, // 这里是设置数据库的地方 值:0-15,一共16个数据库,具体数量可以在redis服务器设置中设置。默认是16个
改成:
protected function build_parameters() { $parameters = [ 'scheme' => 'tcp', 'host' => '127.0.0.1', 'port' => 6379, 'database' => 1, 'timeout' => 1, 'read_timeout' => 1, 'retry_interval' => null, 'persistent' => false, ];
→ ❌ 更诡异的是:保存文件后,一刷新页面,文件自动恢复成原始版本!
? 终极发现:插件自带“自我修复”机制,这是最关键的突破点!
Redis Object Cache 插件会在每次加载时检查 object-cache.php 文件的完整性。如果发现文件被修改,它会自动从插件包中重新复制原始文件覆盖你修改的版本!
这就是为什么“一刷新就恢复原状” 不是玄学,是插件的“保护机制”在作祟!
✅ 终极解决方案(亲测有效,100% 隔离)
? 核心思路:绕过插件的自我修复机制,强制写死数据库
步骤 1:复制文件到外部修改
1. 复制 object-cache.php 到临时目录
cp /www/wwwroot/NewVFX/wp-content/plugins/redis-cache/includes/object-cache.php /tmp/
2. 编辑 /tmp/object-cache.php
nano /tmp/object-cache.php
找到 buildparameters() 方法(约 650 行):
protected function buildparameters() { $parameters = [ \'scheme\' = \'tcp\', \'host\' = \'127.0.0.1\', \'port\' = 6379, \'database\' = 0, // ? 找到这一行 \'timeout\' = 1, // ... 其他配置 ];
修改为:
\'database\' = 1, // 站点 A 强制使用 DB 1 // 或 \'database\' = 2, // 站点 B 强制使用 DB 2
? 也可以在 foreach 循环后加一行强制覆盖:
$parameters[\’database\’] = 1;
✅ 保存文件。
步骤 2:删除原文件,替换为修改版
bash
删除原文件(关键!让插件无法“自我修复”)rm /www/wwwroot/NewVFX/wp-content/plugins/redis-cache/includes/object-cache.php
替换为修改后的文件
cp /tmp/object-cache.php /www/wwwroot/NewVFX/wp-content/plugins/redis-cache/includes/
设置正确权限
chown www-data:www-data /www/wwwroot/NewVFX/wp-content/plugins/redis-cache/includes/object-cache.php chmod 644 /www/wwwroot/NewVFX/wp-content/plugins/redis-cache/includes/object-cache.php
⚠️ 必须删除原文件再复制 如果直接在原位置修改,插件会检测到 MD5 变化并覆盖!
步骤 3:重启服务 & 清理缓存
bash
重启 PHP-FPMsudo systemctl restart php8.2-fpm
清空 Redis(重要!)
redis-cli FLUSHALL访问网站,触发缓存写入
curl -s https://dev.x.newvfx.com /dev/null
步骤 4:验证是否隔离成功
bash
查看 DB 1 是否有数据(站点 A)redis-cli -n 1 DBSIZE redis-cli -n 1 KEYS \"\"
查看 DB 2 是否有数据(站点 B)
redis-cli -n 2 DBSIZE
redis-cli -n 2 KEYS \”\”查看 DB 0 是否为空(应该为 0)
redis-cli -n 0 DBSIZE
✅ 如果 DB 1 和 DB 2 有数据,DB 0 为空 → 恭喜,冲突彻底解决!
当然可以在wp object cache后台直接看到当前使用的数据库名,如果用的是宝塔,可以直接在数据库—-redis中,实时可视化看到新设置的数据库是否在工作,以及具体数据。
- 作者帖子
- 在下方一键注册,登录后就可以回复啦。