GoClub Pro

Redis-基础

最近更新:2026-10-24
本页由同名 OneNote 笔记转换而来,可直接在线阅读;原始笔记文件见「Go语言相关笔记」页的原始链接。

笔记图片
笔记图片
笔记图片
笔记图片
笔记图片
笔记图片
笔记图片
笔记图片
笔记图片
笔记图片
笔记图片
笔记图片
笔记图片
笔记图片

笔记图片

 

笔记图片

 

笔记图片

 

笔记图片

 

笔记图片
笔记图片

 

笔记图片

 

笔记图片
笔记图片
笔记图片
笔记图片
笔记图片
笔记图片
笔记图片
笔记图片
笔记图片
笔记图片
笔记图片
笔记图片
笔记图片
笔记图片
笔记图片
笔记图片
笔记图片
笔记图片

笔记图片
笔记图片
笔记图片
笔记图片
笔记图片
笔记图片
笔记图片
笔记图片
笔记图片
笔记图片

 

笔记图片
笔记图片
笔记图片
笔记图片

逐步讲解

  1. func view1(c *gin.Context, who string) {
    • 定义了一个函数 view1,接收 gin 的上下文 c 和一个字符串参数 who(看起来用来表示“谁”的前缀,比如用户名或作者 id)。
  2. pattern := fmt.Sprintf("%s:*", who)
    • 构建 Redis key 的匹配模式,例如如果 who = "alice",pattern 就是 "alice:*"。用于后面执行 SCAN 来查找所有以 who: 开头的 key。
  3. var works []model.Work
    • 创建一个空的切片,用来收集从 Redis 中读取到的作品数据(model.Work)。
  4. 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 拉到内存)。
  5. for iter.Next(c) {
    • 迭代器的循环,iter.Next(ctx) 每次移动到下一个匹配的 key,返回 true 则继续。
    • 注意:SCAN 是增量式的,不会一次性阻塞所有 key。它可能在多次调用中返回相同 key(极少见),并且在遍历过程中如果有并发修改,结果不是强一致的。
  6. 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。
  7. if err != nil { continue }
    • 出错就跳过该 key,并继续下一个 key。
  8. 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 —— 这是一个风险点。
  9. works = append(works, work)
    • 把构造好的 work 加入列表。
  10. 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:保持的最小空闲连接
    • 返回值:*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:连接/命令错误等
    • 作用:基于乐观锁的事务控制。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 的安全窗口内,将多条写操作作为一个事务提交。
  • 事务相关错误

    • redis.TxFailedErr(变量)
      • 含义:监视的键在 EXEC 前被改动导致事务未执行,通常需要重试。
    • redis.Nil(变量)
      • 含义:值不存在(非致命错误,表示键不存在)。

四、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>
内容反馈

发现错误或想补充内容?

GoClub Pro 是静态知识库,评论功能不再加载第三方脚本。你可以在 GitHub 仓库提交 Issue,反馈会直接进入项目协作流程。

提交 GitHub 反馈