主题
20 · go-redis 实战
目标:在 Go 里正确连接 Redis,封装常用 GET/SET/ZSet,并接入 18 篇项目。
前置:19 · Redis 原理
库:redis/go-redis · 文档:redis.uptrace.dev
对照:Nodeioredis
1. 接入
bash
go get github.com/redis/go-redis/v91
go
package cache
import (
"context"
"time"
"github.com/redis/go-redis/v9"
)
func New(addr, password string, db int) *redis.Client {
return redis.NewClient(&redis.Options{
Addr: addr, // "127.0.0.1:6379"
Password: password,
DB: db,
})
}
func Ping(ctx context.Context, rdb *redis.Client) error {
return rdb.Ping(ctx).Err()
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Viper 增加:
yaml
redis:
addr: "127.0.0.1:6379"
password: ""
db: 01
2
3
4
2
3
4
main:Ping 失败则拒绝启动(或降级策略写清楚)。
2. 常用封装
go
func SetJSON(ctx context.Context, rdb *redis.Client, key string, v any, ttl time.Duration) error {
b, err := json.Marshal(v)
if err != nil {
return err
}
return rdb.Set(ctx, key, b, ttl).Err()
}
func GetJSON(ctx context.Context, rdb *redis.Client, key string, dest any) (bool, error) {
s, err := rdb.Get(ctx, key).Result()
if err == redis.Nil {
return false, nil
}
if err != nil {
return false, err
}
return true, json.Unmarshal([]byte(s), dest)
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
验证码:
go
rdb.Set(ctx, "captcha:"+phone, code, 2*time.Minute)1
排行榜:
go
rdb.ZIncrBy(ctx, "notes:hot", 1, noteID)
rdb.ZRevRangeWithScores(ctx, "notes:hot", 0, 9)1
2
2
3. Context 与超时
所有命令带 context;对请求路径用 c.Request.Context(),并考虑 WithTimeout。
对照 Node:别让 Redis 慢阻塞整条 API 无限等。
4. 动手清单
- [ ] 18 篇项目注入
*redis.Client - [ ]
/health可选检查 Redis Ping - [ ] 登录后把
userId → profile缓存 5 分钟;改资料时删 key - [ ] 单元测试:可用 miniredis 或跳过集成(标明)
- [ ] 错误区分
redis.Nil与真实故障
5. 项目驱动
| 接口 | Redis |
|---|---|
| 登录 | 可选存 token 黑名单 / session |
| GET 热门 | 先读 ZSet/缓存,未命中再 DB 回填 |
| 验证码 | SETEX;校验后 DEL |
6. 常见坑 + AI 审查
| 坑 | 说明 |
|---|---|
忽略 redis.Nil | 当成系统错误返回 500 |
| 无超时连接池默认值不查 | 读 Options 文档 |
| AI 用 redigo 与 go-redis 混抄 API | 统一 go-redis/v9 |
| 在循环里 Pipeline 不用 | 批量用 Pipeline 降 RTT |
