1. 缓存基础概念

1.1 缓存的定义

缓存(Cache)是位于数据请求路径上的临时存储层,用于保存频繁访问的数据副本。当系统收到数据请求时,优先从缓存中读取,只有在缓存未命中时才回源到数据库或其他慢速存储。

核心思想:用空间换时间——将热数据存储在高速介质(如内存)中,减少对慢速介质(如磁盘、网络)的访问次数。

1.2 缓存的核心作用

  • 加速读操作:内存读取延迟通常在微秒级(<1ms),而数据库磁盘IO延迟在毫秒级(10~50ms),缓存可将响应时间降低 1~2 个数量级。
  • 保护数据库:缓存吸收高频读请求,降低数据库连接数、CPU 和 IO 压力,防止数据库因并发过高而崩溃。
  • 提升系统吞吐量:单机 Redis 可支撑 10 万+ QPS,而单库 MySQL 通常在 1 万 QPS 以下,缓存层可显著扩展系统容量。
典型场景:商品详情页、用户会话信息、配置中心、热点新闻列表等读多写少的数据。

1.3 缓存与数据库的差异

对比维度 缓存(如 Redis) 数据库(如 MySQL)
存储介质 内存(DRAM) 磁盘(SSD/HDD)
读写延迟 0.1~1 ms 10~50 ms
数据持久性 弱(宕机丢失) 强(ACID 事务)
查询能力 简单 KV / 有限数据结构 复杂 SQL / 关联查询
容量成本 高(GB 级,昂贵) 低(TB 级,便宜)
一致性保证 最终一致性(默认) 强一致性(可配置)
典型 QPS 10 万+ 1 万左右

1.4 缓存与数据库的协作关系

下图展示了典型的缓存-数据库分层架构,请求优先经过缓存层,未命中时回源数据库并回填缓存。

缓存与数据库协作架构 客户端请求 缓存层(Redis / 本地缓存) 延迟 0.1~1ms | QPS 10万+ 命中 ✅ 未命中 ❌ 数据库层(MySQL / PostgreSQL) 延迟 10~50ms | QPS 1万 回填缓存(Cache-Aside) 缓存命中:直接返回 未命中:查库 + 回填

1.5 缓存一致性问题的根源

缓存与数据库的差异直接导致了一致性问题:

  • 写入时序差异:先写库还是先写缓存?不同顺序导致不同的数据窗口。
  • 删除 vs 更新:缓存更新操作(set)与删除操作(del)对并发读的影响不同。
  • 过期时间窗口:即使设置了 TTL,在过期前缓存与数据库仍可能不一致。
常见误区:认为只要设置了缓存过期时间就能保证最终一致性。实际上,在 TTL 窗口内,脏数据可能被大量请求读取,导致业务异常。

1.6 缓存使用的基本原则

  1. 读多写少:缓存只适合读频率远高于写频率的数据。
  2. 容忍最终一致性:业务能接受短时间(秒级)的数据不一致。
  3. 数据量可控:缓存数据量不能超过内存容量,需设置淘汰策略(LRU/LFU/TTL)。
  4. 避免缓存穿透/击穿/雪崩:需要配套保护措施(布隆过滤器、互斥锁、过期时间打散)。
一句话总结:缓存是加速读、保护数据库的利器,但引入缓存的同时必须设计一致性闭环和错误处理机制,否则缓存会成为系统不稳定的根源。