必须使用 github.com/redis/go-redis/v9 初始化全局 redis.client,设 poolsize:20、minidleconns:5、maxconnage:30time.minute,地址密码db从环境变量读,初始化后立即用带超时的 context 调 ping() 验证连通性,失败则 log.fatal。

直接用 github.com/redis/go-redis/v9 初始化一个复用的 *redis.Client,挂到全局变量或结构体字段里,别找“Fiber-Redis”包——它不存在,也无需中间件封装。
怎么初始化 redis.Client 并确保它真正连得上
不能只调 redis.NewClient() 就完事。默认 PoolSize=10,线上 QPS 一过 200 就排队;MinIdleConns=0 会导致 SLB/NAT 断连后首个请求卡死重连。
- 显式设
PoolSize: 20(中小型服务够用),高并发可调到 50,但别超 Redis 的maxclients - 必须设
MinIdleConns: 5和MaxConnAge: 30 * time.Minute,防静默断连 - 地址、密码、DB 从环境变量读,比如
os.Getenv("REDIS_ADDR"),别硬编码"localhost:6379" - 初始化后立刻用带超时的 ctx 调
rdb.Ping(ctx).Err(),失败就log.Fatal,别让服务带病启动
在 Fiber handler 里安全读写缓存的写法
fiber.Ctx 不自带 Redis 实例,也不该往 c.Locals 塞 *redis.Client(GC 压力大且无必要)。最轻量的方式是闭包捕获全局 client 或通过结构体字段传入。
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
- 读缓存用
rdb.Get(ctx, key).Result(),返回(string, error);key 不存在时error是redis.Nil,不是nil,必须用errors.Is(err, redis.Nil)判断 - 写缓存用
rdb.SetEX(ctx, key, value, ttl),比Set+Expire少一次 round-trip,更原子 - value 是 struct?先
json.Marshal再存,字段必须首字母大写 +json:"field"tag - 所有操作必须带
context.WithTimeout,HTTP handler 中推荐:ctx, cancel := context.WithTimeout(c.Context(), 300*time.Millisecond),用完记得cancel()
差异化 TTL 和防穿透/击穿/雪崩怎么落地
Fiber 没有 @Cacheable 或 timeToLive 这种东西,TTL 差异化只能靠业务代码控制——这不是缺陷,是设计选择。
- 按业务类型设 TTL:用户资料用
2 * time.Hour,商品列表用10 * time.Minute,配置项用24 * time.Hour,直接在 handler 里 if/else 或查 map - 防穿透:DB 查不到时,存
rdb.Set(ctx, key, "null", 60*time.Second),后续读到"null"就跳过 DB - 防击穿:热点 key 过期瞬间大量请求打穿 DB,用
singleflight.Group包一层Do,同一 key 只放行一个查 DB - 防雪崩:TTL 加随机扰动,比如
baseTTL + time.Duration(rand.Int63n(int64(2*time.Minute))),每次生成前用time.Now().UnixNano()做 seed
最容易被忽略的是连接池参数和 context 超时——它们不出问题时完全隐形,一出就是 goroutine 卡死、QPS 断崖、日志里搜不到根因。宁可在启动时多验一次 Ping,也不要等压测时才发现 redis: connection pool timeout。










