必须用 github.com/redis/go-redis/v9;v8 及更早版本已归档不再维护,v9 强制 context 保障超时与资源释放,初始化后须立即 Ping 验证连接,否则上线后可能静默崩溃。

必须用 github.com/redis/go-redis/v9,别碰 v8 或更早版本;连接不验证、过期时间传错、context 复用,这三件事能让你的缓存服务在上线后静默崩掉。
用哪个库?v9 是唯一生产可用选项
v8 及以前的 github.com/go-redis/redis 已归档,不再维护。v9 不只是版本号升级,它强制所有方法带 context.Context,这是超时控制和资源释放的底线保障。
- 安装命令必须是:
go get github.com/redis/go-redis/v9 - 旧代码里 import 的
github.com/go-redis/redis/v8要全量替换成github.com/redis/go-redis/v9 - v9 中
redis.Client内部已集成连接池与自动重连,无需手动redis.Dial()或管理redis.Conn
连接初始化后不 Ping() = 没连上
rdb.Ping(ctx).Err() 不是可选步骤,是连接通路的唯一验证方式。只初始化 redis.NewClient() 不会真正建连,首次 Set() 或 Get() 才触发拨号 —— 但那时失败已无法优雅降级。
- 务必在
main()初始化 client 后立即调用:if err := rdb.Ping(ctx).Err(); err != nil { log.Fatal(err) } - Docker/K8s 环境下网络就绪慢,建议加简单重试:
for i := 0; i -
Ping()成功只说明“能连上”,不代表可读写:如果 Redis 配了密码、ACL 或只读从节点,仍可能后续Set()报NOAUTH或READONLY
Set() 过期时间必须是 time.Duration,60 不是 60 秒
redis.Client.Set() 第三个参数类型是 time.Duration,单位是纳秒。传 60 就是 60 纳秒,相当于立刻过期;传 0 表示永不过期;传 -1 在新版 v9 里会被转为永不过期,但语义不清,应避免。
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
立即学习“go语言免费学习笔记(深入)”;
- 正确写法:
rdb.Set(ctx, "key", value, 30*time.Minute)、5*time.Second - 错误写法:
rdb.Set(ctx, "key", value, 30)(纳秒)、"30s"(编译不通过) - 别把 HTTP 超时和缓存 TTL 混在一起设:
context.WithTimeout(r.Context(), 2*time.Second)控制本次请求生命周期,30*time.Minute控制 key 在 Redis 里存多久,两者独立
每个 Redis 操作都要独立 context,别复用或全局存
一个 context.Context 被多个 goroutine 共享时,只要其中任意一个取消或超时,整个 context 就失效,其他还在跑的 Redis 请求会全部收到 context canceled 错误。
- HTTP handler 中必须用
r.Context(),它是 per-request 的,天然安全 - 后台定时任务不能用
context.Background()硬编码,得自己新建:ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) - 绝对不要把
ctx存成全局变量、结构体字段或常量,尤其不能在初始化 client 时就绑定一个长期存活的 context - 并发读写同一 key 时,
GET + SET非原子,要用SetNX()或 Lua 脚本防击穿
最易被忽略的是:连接池没关、context 没控好、过期时间单位搞错 —— 这三者不会当场报错,但会在高并发或网络抖动时集中爆发,表现为大量超时、fd 耗尽、缓存永久失效。它们都藏在初始化和调用的“默认值”里,而不是显眼的 error 分支中。

















