数据库明明有数据,为什么还要再存一份?

发布 · 视频 2:12 · 约 3 分钟读完 · #后端#服务端缓存#性能

章节

  1. 0:00明明都有
  2. 0:20每单都跑仓库
  3. 0:42备菜台
  4. 1:12放多久
  5. 1:29菜单变了
  6. 1:50回顾

快捷键:K/空格 播放暂停 · J/L 上/下一章 · ↑/↓ 切换章节

数据库里什么都有,可很多网站还要在它前面再放一份常用数据,这就是服务端缓存(server-side cache)。它像后厨里的备菜台:热门菜提前切好摆在手边,点单来了伸手就拿,不用每次都跑仓库。下面分 6 步讲清楚。

6 步看懂服务端缓存

1. 明明都有#▶ 从这里看

  • 第七期讲的浏览器缓存在你自己的电脑里;这一期的缓存在网站的服务器这边,公共数据可以给很多访客共用(也可以只属于某台服务器或某个用户)。

2. 每单都跑仓库#▶ 从这里看

  • 数据库通常把数据存在磁盘上,还要按条件查找、拼装结果,每次查询都有成本。
  • 访问量一大,同样的查询被重复执行成千上万次,数据库就成了瓶颈。

3. 备菜台#▶ 从这里看

  • 服务端缓存一般放在内存里(常用的开源工具如 Redis),读取比查数据库快得多。1
  • 命中(cache hit):缓存里有,直接返回。
  • 没命中(cache miss):缓存里没有,去数据库查,再把结果写进缓存,下次就能命中。
  • 这种「先查缓存、没有再查数据库并回填」的用法,常叫旁路缓存(cache-aside)。2

4. 放多久#▶ 从这里看

  • 内存比磁盘贵、空间小,所以只放热门数据。
  • 每份缓存可以设过期时间(TTL,time to live),时间一到自动删除,例如 Redis 的 EXPIRE 命令。1
  • 配置了内存上限和淘汰策略后,满了就会淘汰一部分(比如最近最少用到的那些);如果设成不淘汰,新的写入会被拒绝。3

5. 菜单变了#▶ 从这里看

  • 数据库里的数据改了,缓存里那份就旧了。常见做法是:先更新数据库,再删掉对应的缓存,下一次读取没命中,自然会从数据库拿到新数据并回填。2
  • 但这不是「一改就立刻全对」:从改完数据库到删掉缓存之间,仍可能有请求读到旧数据,只是时间很短。2
  • 忘了删,或者删失败,用户就会在过期之前一直看到旧数据。过期时间也是一道兜底。

6. 回顾#▶ 从这里看

  • 浏览器缓存:你家冰箱,在你电脑里。
  • CDN:附近门店,离你近。
  • 负载均衡:店里多开柜台,人多也扛得住。
  • 服务端缓存:后厨备菜台,替数据库挡掉大量重复查询。
  • 几层叠在一起,网站才能又快又稳。

深入一问

为什么不直接删掉旧缓存再更新数据库?
如果先删缓存、数据库还没改完,这时正好有请求进来,会把旧数据重新读进缓存。所以更常见的顺序是先改数据库,再删缓存。2

缓存挂了网站会怎样?
如果缓存挂了,程序又直接去查数据库,大量请求就会一下子打到数据库上;所以还要配合限流、降级。另外,缓存只是加速,数据始终以数据库为准,数据库也要能扛住缓存失效时的压力。

易错点

  • ❌ 「有了缓存就不需要数据库」→ ✅ 缓存只放常用数据的副本,数据库才是准的那份。
  • ❌ 「服务端缓存和浏览器缓存是一回事」→ ✅ 一个在服务器这边,公共数据可以给很多访客共用(也可以只属于某台服务器或某个用户);一个在你自己电脑里。
  • ❌ 「改了数据库,缓存会自己变」→ ✅ 要主动删掉对应缓存,或者等它过期。

参考资料

Footnotes

  1. Redis 官方文档,《EXPIRE》(设置过期时间)。https://redis.io/docs/latest/commands/expire/ ↩ ↩2

  2. Microsoft Azure 架构中心,《Cache-Aside pattern》(通用设计模式说明,ms.date 2025-09-11,更新于 2025-12-09,访问于 2026-10-14)。https://learn.microsoft.com/en-us/azure/architecture/patterns/cache-aside ↩ ↩2 ↩3 ↩4

  3. Redis 官方文档,《Key eviction》(内存满时的淘汰策略)。https://redis.io/docs/latest/develop/reference/eviction/ ↩

幕后

这部片子完全由代码生成。