Redis设置值失败:Go代码卡在Set指令前无法执行
问题分析与解决方案
核心原因
你的Go代码卡在Set操作环节,是因为Redis哨兵返回给客户端的是主节点的Docker内部IP(172.18.0.2),而运行在宿主机的Go程序无法直接访问Docker网桥内部的私有IP,导致请求超时阻塞,永远执行不到后续的打印逻辑。
解决步骤
1. 修改Redis主节点的启动配置
在Docker Compose的redis-master服务的command中,添加主节点宣告配置,让它向哨兵报告宿主机可访问的IP和端口:
redis-master: # ... 其他配置保持不变 command: redis-server --appendonly yes --bind 0.0.0.0 --master-announce-ip 127.0.0.1 --master-announce-port 6379
--bind 0.0.0.0:允许Redis主节点接收来自任意IP的请求--master-announce-ip 127.0.0.1:告诉哨兵,主节点的可访问IP是宿主机的回环地址(如果是局域网内其他机器访问,替换成宿主机的局域网IP)--master-announce-port 6379:宣告主节点的可访问端口(对应宿主机的映射端口)
2. 完善Go代码的哨兵地址与错误处理
- 补全所有哨兵的宿主机端口地址,提升连接可靠性
- 不要忽略错误,添加错误打印方便排查问题:
package main import ( "context" "fmt" "time" "github.com/redis/go-redis/v9" ) var redisClient = redis.NewFailoverClient(&redis.FailoverOptions{ MasterName: "mymaster", // 补全三个哨兵的宿主机访问地址 SentinelAddrs: []string{"localhost:26379", "localhost:26380", "localhost:26381"}, DB: 0, }) var ctx = context.Background() func main() { err := redisClient.Set(ctx, "123", "value123", 10*time.Second).Err() if err != nil { fmt.Printf("Set key 123 failed: %v\n", err) return } err = redisClient.Set(ctx, "1234", "value1234", 10*time.Second).Err() if err != nil { fmt.Printf("Set key 1234 failed: %v\n", err) return } fmt.Println("Finished") }
3. 确认哨兵配置文件sentinel.conf的正确性
确保你的sentinel.conf包含以下核心监控规则:
sentinel monitor mymaster redis-master 6379 2 sentinel down-after-milliseconds mymaster 5000 sentinel failover-timeout mymaster 10000 sentinel parallel-syncs mymaster 1
此处的redis-master是Docker内部服务名,哨兵在容器网络内可正常通过该名称访问主节点。
4. 重启所有服务
执行以下命令重启Docker Compose服务,让配置生效:
docker-compose down docker-compose up -d
验证
重启后运行Go代码,应该能正常执行Set操作并打印Finished,也可以通过redis-cli连接主节点验证数据写入:
redis-cli get 123 redis-cli get 1234
内容的提问来源于stack exchange,提问作者TooLateForThis
相关产品推荐
相关产品推荐

