Spring Boot 连接 Redis 出现 READONLY You can't write against a read only replica 报错问题

一、问题描述

在 Spring Boot 项目中使用 StringRedisTemplateRedisTemplate 时,写入数据出现如下异常:

io.lettuce.core.RedisReadOnlyException: READONLY You can't write against a read only replica.

意思是:你连接的 Redis 节点是只读的副本(replica/slave),不允许执行写操作


二、问题原因

根据 Redis 部署方式不同,出现该问题的根源有两种:

1. 阿里云托管版 Redis(ApsaraDB for Redis)

  • 阿里云托管 Redis 在 读写分离架构下会提供两类连接地址:

    • 读写地址(Primary / Master)✅
    • 只读地址(ReadOnly / Replica)❌
  • 如果配置了只读地址,就会出现该报错。

2. 自建 Redis(部署在 ECS 上)

  • 如果你自己在 ECS 上安装 Redis,且 redis.conf 中配置了:

    replicaof <master-ip> <master-port>
    

    那么当前实例就是一个 从库,只能读,不能写。


三、排查步骤

无论哪种情况,首先确认连接的节点角色:

redis-cli -h <host> -p 6379 -a <password> ROLE
  • 如果返回:

    role:master
    

    → 主库,可以正常写入。

  • 如果返回:

    role:slave
    master_host: ...
    

    → 从库,只读,写入会报错。


四、解决方案

情况一:阿里云托管版 Redis

  1. 打开阿里云控制台 → Redis → 实例详情 → 数据库连接

  2. 找到 读写地址(一般不带 -ro 后缀),在 application.yml 里配置这个地址:

    spring:
      data:
        redis:
          host: r-xxxxxx.redis.rds.aliyuncs.com   # 使用读写地址
          port: 6379
          password: 123321
    
  3. 只读地址(带 -ro 后缀)只能用于读操作,不要用来写。


情况二:自建 Redis

  1. 如果只是测试或单机使用,直接把实例切回主库:

    redis-cli -h <公网IP> -p 6379 -a <密码> REPLICAOF NO ONE
    

    → 立刻成为主库,可以写。

  2. 修改 redis.conf 永久生效:
    注释掉或删除

    replicaof <master-ip> <master-port>
    

    然后重启 Redis 服务。

  3. 确认:

    redis-cli -h <公网IP> -p 6379 -a <密码> ROLE
    

    返回 role:master 即表示修复成功。


五、总结

  • 报错 READONLY You can't write against a read only replica 本质原因是:连接到了只读副本

  • 托管版:检查连接地址,使用 读写地址

  • 自建版:检查配置文件,确保当前节点是 主库

  • 排查时,建议第一步执行:

    redis-cli -h <host> -p 6379 -a <password> ROLE
    

    直接确认角色,避免走弯路。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