You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Redis集群调用clusterGetNodes仅返回单个节点求助

Redis集群节点获取异常问题

Spring配置

spring.data.redis.password=...
spring.data.redis.username=default
spring.data.redis.ssl.enabled=false
spring.data.redis.cluster.nodes=127.0.0.1:16379,127.0.0.1:17379,127.0.0.1:18379,127.0.0.1:19379,127.0.0.1:20379,127.0.0.1:21379

RedisTemplate Bean定义

@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
    RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
    redisTemplate.setConnectionFactory(redisConnectionFactory);
    redisTemplate.setKeySerializer(new StringRedisSerializer());
    redisTemplate.setHashKeySerializer(new StringRedisSerializer());
    redisTemplate.setHashKeySerializer(new JdkSerializationRedisSerializer());
    redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());
    redisTemplate.setEnableTransactionSupport(true);
    redisTemplate.afterPropertiesSet();
    return redisTemplate;
}

Docker Compose配置

version: '3.8'

services:
  redis-node-0:
    image: docker.io/bitnami/redis-cluster:7.2
    volumes:
      - ./redis-data/redis-cluster_data-0:/bitnami/redis/data
    ports:
      - "${REDIS_CLUSTER_PORT_0}:${REDIS_CLUSTER_PORT_0}"
    environment: &redis-environment
      REDIS_CLUSTER_DYNAMIC_IPS: no
      REDIS_PORT_NUMBER: ${REDIS_CLUSTER_PORT_0}
      REDIS_CLUSTER_ANNOUNCE_PORT: ${REDIS_CLUSTER_PORT_0}
      REDIS_PASSWORD: ${REDIS_MASTER_PASSWORD}
      REDIS_USERNAME: ${REDIS_CLI_USER}
      #REDIS_DISABLE_DEFAULT_USER: true
      REDIS_CLUSTER_ANNOUNCE_IP: ${REDIS_MASTER_HOST}
      REDIS_NODES: redis-node-0:${REDIS_CLUSTER_PORT_0} redis-node-1:${REDIS_CLUSTER_PORT_1} redis-node-2:${REDIS_CLUSTER_PORT_2} redis-node-3:${REDIS_CLUSTER_PORT_3} redis-node-4:${REDIS_CLUSTER_PORT_4} redis-node-5:${REDIS_CLUSTER_PORT_5}

  redis-node-1:
    image: docker.io/bitnami/redis-cluster:7.2
    volumes:
      - ./redis-data/redis-cluster_data-1:/bitnami/redis/data
    ports:
      - "${REDIS_CLUSTER_PORT_1}:${REDIS_CLUSTER_PORT_1}"
    environment:
      <<: *redis-environment
      REDIS_PORT_NUMBER: ${REDIS_CLUSTER_PORT_1}
      REDIS_CLUSTER_ANNOUNCE_PORT: ${REDIS_CLUSTER_PORT_1}

  redis-node-2:
    image: docker.io/bitnami/redis-cluster:7.2
    volumes:
      - ./redis-data/redis-cluster_data-2:/bitnami/redis/data
    ports:
      - "${REDIS_CLUSTER_PORT_2}:${REDIS_CLUSTER_PORT_2}"
    environment:
      <<: *redis-environment
      REDIS_PORT_NUMBER: ${REDIS_CLUSTER_PORT_2}
      REDIS_CLUSTER_ANNOUNCE_PORT: ${REDIS_CLUSTER_PORT_2}

  redis-node-3:
    image: docker.io/bitnami/redis-cluster:7.2
    volumes:
      - ./redis-data/redis-cluster_data-3:/bitnami/redis/data
    ports:
      - "${REDIS_CLUSTER_PORT_3}:${REDIS_CLUSTER_PORT_3}"
    environment:
      <<: *redis-environment
      REDIS_PORT_NUMBER: ${REDIS_CLUSTER_PORT_3}
      REDIS_CLUSTER_ANNOUNCE_PORT: ${REDIS_CLUSTER_PORT_3}

  redis-node-4:
    image: docker.io/bitnami/redis-cluster:7.2
    volumes:
      - ./redis-data/redis-cluster_data-4:/bitnami/redis/data
    ports:
      - "${REDIS_CLUSTER_PORT_4}:${REDIS_CLUSTER_PORT_4}"
    environment:
      <<: *redis-environment
      REDIS_PORT_NUMBER: ${REDIS_CLUSTER_PORT_4}
      REDIS_CLUSTER_ANNOUNCE_PORT: ${REDIS_CLUSTER_PORT_4}

  redis-node-5:
    image: docker.io/bitnami/redis-cluster:7.2
    volumes:
      - ./redis-data/redis-cluster_data-5:/bitnami/redis/data
    ports:
      - "${REDIS_CLUSTER_PORT_5}:${REDIS_CLUSTER_PORT_5}"
    depends_on:
      - redis-node-0
      - redis-node-1
      - redis-node-2
      - redis-node-3
      - redis-node-4
    environment:
      <<: *redis-environment
      REDIS_PORT_NUMBER: ${REDIS_CLUSTER_PORT_5}
      REDIS_CLUSTER_ANNOUNCE_PORT: ${REDIS_CLUSTER_PORT_5}
      REDISCLI_AUTH: ${REDIS_CLI_USER}
      REDIS_CLUSTER_REPLICAS: 1
      REDIS_CLUSTER_CREATOR: yes

