Redis 如何将我的数据库读取从约 26K 降至几乎为零

发布: (2026年2月9日 GMT+8 01:09)
5 分钟阅读
原文: Dev.to

Source: Dev.to

Cover image for How Redis Cut My Database Reads from ~26K to Almost Zero

我过去在每一次页面加载时都直接请求 Supabase——博客、单篇文章、经历、工具箱、服务、连接、个人信息、角色可见性、技能……基本上我的整个个人仪表盘都依赖于直接的数据库查询。

结果是?

  • 约 26,000 次数据库读取/天
  • 响应缓慢
  • 不必要的负载
  • 偶尔的连接警告

于是,我引入了 Redis 作为读穿缓存,并配合一个小型的 预热脚本——一切都改变了。

我缓存的内容

我专注于 最热的读取密集型数据

  • 博客 → 已发布列表、单篇数据、合并的博客负载
  • 经历 → 活跃的 + 完整历史
  • 工具箱 → 全部、软件、硬件
  • 服务 → 活跃的 + 全部
  • 连接 → 完整列表
  • 个人信息 → 单例记录
  • 角色可见性 → 侧边栏 & 快捷操作
  • 技能 → 完整列表 + 类别变体

这些是完美的 缓存候选,因为它们:

  • 更改频率低
  • 被持续读取
  • 不需要实时一致性

Source:

缓存工作原理

1) 读取穿透缓存模式

每个 GET 接口都包装了一个辅助函数:

getCached(key, fetcher, ttl = 300)

流程

请求 → 检查 Redis
        → 缓存命中 → 立即返回
        → 缓存未命中 → 从 Supabase 获取 → 存入 Redis → 返回
  • 只有第一次请求会访问数据库
  • 其余所有请求 在毫秒级从 Redis 提供服务

2) 写入时的智能失效

当数据通过 POSTPUTDELETE 发生变化时,我会调用:

invalidateKeys([...])

这只会清除 受影响的缓存前缀,保持一切:

  • 新鲜
  • 一致
  • 快速

3) 预热缓存

为避免部署后出现冷启动延迟,我编写了一个脚本:

scripts/prewarm-redis.mjs

它仅调用 公共 API 接口——不需要数据库凭证。

运行方式如下:

BASE_URL=http://localhost:3000 node scripts/prewarm-redis.mjs

现在 Redis 在真实用户到来之前已经 全部填充

4) 可视化与健康监控

我在 Data tab UI 中添加了显示:

  • Redis 健康状态
  • 缓存项目总数
  • 缓存数据集概览

如果 Redis 出现故障,我能立刻发现。

结果 📉

使用 Redis 前

  • ~26K 每日数据库读取
  • 延迟更高
  • 存在最大连接数限制的风险

使用 Redis 后

  • 冷启动: 每个数据集仅一次数据库访问
  • 热流量: 几乎为零的数据库读取
  • 延迟: 单位毫秒级
  • 稳定性: 没有连接压力

简而言之: 数据库成为备份;Redis 成为主要读取层。

最大差异的关键因素

  1. 缓存最热的读取 – 当列表和单例数据被缓存时,可带来巨大的投资回报率。
  2. 保持 TTL 适度 – 我使用 5 分钟 来平衡新鲜度和性能。
  3. 部署时始终预热 – 完全消除冷启动惩罚。
  4. 监控缓存健康 – 可视性防止静默的性能回退。

如何尝试

  1. 配置 Redis

    REDIS_URL=...
    # or host/port/user/password
  2. 启动你的应用

  3. 运行预热脚本

  4. 打开仪表盘/博客页面

观察:

  • 数据库指标下降
  • Redis 命中率上升
  • 延迟缩短

最终思考

添加 Redis 不仅是一次 性能优化——它从根本上改变了我的应用在 大规模读取 时的处理方式。

从:

“每次都查询数据库”

到:

“从内存即时提供,只有在必要时才访问数据库。”

这一次转变将 每日 26K 次读取降低到几乎为零

而最棒的是?实现时间不到一天

0 浏览
Back to Blog

相关文章

阅读更多 »