Skip to content

055. Redis 连接池与实体缓存

学习目标

这一节开始实现 Redis 缓存。

学完后,你应该能理解:

  • Redis 在项目里缓存哪些数据;
  • 为什么缓存能减少数据库查询;
  • Redis 连接池负责什么;
  • 为什么缓存也要设置过期时间;
  • RedisCache 如何缓存数据库实体;
  • 为什么要区分“没有缓存”和“数据库没有值”。

为什么需要 Redis

Redis 是内存型缓存数据库。

它适合缓存经常读取、变化不太频繁的数据。

项目里可以缓存:

  • 当前用户信息;
  • 通用模块配置信息;
  • Dify 插件调用后端接口用的 API token;
  • AI 模型配置;
  • 其他高频查询数据。

这些数据如果每次请求都查 MySQL,会给数据库带来压力。

放进 Redis 后,请求可以优先从缓存读取。

缓存不是越多越好

Redis 使用内存。

缓存越多,占用内存越多。

学习环境的服务器内存比较紧张,前端、后端、Dify、数据库等服务都会吃内存。

所以课程项目只缓存必要内容。

真实业务服务器内存更大,可以根据访问频率和成本决定缓存范围。

Redis 连接池

后端连接 Redis 时,不应该每次请求都新建连接。

更合理的方式是创建连接池。

连接池负责复用连接:

  • 请求需要 Redis 时,从池里拿连接;
  • 用完后连接回到池里;
  • 程序退出时关闭连接池。

这样能减少频繁创建连接的成本。

连接健康检查

应用启动时可以检查 Redis 是否正常。

常见做法是:

  1. 获取 Redis client;
  2. 执行 ping
  3. 写入一条临时缓存;
  4. 再读出来验证值是否一致;
  5. 设置短过期时间,避免测试数据长期残留。

如果 Redis 连不上,应用启动时就能尽早发现。

Docker 里的 Redis

课程环境里的 Redis 通过 Docker 运行。

宿主机端口映射到容器里的 Redis 端口。

Redis Commander 作为 Web 管理工具,也在同一个 Docker 网络里访问 Redis。

这能帮助你在浏览器里看到缓存 key 是否写入、过期和删除。

RedisUtil

RedisUtil 负责通用 Redis 能力。

它包含:

  • 初始化连接池;
  • 获取 Redis client;
  • 检查连接是否正常;
  • 关闭连接池;
  • 读取 Redis 环境变量配置。

业务代码不应该到处重复创建 Redis client。

统一工具类能减少连接管理混乱。

为什么缓存实体

用户信息这类数据会被频繁查询。

例如认证中间件几乎每次请求都可能需要当前用户。

如果每次都查 MySQL,压力会很大。

可以把用户实体按用户名缓存起来。

后续再需要这个用户时,先查 Redis。

Redis 没有命中,再查 MySQL,并把结果写回 Redis。

RedisCache

RedisCache 是面向实体类的缓存封装。

初始化时会指定:

  • 缓存 key 前缀;
  • 对应的模型类;
  • 查询字段;
  • 默认缓存过期时间;
  • 空值缓存过期时间。

例如用户缓存可以用 user 作为前缀,用用户名作为查询字段。

最终缓存 key 可以类似:

txt
user:zhangsan

没有缓存与没有值

读取缓存时有两个不同情况:

  • Redis 里没有这个 key;
  • Redis 里记录了这个 key 对应的数据库数据不存在。

这两个不能混在一起。

如果只是 Redis 没有缓存,可以去 MySQL 查。

如果已经缓存了“数据库没有值”,就不必每次都继续查 MySQL。

这叫空值缓存。

空值缓存

空值缓存用一个特殊标记表示数据库没有对应记录。

例如查询不存在的用户名:

  1. 第一次 Redis 没命中;
  2. 去 MySQL 查,也没有;
  3. 把“无值标记”写入 Redis;
  4. 下一次相同查询直接返回无值。

空值缓存过期时间通常比较短。

这样能减少恶意或错误请求反复击穿数据库。

写入缓存

写缓存时要把模型对象转成字典,再序列化成 JSON 字符串。

如果对象里有 None 字段,可以按项目需要去掉。

Redis 里统一存字符串,读取时再解析回字典。

这样缓存格式更可控。

缓存命中后的变化

第一次查询用户时,可能会看到 SQL 执行日志。

因为 Redis 没有命中,需要查 MySQL。

第二次查询同一个用户时,如果缓存还没过期,就不会再执行 SQL。

这就是缓存减少数据库访问的直接效果。

这一节的重点

这一节搭起 Redis 缓存基础。

你需要记住:

  • Redis 适合高频读取数据;
  • 连接池负责复用连接;
  • 缓存要设置过期时间;
  • 实体缓存要有 key 前缀和查询字段;
  • 空值缓存能避免不存在的数据反复打到 MySQL。

AI Agent 课程学习文档。