volumes:
  redis-cluster_data-0:
    driver: local
  redis-cluster_data-1:
    driver: local
  redis-cluster_data-2:
    driver: local
  redis-cluster_data-3:
    driver: local
  redis-cluster_data-4:
    driver: local
  redis-cluster_data-5:
    driver: local

问题描述

执行以下代码获取集群节点时,每次仅返回单个节点(如127.0.0.1:19379,节点随机变化),但实际期望返回全部6个节点:

redisTemplate.getConnectionFactory().getClusterConnection()
        .clusterGetNodes()
        .forEach(x -> System.out.println(x.getHost() + ":" + x.getPort()));

解决建议
  • 检查Redis集群实际状态
    用Redis CLI连接任意节点,执行CLUSTER NODES命令,确认集群是否正常初始化,6个节点是否全部加入集群且状态正常。如果集群本身未正确搭建,客户端自然无法获取全量节点。

  • 修正Docker Compose的集群公告IP配置
    Docker Compose中REDIS_CLUSTER_ANNOUNCE_IP使用了${REDIS_MASTER_HOST},若该变量值为容器内部域名(如redis-node-0),外部Spring客户端无法解析,只能获取当前连接的节点。将REDIS_CLUSTER_ANNOUNCE_IP改为宿主机IP(如127.0.0.1),确保节点公告地址是客户端可访问的地址。

  • 开启Spring Redis客户端拓扑刷新
    添加以下配置强制开启集群拓扑刷新,让客户端定期同步全量节点信息:

    spring.data.redis.cluster.max-redirects=3
    spring.data.redis.cluster.topology-refresh-enabled=true
    spring.data.redis.cluster.topology-refresh-period=30000
    
  • 修复RedisTemplate序列化配置错误
    当前RedisTemplate重复设置了HashKeySerializer,最终会覆盖为JdkSerializationRedisSerializer,虽与节点获取问题无关,但属于配置错误,建议修正为单次设置:

    // 二选一,根据业务需求选择合适的序列化器
    redisTemplate.setHashKeySerializer(new StringRedisSerializer());
    // redisTemplate.setHashKeySerializer(new JdkSerializationRedisSerializer());
    
  • 使用ClusterRedisConnection获取完整拓扑
    绕过RedisTemplate,直接获取集群拓扑信息,该方式比clusterGetNodes()更可靠:

    ClusterRedisConnection connection = (ClusterRedisConnection) redisTemplate.getConnectionFactory().getConnection();
    RedisClusterTopology topology = connection.clusterGetTopology();
    topology.getNodes().forEach(node -> System.out.println(node.getHost() + ":" + node.getPort()));
    

内容的提问来源于stack exchange,提问作者Sha

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 12:35:08