Windows11下Docker部署Redis Cluster,Go客户端连接失败求助
解决Windows 11下Docker Compose部署Redis Cluster的连接问题
问题概述
在Windows 11环境中,通过Docker Compose部署6节点Redis Cluster后,使用Go语言的redis/go-redis库连接集群时出现错误:
dial tcp 127.0.0.1:7001: connectex: 由于目标计算机积极拒绝,无法建立连接。
但单独运行单个Redis容器时,能正常连接127.0.0.1:6379。
核心问题分析
- Windows Docker的
host网络模式限制:Windows下Docker Desktop依赖WSL2虚拟机运行,network_mode: host配置会让容器使用WSL2的网络栈,而非Windows主机的网络栈。此时Windows主机直接访问127.0.0.1:7001是指向本地,而非容器所在的WSL2虚拟机,导致连接被拒绝。 - Redis Cluster未初始化:仅启动6个Redis节点并不等于创建了集群,必须执行
redis-cli --cluster create命令完成集群初始化,否则节点都是独立状态,无法被ClusterClient识别。 - Redis配置缺失集群参数:如果
redis.conf未开启集群相关配置,节点不会以集群模式运行,自然无法响应集群连接请求。
分步解决方案
1. 修正Docker Compose网络配置
移除network_mode: "host"配置,改用Docker默认的bridge网络(Windows下兼容),保留端口映射配置。修改后的docker-compose.yaml如下:
version: '3' services: redis-1: container_name: "redis-1" image: redis:7.2-rc-alpine3.18 ports: - 7000:7000 - 17000:17000 volumes: - "./redis/redis.conf:/etc/redis.conf" command: redis-server /etc/redis.conf --port 7000 redis-2: container_name: "redis-2" image: redis:7.2-rc-alpine3.18 ports: - 7001:7001 - 17001:17001 volumes: - "./redis/redis.conf:/etc/redis.conf" command: redis-server /etc/redis.conf --port 7001 redis-3: container_name: "redis-3" image: redis:7.2-rc-alpine3.18 ports: - 7002:7002 - 17002:17002 volumes: - "./redis/redis.conf:/etc/redis.conf" command: redis-server /etc/redis.conf --port 7002 redis-4: container_name: "redis-4" image: redis:7.2-rc-alpine3.18 ports: - 7003:7003 - 17003:17003 volumes: - "./redis/redis.conf:/etc/redis.conf" command: redis-server /etc/redis.conf --port 7003 redis-5: container_name: "redis-5" image: redis:7.2-rc-alpine3.18 ports: - 7004:7004 - 17004:17004 volumes: - "./redis/redis.conf:/etc/redis.conf" command: redis-server /etc/redis.conf --port 7004 redis-6: container_name: "redis-6" image: redis:7.2-rc-alpine3.18 ports: - 7005:7005 - 17005:17005 volumes: - "./redis/redis.conf:/etc/redis.conf" command: redis-server /etc/redis.conf --port 7005
2. 配置Redis集群参数
编辑./redis/redis.conf,添加或修改以下集群必备配置:
cluster-enabled yes cluster-config-file nodes.conf cluster-node-timeout 5000 appendonly yes
这些配置会让Redis节点以集群模式启动,并生成集群节点信息文件。
3. 启动容器并初始化Redis Cluster
- 启动所有Redis容器:
docker-compose up -d - 进入任意一个容器,执行集群创建命令(使用容器名称互访,自动分配主从节点):
执行命令后输入docker exec -it redis-1 redis-cli --cluster create redis-1:7000 redis-2:7001 redis-3:7002 redis-4:7003 redis-5:7004 redis-6:7005 --cluster-replicas 1yes确认集群创建。
4. 调整Go代码的连接逻辑
由于Redis Cluster初始化时会返回容器内部的地址(如redis-1:7000),Windows主机无法直接访问,需通过两种方式解决:
方式一:地址映射(推荐)
在ClusterOptions中添加DialContext,将容器内部地址替换为Windows本地映射地址:
import ( "context" "fmt" "net" "time" "github.com/redis/go-redis/v9" ) var ctx = context.Background() func main() { c := redis.NewClusterClient(&redis.ClusterOptions{ Addrs: []string{"localhost:7000", "localhost:7001"}, DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) { // 替换容器内部地址为本地映射端口 addrMap := map[string]string{ "redis-1:7000": "localhost:7000", "redis-2:7001": "localhost:7001", "redis-3:7002": "localhost:7002", "redis-4:7003": "localhost:7003", "redis-5:7004": "localhost:7004", "redis-6:7005": "localhost:7005", } if mappedAddr, ok := addrMap[addr]; ok { addr = mappedAddr } return net.DialTimeout(network, addr, 5*time.Second) }, }) if err := c.Ping(ctx).Err(); err != nil { fmt.Println("Unable to connect to redis " + err.Error()) } else { fmt.Println("Connected to Redis Cluster successfully!") } }
方式二:用Windows可访问地址创建集群
创建集群时使用host.docker.internal(Docker提供的Windows主机别名)作为节点地址,这样Redis返回的地址直接是Windows可访问的:
docker exec -it redis-1 redis-cli --cluster create host.docker.internal:7000 host.docker.internal:7001 host.docker.internal:7002 host.docker.internal:7003 host.docker.internal:7004 host.docker.internal:7005 --cluster-replicas 1
此时Go代码无需修改DialContext,直接使用原配置即可:
c := redis.NewClusterClient(&redis.ClusterOptions{ Addrs: []string{"127.0.0.1:7001"}, })
内容的提问来源于stack exchange,提问作者William Cole
相关产品推荐
相关产品推荐

