READONLY 错误是什么
READONLY You can't write against a read only replica 表示写命令被发到了副本上。Redis 的主从复制是单向的,副本默认只读,所以这不是数据或权限问题,而是路由问题:要么客户端指向了副本,要么故障切换后仍指向已经降级为副本的旧主。
基本信息
| 错误文本 | READONLY You can't write against a read only replica |
|---|---|
| 典型根因 | 写请求发到副本,含切换后仍指向旧主 |
| 确认角色 | INFO replication 的 role 字段 |
| 拓扑查询 | CLUSTER NODES、CLUSTER SLOTS 或 Sentinel 的主库地址查询 |
| 副本开关 | replica-read-only 默认 yes |
| 修复方向 | 刷新拓扑后写新主,而不是改副本的可写开关 |
典型使用场景
- 切换后报错定位:故障切换窗口内客户端仍指向旧主,是最常见的一幕
- 发布期排查:只配置了单一地址的客户端在新拓扑下会持续报错
- 代理层核对:确认代理是否跟随拓扑自动更新后端列表
- 误操作核对:确认没有变更把主库直接降级成了副本
- 演练验收:主从切换演练后确认所有写客户端都能自愈
最小示例
最小示例
redis-cli -h <host> -p <port> INFO replication | grep -E '^role|master_link_status' # 确认角色
redis-cli -h <host> -p <port> INFO server | grep -E 'tcp_port|redis_version' # 确认连的是哪个实例
redis-cli -c -h <cluster_node> CLUSTER NODES # 集群拓扑与主节点
redis-cli -h <sentinel> SENTINEL get-master-addr-by-name mymaster # 哨兵记录的当前主
redis-cli -h <replica> CONFIG GET replica-read-only # 副本只读开关(默认 yes)根因与处置
| 根因 | 识别方式 | 处置 |
|---|---|---|
| 写请求打到副本 | 该实例 role 为 slave | 修正客户端路由,只有读流量才走副本 |
| 切换后仍指向旧主 | 旧主 role 已变为 slave | 刷新拓扑,或改用支持拓扑发现的客户端 |
| 客户端只配单一地址 | 配置里没有哨兵或集群节点列表 | 换成带拓扑发现能力的连接配置 |
| 代理后端未更新 | 代理健康检查与拓扑同步滞后 | 修代理的后端发现逻辑 |
| 误把主库改成副本 | 实例 role 突然变为 slave | 核对变更记录并恢复主从关系 |
写请求重试到同一个副本永远不会成功;正确做法是刷新拓扑后写到新主,读请求才可以继续留在副本上。
不要靠在副本上关闭只读开关来「解决」报错:副本接受写会与主库数据分叉,后续复制与切换都会出问题。