必须显式配置redis.NewClient的PoolSize(建议并发请求数2–4倍)、MinIdleConns(≥5)、MaxConnAge(30分钟),初始化后立即Ping验证,所有操作带context.WithTimeout,Key加服务前缀,Value统一json序列化,空值设"null"防穿透。

直接用 redis.NewClient 初始化后就开始 Set/Get,线上基本等于主动制造故障——连接池没调、context 没设超时、空值没兜底、结构体序列化失败,90% 的缓存问题都源于初始化阶段的疏漏。
redis.NewClient 必须显式配 PoolSize 和 MinIdleConns
默认 PoolSize=10、MinIdleConns=0,只适合本地调试。QPS 超 200 就开始排队,报错常是 redis: connection pool timeout,不是 Redis 慢,是连接池“没水了”。
-
PoolSize建议设为预估并发请求数的 2–4 倍(比如 QPS 300 → 设 60–120),但别超过 Redis 实例的maxclients(默认 10000) -
MinIdleConns必须 ≥5:防 SLB/NAT 网关静默断连,否则第一个请求必重连失败 - 务必加
MaxConnAge: 30 * time.Minute:避免连接老化后卡在READ状态不释放 - 地址别硬编码
"localhost:6379",从环境变量(如REDIS_ADDR)或配置中心读取
所有 Redis 操作必须带 context.WithTimeout
用 context.Background() 或裸 context.TODO() 调 client.Get,等于给 goroutine 埋雷:Redis 延迟一高,handler 就卡死,监控里只看到 goroutine 数暴涨、QPS 断崖下跌。
- HTTP handler 中统一用
ctx, cancel := context.WithTimeout(r.Context(), 300*time.Millisecond),优先继承 request 生命周期 - 写操作(
Set、Del、分布式锁)同样要超时;锁逻辑缺超时,会导致假死、资源长期被占 - 超时值不是越小越好:建议略大于 Redis P99 RT(比如 P99 是 80ms,设 200ms 较稳妥)
- 别在 handler 外层统一套一个超时,要按操作粒度设:
Get可 200ms,MGET可 300ms,写锁可 500ms
Key 加前缀 + Value 统一用 json.Marshal
多个服务共用一个 Redis 实例但 key 没前缀,或同一结构体混用 json.Marshal 和 gob.Encode,结果就是缓存读出来 invalid character 或直接 panic,日志里找不到源头。
立即学习“go语言免费学习笔记(深入)”;
- key 必须加服务前缀,比如
"user:" + uid;推荐用url.PathEscape或strconv转义,避免注入和冲突 - value 存 struct?先
json.Marshal再存;别直接传 struct 指针给Set——序列化失败会静默丢数据 - TTL 别设成 0:
Set(ctx, key, val, 0)表示“不设置过期”,不是“永不过期”,更不是“过期时间为 0 秒” - 查不到时写空值防穿透,推荐
client.Set(ctx, key, "null", 60*time.Second);业务层解包时判if val == "null" { return nil, nil }
穿透/击穿/雪崩必须在 Go 层轻量兜底
Redis 自身不解决这三类问题,指望客户端库自动处理?不存在的。Go 层必须自己加判断逻辑,但不用布隆过滤器或复杂锁,多数情况够用。
- 穿透:查 DB 返回
nil时,rdb.Set(ctx, key, "null", 60*time.Second);后续读到"null"就跳过 DB - 击穿:用
singleflight.Group包一层Do,同一 key 并发请求只放行一个查 DB,其余等待结果 - 雪崩:TTL 加随机扰动,
baseTTL + time.Duration(rand.Int63n(int64(2*time.Minute)));注意每次生成前用time.Now().UnixNano()做 seed,别用全局rand.Seed()
最易被忽略的是:初始化后没调 rdb.Ping(ctx).Err() 验证连通性,以及把 context.Background() 当“默认上下文”到处传——它没有 cancel 信号,是“永生上下文”,不是“默认上下文”。


















