1. 缓存基础:定义、价值、与数据库的差异及失效场景
缓存(Cache)是分布式系统中提升数据访问性能的核心手段。本章从最基础的概念出发,厘清缓存的定义、业务价值、与数据库的本质差异,以及最常见的缓存失效场景,为后续构建一致性闭环架构奠定理论基础。
1.1 缓存的定义
缓存是一种将数据临时存储在高速存储介质中的技术,目的是减少对原始数据源(如数据库、磁盘文件、远程服务)的访问次数,从而降低延迟、提升吞吐量。在计算机体系结构中,缓存无处不在:从 CPU 的 L1/L2/L3 缓存,到操作系统的页缓存,再到分布式系统中的 Redis、Memcached 等中间件,其核心思想都是“用空间换时间”。
核心公式:缓存命中率 = 缓存命中的请求数 / 总请求数。命中率越高,系统整体延迟越低,数据库压力越小。
1.2 缓存的价值
缓存为系统带来的收益可以量化为以下几个关键维度:
| 维度 | 说明 | 典型收益 |
|---|---|---|
| 降低延迟 | 缓存(内存)的读取延迟通常在微秒级,而数据库(磁盘)在毫秒级 | 延迟降低 10~100 倍 |
| 提升吞吐量 | 缓存可承载每秒数万到数十万次请求,数据库受连接池和磁盘 I/O 限制 | 吞吐量提升 5~50 倍 |
| 保护数据库 | 缓存吸收热点请求,避免数据库被突发流量打垮 | 数据库连接数降低 60%~90% |
| 降低成本 | 减少数据库实例的扩容需求,降低硬件和运维成本 | 同等负载下硬件成本降低 30%~70% |
工程经验:在电商秒杀场景中,商品详情页的缓存命中率通常要求达到 99% 以上,否则数据库会在瞬间被击穿。缓存不是可选项,而是高并发系统的必选项。
1.3 缓存与数据库的差异
理解缓存与数据库的本质差异,是设计缓存策略的前提。下表从多个维度进行对比:
| 对比维度 | 缓存(如 Redis) | 数据库(如 MySQL) |
|---|---|---|
| 存储介质 | 内存(DRAM) | 磁盘(SSD/HDD) |
| 读写延迟 | 0.1~1 ms | 1~50 ms |
| 数据持久性 | 弱(宕机丢失,除非开启 AOF/RDB) | 强(ACID 事务保证) |
| 数据容量 | GB ~ TB 级(受内存限制) | TB ~ PB 级 |
| 查询能力 | 简单 Key-Value / 有限数据结构 | 复杂 SQL、关联查询、事务 |
| 一致性模型 | 最终一致性为主 | 强一致性(可配置) |
| 成本 | 高(内存价格远高于磁盘) | 低(磁盘存储成本低) |
常见误区:不要试图用缓存替代数据库。缓存是加速层,不是存储层。所有缓存数据都必须能从数据库恢复,否则一旦缓存宕机将导致数据永久丢失。
1.4 缓存失效场景
缓存失效是导致系统性能雪崩或数据不一致的主要诱因。以下是四种最常见的失效场景:
- 缓存穿透:请求查询一个数据库中也不存在的数据(如不存在的用户 ID),缓存无法命中,每次请求都穿透到数据库,导致数据库压力激增。
- 缓存击穿:某个热点 Key 在缓存过期的瞬间,大量并发请求同时访问该 Key,全部穿透到数据库,导致数据库瞬间过载。
- 缓存雪崩:大量缓存 Key 在同一时间过期,或缓存节点宕机,导致所有请求直接打到数据库,引发连锁崩溃。
- 缓存与数据库数据不一致:由于并发写操作或更新顺序问题,缓存中的数据与数据库中的真实数据出现偏差,导致业务读取到脏数据。
下图展示了三种典型缓存失效场景的请求路径:
1.5 缓存一致性问题的根源
缓存与数据库之间的数据不一致,本质上是由于并发写操作和更新时序导致的。以下是一个典型的并发更新场景:
// 场景:线程A和线程B同时更新同一数据
// 时间线:
// T1: 线程A 更新数据库 (value = 100)
// T2: 线程B 更新数据库 (value = 200)
// T3: 线程B 更新缓存 (value = 200)
// T4: 线程A 更新缓存 (value = 100) ← 缓存最终为旧值100,与数据库200不一致