初始化 rdb 客户端需正确设置 addr(docker 中用 host.docker.internal 或宿主 ip)、显式调用 ping 校验连接、password 和 username(acl)不遗漏、使用带超时的 context;set 过期时间必须为 time.duration 类型;哨兵模式须用 newfailoverclient 并配对 mastername 与 sentineladdrs;连接池参数需按压测调优,并强制健康检查。

怎么初始化 rdb 客户端才不会连不上
本地开发连不上 Redis,八成是 Addr 配错了或没启服务。默认地址 "localhost:6379" 看似简单,但 Docker 里跑 Go 程序时,localhost 指的是容器自己,不是宿主机;得换成 "host.docker.internal:6379"(Mac/Win)或宿主真实 IP(Linux)。另外,redis.NewClient 不会立即建连,只是配置好参数,真正校验要靠 rdb.Ping(ctx).Result() —— 这一步必须做,否则后续操作失败时错误堆栈里根本看不出是连接问题。
-
Addr必须带端口,写成"127.0.0.1:6379"比"localhost:6379"更稳(避免 DNS 解析干扰) - 密码非空时,
Password字段不能漏,且不能多加空格;Redis 6+ ACL 用户需用Username字段显式指定 - 别省略
ctx:用context.Background()可以,但生产环境建议传带超时的 context,比如context.WithTimeout(ctx, 5*time.Second)
rdb.Set 和 rdb.Get 的过期时间参数到底填什么
rdb.Set(ctx, key, value, expiration) 第四个参数是 time.Duration,不是秒数也不是字符串。填 0 表示永不过期;填 time.Minute 或 5 * time.Second 才生效;填 60 是错的 —— 它会被当成纳秒,实际过期时间几乎为零。
- 常见误写:
rdb.Set(ctx, "k", "v", 3600)→ 实际设了 3600 纳秒过期,等同于立刻失效 - 正确写法:
rdb.Set(ctx, "k", "v", 1*time.Hour)或rdb.Set(ctx, "k", "v", time.Duration(3600)*time.Second) -
rdb.Get返回redis.Nil错误表示 key 不存在,不是常规 error,要用if err == redis.Nil判断,别直接panic(err)
为什么哨兵模式下换主后请求还发到旧地址
用 NewClient(&Options{Addr: "10.0.1.10:6379"}) 直连某个 Redis 实例,哪怕配了哨兵,go-redis 也完全不知道哨兵存在 —— 它只会死磕这个地址。真要支持自动故障转移,必须用 redis.NewFailoverClient,且 MasterName 必须和哨兵配置中 sentinel monitor mymaster 的名字**完全一致(大小写敏感)**,SentinelAddrs 填的是哨兵节点地址(如 "10.0.1.10:26379"),不是 Redis 实例地址。
使用 uber-go/dig 在 Golang 中实现依赖注入——基于反射容器,提供 Provide/Invoke、dig.In/dig.Out 参数与结果对象,支持命名依赖等
- 错误示范:把
SentinelAddrs写成 Redis 主节点地址,或只填一个哨兵节点(单点失效风险) - 推荐写法:
SentinelAddrs: []string{"10.0.1.10:26379", "10.0.1.11:26379", "10.0.1.12:26379"} - 连接成功后,可调
rdb.Info(ctx, "replication").Result()看当前角色,验证是否真的连上了新主
并发高时为啥总卡在 rdb.Get 上
默认连接池大小是 CPU 核数 × 10,看着大,但若每个请求都新建 context 且不设超时,或 Redis 响应慢,连接池会迅速耗尽,后续请求就在 PoolTimeout 里排队。这不是代码写错了,是连接池参数没按压测结果调优。
- 关键配置项:
PoolSize(建议从 20–50 起调)、MinIdleConns(保持常驻连接,防冷启动抖动)、MaxConnAge(避免长连接老化,设 30m 左右) - 务必设
PoolTimeout,比如3 * time.Second,否则排队请求可能卡住整个 goroutine - 用
rdb.Set(ctx, key, val, 0).Err()时别忽略返回的 error,网络波动时它可能返回redis.Timeout,这比 panic 更值得监控
最常被跳过的其实是健康检查:上线前没跑通 rdb.Ping、没验证 rdb.Set 后 rdb.Get 能读回、没模拟过主从切换 —— 这些都不是“以后再补”的事,是发布前最后一道闸门。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










