Redis 做完故障切换,监控显示新主已经正常,Magento 仍不断报 READONLY You can't write against a read only replica。这说明应用当前连接的节点角色是 replica。问题不在 Magento 缓存内容,而在连接发现或旧连接没有刷新。

从报错的PHP节点确认它实际连到了谁

不要只在 Redis 管理机上看。登录发生错误的 Web、cron 和 consumer 节点,解析配置里的主机名,并连接同一个地址查询 role。

getent hosts redis.internal
redis-cli -h redis.internal -p 6379 ROLE
redis-cli -h redis.internal -p 6379 INFO replication

多节点环境可能只有部分机器缓存了旧 DNS,表现为请求随机报错。也可能 cache、page_cache、session 使用三套不同 Redis 配置,首页正常但登录失败,或者后台正常而 cron 报错。

先按报错上下文判断是哪一个用途:前台随机退出多半是 session 写失败;配置保存或缓存清理时报错多半是 cache;整页缓存刷新失败则看 page_cache。三套连接逐个做最小读写测试,能避免只修首页缓存而客户仍然掉线。

切主机制要和Magento连接方式匹配

如果使用云 Redis 的主节点 endpoint,配置应指向会随故障切换更新的写端点,而不是某台实例 IP。使用 Sentinel 或代理时,要确认 Magento 所用客户端和配置确实支持主节点发现,不能把 Sentinel 地址当普通 Redis 地址直连。

检查 app/etc/env.php 中 cache、page_cache、session 的 server、port、database 和持久连接设置。不要在三处共用同一 database 后靠前缀勉强区分,故障排查会非常混乱。

旧的PHP长连接不会因为DNS更新立刻消失

解析已经指向新主,但 PHP-FPM worker 仍持有到旧副本的 persistent connection 时,需要按发布流程平滑重载 PHP-FPM,并重启长期运行的 consumer。先摘流量再处理,避免直接重启造成结账请求中断。

修复后分别写入 cache、session,并跑一条 cron/consumer 任务。再做一次受控切换,观察应用恢复时间、DNS TTL 和连接重建。真正的解决不是手工改一次 IP,而是让下次故障切换时所有写连接都能自动跟随主节点。

受控切换时我会保留一条已登录客户会话并持续请求,同时监控新登录、购物车写入和后台保存。缓存可以短暂 MISS,但 Session 不能在主从切换时被写到两边形成分叉。如果架构无法保证会话一致性,至少要明确故障窗口和用户影响,而不是仅凭 Redis 监控变绿宣布恢复。