redis集群节点返回127.0.0.1是因未配置cluster-announce-ip等参数,导致客户端重定向失败;需设置真实ip、端口并重启节点,同时spring boot需正确启用lettuce集群模式、调优超时与连接池、开启tcp keepalive,并配置cluster-require-full-coverage no提升可用性。

redis-cli cluster nodes 返回节点 IP 是 127.0.0.1?
这是 Redis 集群最常被忽略的配置陷阱。客户端通过 redis-cli cluster nodes 获取到的节点地址,会直接用于后续重定向连接 —— 如果返回的是 127.0.0.1,那你的 Spring Boot 应用在远程访问时就会连到自己本地,必然失败。
根本原因在于 Redis 节点启动时未显式声明对外可访问的 IP。解决方法是:启动前在每个节点的 redis.conf 中设置:
cluster-announce-ip 192.168.1.100 cluster-announce-port 6379 cluster-announce-bus-port 6380
注意三点:
-
cluster-announce-ip必须填该节点真实对外 IP,不能是0.0.0.0或127.0.0.1 - 三个
announce参数需成对出现,缺一不可(否则部分节点可能广播错误 bus 地址) - 改完后必须
redis-cli cluster reset hard并重启节点,仅 reload config 不生效
Spring Boot 连接集群时反复报 MOVED/ASK 重定向异常
现象是日志里高频出现 MOVED 12345 127.0.0.1:6379 或 ASK 12345 192.168.1.101:6379,但应用始终无法稳定路由。这不是代码问题,而是客户端没正确启用集群模式支持。
关键检查点:
- 确认你用的是
Lettuce(Spring Boot 2.0+ 默认),且配置了spring.redis.cluster.nodes,而非spring.redis.host - 确保连接字符串中没有硬编码单节点地址,比如
redis://127.0.0.1:6379—— 这会让 Lettuce 自动降级为单机模式 - 检查是否误启用了
spring.redis.ssl=true但集群没配 TLS,会导致握手失败后反复重试触发重定向循环
一个快速验证方式:redis-cli -c -h 192.168.1.100 -p 6379 get testkey。加 -c 参数能模拟集群客户端行为,如果它也卡住或报错,说明集群拓扑本身就有问题。
timeout 设置过短导致集群连接频繁中断
Redis 集群的命令执行路径比单机长:请求 → 计算 slot → 查找目标节点 → 重定向(可能多次)→ 执行。若 spring.redis.timeout 设为 1000ms,在网络稍有延迟(比如跨可用区)时极易超时。
合理值参考:
- 内网同机房:建议
spring.redis.timeout=3000ms - 跨可用区或混合云:至少
5000ms,并同步调高spring.redis.lettuce.pool.max-wait(建议 ≥ timeout 值) - 千万别只调
timeout却忽略连接池的max-wait,否则连接池会先于网络超时抛出Could not get a resource from the pool
另外,tcp-keepalive 在集群场景下容易被低估。默认 Linux 的 tcp_keepalive_time=7200s(2 小时),而云环境 NAT 网关通常 300s 就断空闲连接。结果就是连接池里躺着一堆「已断开但未感知」的 socket,首次使用就报 Connection reset。
解决方案分两端:
- 服务端(redis.conf):设
tcp-keepalive 300(单位秒),让 Redis 主动发心跳探活 - 客户端(Lettuce):在
LettuceClientConfigurationBuilderCustomizer中启用底层 socket keepalive:clientOptions.socketOptions(…).keepAlive(true)
cluster-require-full-coverage=false 没配,集群一节点宕机就全挂
默认情况下,只要集群中任意一个哈希槽(slot)不可用(比如某个 master 宕机且无 replica),整个集群就会拒绝所有写操作,并返回 CLUSTERDOWN The cluster is down。这和你“只是某个节点挂了,其他业务应该还能跑”的预期完全相反。
修复只需在所有节点的 redis.conf 中加一行:
cluster-require-full-coverage no
然后逐个执行 redis-cli cluster reset hard + 重启。效果是:即使丢失部分 slot,只要请求的 key 对应的 slot 在线,命令就能成功。
注意这个参数治标不治本 —— 它掩盖了高可用缺陷。真正要做的,是确保每个 master 至少配一个 replica,并监控 cluster_state:ok 和 cluster_slots_assigned 是否 16384。
最后提醒一句:集群模式下,keys *、flushall 这类全局命令根本不可用,报 CROSSSLOT Keys in request don't hash to the same slot 是设计使然,不是配置错了。










