Redis-基础
本页由同名 OneNote 笔记转换而来,可直接在线阅读;原始笔记文件见「Go语言相关笔记」页的原始链接。





















































逐步讲解
- func view1(c *gin.Context, who string) {
- 定义了一个函数 view1,接收 gin 的上下文 c 和一个字符串参数 who(看起来用来表示“谁”的前缀,比如用户名或作者 id)。
- pattern := fmt.Sprintf("%s:*", who)
- 构建 Redis key 的匹配模式,例如如果 who = "alice",pattern 就是 "alice:*"。用于后面执行 SCAN 来查找所有以 who: 开头的 key。
- var works []model.Work
- 创建一个空的切片,用来收集从 Redis 中读取到的作品数据(model.Work)。
- iter := Temp.RE.Scan(c, 0, pattern, 0).Iterator()
- 使用 Redis 的 SCAN 命令按模式遍历 keys:
- 第一个参数是上下文(这里直接传了 gin.Context),用于超时/取消。
- 0 表示从 cursor 0 开始扫描(第一次)。
- pattern 是前面构建的匹配模式。
- 最后一个 0 是 count(建议为扫描提供一个合理的 count,0 表示使用默认)。
- .Iterator() 返回一个迭代器对象(可以使用 iter.Next(ctx) 逐个遍历匹配到的 key,不会一次性把所有 key 拉到内存)。
- 使用 Redis 的 SCAN 命令按模式遍历 keys:
- for iter.Next(c) {
- 迭代器的循环,iter.Next(ctx) 每次移动到下一个匹配的 key,返回 true 则继续。
- 注意:SCAN 是增量式的,不会一次性阻塞所有 key。它可能在多次调用中返回相同 key(极少见),并且在遍历过程中如果有并发修改,结果不是强一致的。
- workData, err := Temp.RE.HMGet(c, iter.Val(), "title", "author", "content", "image").Result()
- 对当前 key(iter.Val() 返回 key 字符串)执行 HMGET,按顺序获取 hash 的四个字段:title, author, content, image。
- Result() 返回 ([]interface{}, error) —— 每个字段对应一个位置,字段不存在时返回 nil。
- 如果发生错误(比如连接失败),代码里选择用 continue 跳过当前 key。
- if err != nil { continue }
- 出错就跳过该 key,并继续下一个 key。
- work := model.Work{
Title: workData[0].(string),
Author: workData[1].(string),
Content: workData[2].(string),
Image: workData[3].(string),
}- 将返回的 interface{} 数组转换为 string 并构造 model.Work。
- 这里使用了断言 .(string)。如果某个字段为 nil(字段不存在)或不是 string 类型,会引发 panic —— 这是一个风险点。
- works = append(works, work)
- 把构造好的 work 加入列表。
- c.JSON(200, gin.H{"works": works})
- 用 gin 返回 HTTP 状态 200 和 JSON 对象,包含 works 字段。

附件文档全文:《redis 的知识》(go-redis 函数整理)
redis的知识

1. 添加缓存服务
ASSISTANT:
下面把示例代码里“每一个用到的函数/方法”的函数签名、参数说明、返回值与作用按模块整理,便于你快速查阅。内容基于 github.com/redis/go-redis/v9 与 gin。
一、Redis 客户端初始化与连通性
创建客户端
- 签名:GO
1func NewClient(opt *redis.Options) *redis.Client 2 - 参数:
- opt:Redis 连接配置。
- Addr string:地址,如 "redis:6379" 或 "127.0.0.1:6379"
- Password string:密码(示例为 "123456")
- DB int:数据库索引,默认 0
- PoolSize int:连接池最大连接数
- MinIdleConns int:保持的最小空闲连接
- opt:Redis 连接配置。
- 返回值:*redis.Client,客户端实例。
- 作用:构造一个连接 Redis 的客户端。
- 签名:
Ping 测试连通性
- 签名:GO
1func (c *Client) Ping(ctx context.Context) *redis.StatusCmd 2 - 参数:
- ctx:上下文(可控制超时/取消)。
- 返回值:*redis.StatusCmd(结果可通过 Err() 或 Result() 读取)。
- StatusCmd.Err() error:是否有错误
- StatusCmd.Result() (string, error):通常返回 "PONG"
- 作用:检测与 Redis 的连接是否正常。
- 签名:
上下文超时(标准库)
- 签名:GO
1func WithTimeout(parent context.Context, timeout time.Duration) (context.Context, context.CancelFunc) 2 - 参数:
- parent:父上下文
- timeout:超时时间
- 返回值:
- Context:带超时的上下文
- CancelFunc:取消函数(用完要调用)
- 作用:限制操作最长执行时间,避免挂死。
- 签名:
二、Gin 路由、处理函数与上下文
创建默认引擎
- 签名:GO
1func Default() *gin.Engine 2 - 返回值:*gin.Engine,包含 Logger、Recovery 中间件。
- 作用:快捷创建 Web 引擎。
- 签名:
注册 POST 路由
- 签名:GO
1func (engine *Engine) POST(relativePath string, handlers ...gin.HandlerFunc) 2 - 参数:
- relativePath:路由路径,如 "/tx-pipeline-demo"
- handlers:一个或多个处理函数
- 作用:绑定处理函数到 POST 路由。
- 签名:
处理函数类型
- 签名:GO
1type HandlerFunc func(*gin.Context) 2 - 参数:
- *gin.Context:请求上下文(含 Request、Response、Params 等)。
- 作用:处理单个 HTTP 请求。
- 签名:
从请求获取上下文
- 签名:GO
1func (c *gin.Context) Request.Context() context.Context 2 - 返回值:标准库 Context,用于传递给 Redis 等库。
- 作用:让后端操作受请求生命周期控制。
- 签名:
返回 JSON
- 签名:GO
1func (c *gin.Context) JSON(code int, obj any) 2 - 参数:
- code:HTTP 状态码,如 http.StatusOK
- obj:任意可序列化对象,常用 gin.H
- 作用:返回 JSON 响应。
- 签名:
gin.H(便捷 Map)
- 签名:GO
1type H map[string]any 2 - 作用:构建 JSON 对象。
- 签名:
启动服务
- 签名:GO
1func (engine *Engine) Run(addr ...string) error 2 - 参数:
- addr:可选地址,默认 ":8080"
- 返回值:error
- 作用:启动 HTTP 服务器。
- 签名:
三、Redis 事务(MULTI/EXEC)与乐观锁(WATCH)
使用事务批处理(在客户端维度)
- 签名(客户端方法):GO
1func (c *Client) TxPipelined(ctx context.Context, fn func(redis.Pipeliner) error) ([]redis.Cmder, error) 2 - 参数:
- ctx:上下文
- fn:回调,在其中向事务管道 pipe 排队命令
- 类型:func(redis.Pipeliner) error
- 返回值:
- []redis.Cmder:每条命令的结果对象
- error:提交阶段错误;若为 nil 表示 EXEC 成功
- 作用:封装 MULTI/EXEC,一次性按顺序执行回调中排队的命令,保证原子性并减少往返。
- 签名(客户端方法):
获取事务管道(如果你需要更细控制)
- 签名:GO
1func (c *Client) TxPipeline() redis.Pipeliner 2func (tx *Tx) TxPipeline() redis.Pipeliner 3 - 说明:返回一个事务管道,需手动 Exec/Close;一般直接用 TxPipelined 更简单。
- 签名:
乐观锁(WATCH)
- 签名:GO
1func (c *Client) Watch(ctx context.Context, fn func(*redis.Tx) error, keys ...string) error 2 - 参数:
- ctx:上下文
- fn:回调,在监视的键不被修改的前提下执行;类型:func(*redis.Tx) error
- keys:要监视的键列表
- 返回值:
- error:
- nil:提交成功
- redis.TxFailedErr:表示监视的键在执行前被其他客户端修改,事务未执行(需重试)
- 其他 error:连接/命令错误等
- error:
- 作用:基于乐观锁的事务控制。READ → 计算 → MULTI/EXEC 提交;若被改动,EXEC 不执行。
- 签名:
在 WATCH 回调里读取与提交
读取键值:
- 签名:GO
1func (tx *Tx) Get(ctx context.Context, key string) *redis.StringCmd 2 - 参数:
- ctx:上下文
- key:键名
- 返回值:*redis.StringCmd
- 常用读取:
- StringCmd.Result() (string, error)
- StringCmd.Int() (int, error) // 便捷转换为整数(示例中使用)
- StringCmd.Int64() (int64, error) // 另一个整数转换
- 错误:
- redis.Nil:键不存在(不是连接错误)
- 常用读取:
- 作用:读取当前值用于判断。
- 签名:
在事务中排队命令并提交:
- 签名(在 tx 上):GO
1func (tx *Tx) TxPipelined(ctx context.Context, fn func(redis.Pipeliner) error) ([]redis.Cmder, error) 2 - 参数与返回值:同 Client.TxPipelined
- 作用:在 WATCH 的安全窗口内,将多条写操作作为一个事务提交。
- 签名(在 tx 上):
事务相关错误
- redis.TxFailedErr(变量)
- 含义:监视的键在 EXEC 前被改动导致事务未执行,通常需要重试。
- redis.Nil(变量)
- 含义:值不存在(非致命错误,表示键不存在)。
- redis.TxFailedErr(变量)
四、Pipeliner 常用命令(在事务中或普通管道中都可用)
HSET(设置哈希字段)
- 签名:GO
1func (p Pipeliner) HSet(ctx context.Context, key string, values ...interface{}) *redis.IntCmd 2 - 参数:
- ctx:上下文
- key:哈希键名
- values:可为成对的 field, value 序列,或单个 map[string]interface{}
- 示例:HSet(ctx, "user:1001", "name", "Alice", "balance", "100")
- 或:HSet(ctx, "user:1001", map[string]interface{}{"name":"Alice","balance":"100"})
- 返回值:*redis.IntCmd(新添加的字段数量)
- 读取:IntCmd.Result() (int64, error),IntCmd.Val() int64
- 作用:批量设置哈希字段。
- 签名:
INCR(自增)
- 签名:GO
1func (p Pipeliner) Incr(ctx context.Context, key string) *redis.IntCmd 2 - 参数:
- ctx:上下文
- key:键名(不存在时按 0 起始)
- 返回值:*redis.IntCmd(自增后的值)
- 作用:计数器 +1。
- 签名:
DECR(自减)
- 签名:GO
1func (p Pipeliner) Decr(ctx context.Context, key string) *redis.IntCmd 2 - 参数/返回值:同 Incr
- 作用:计数器 -1(常用于扣库存)。
- 签名:
命令结果公共接口
- 签名:GO
1type Cmder interface { 2 Name() string 3 FullName() string 4 Args() []interface{} 5 Err() error 6 String() string 7} 8 - 说明:TxPipelined 返回的每条命令结果都实现 Cmder,可用于统一检查错误。
- 签名:
五、HTTP 常量与用法(标准库)
- HTTP 状态码(net/http)
- 常用:
- http.StatusOK(200)
- http.StatusInternalServerError(500)
- http.StatusConflict(409)
- 用途:表达请求成功、服务器错误、资源冲突(事务重试失败)。
- 常用:
六、其他标准库函数(示例中用到)
字符串格式化
- 签名:GO
1func Sprintf(format string, a ...any) string 2 - 作用:构造错误信息或日志字符串。
- 签名:
环境变量
- 签名:GO
1func Getenv(key string) string 2 - 作用:读取 REDIS_ADDR、REDIS_PASSWORD 等。
- 签名:
时间
- 当前时间:GO
1func Now() time.Time 2 - 格式化:GO
1func (t Time) Format(layout string) string 2- 常用 layout:time.RFC3339
- 休眠:GO
1func Sleep(d time.Duration) 2
- 当前时间:
七、用法串起来的流程提示(简化版)
- 创建客户端:redis.NewClient(&redis.Options{Addr, Password, ...})
- Ping 连通性:rdb.Ping(ctx)
- 路由与处理函数:engine.POST(..., func(c *gin.Context){ ... })
- 在处理函数中拿到 ctx:ctx := c.Request.Context()
- 原子事务批处理:rdb.TxPipelined(ctx, func(pipe redis.Pipeliner){ pipe.HSet(...); pipe.Incr(...); return nil })
- 乐观锁事务:rdb.Watch(ctx, func(tx *redis.Tx){ v, _ := tx.Get(ctx, key).Int(); tx.TxPipelined(ctx, func(p redis.Pipeliner){ p.Decr(...); p.Incr(...); return nil }); return nil }, key)
- 错误分支:
- errors.Is(err, redis.TxFailedErr):重试
- err == redis.Nil:键不存在
- 其他 err:返回 500
如果你还想看某个具体方法的更多字段、可选参数或返回类型细节(例如 IntCmd、StringCmd 的所有方法),告诉我方法名,我再进一步展开。
<hr />
<a href="https://chatboxai.app" target="_blank">
<img src='https://chatboxai.app/icon.png'>
<b style='font-size:30px'>Chatbox AI</b>
</a>
<p><a a href="https://chatboxai.app" target="_blank">https://chatboxai.app</a></p>
</div>