缓存系统设计
缓存是系统设计中最重要的技术之一。面试官想看你不只是会用 Redis,而是理解缓存为什么能解决问题,以及缓存带来的新问题怎么应对。
面试考察点
面试官通过这道题想考察:
1. 你是否理解缓存的读写模式
2. 你是否能解决缓存的三大问题
3. 你是否能设计合理的缓存策略
4. 你是否理解 Redis 的适用场景
一、缓存读写模式
1.1 Cache Aside(最常用)
面试官追问:"缓存怎么和数据库配合?"
Cache Aside(旁路缓存):
读操作:
1. 先读缓存
2. 缓存命中 → 返回数据
3. 缓存未命中 → 读数据库 → 写入缓存 → 返回
写操作:
1. 写数据库
2. 删除缓存(不是更新!)
为什么是删除而不是更新?
因为更新缓存可能造成数据不一致!
而且删除比更新更简单!
1.2 为什么写是删除不是更新?
场景:
线程 A:写 x=1
线程 B:读 x
错误的做法(更新缓存):
1. A 更新数据库 x=1
2. A 更新缓存 x=1
3. B 读缓存,命中 x=1 ✓
但如果有并发问题:
1. A 更新数据库 x=1
2. A 更新缓存(延迟)
3. B 读缓存,命中 x=0(旧的) ✗
正确的做法(删除缓存):
1. A 删除缓存
2. A 更新数据库 x=1
3. B 读缓存,未命中
4. B 读数据库 x=1,写入缓存
5. 后续读都是 x=1 ✓
二、缓存三大问题
2.1 缓存雪崩
面试官追问:"什么是缓存雪崩?怎么解决?"
问题:
大量缓存同时过期 → 大量请求打到数据库 → 数据库崩溃!
场景:
- 缓存都设了相同的过期时间
- Redis 宕机
解决思路:
1. 过期时间加随机值
TTL = baseTTL + random(0, 300)
2. 互斥锁
只有一个人去加载数据,其他人等待
3. 热点数据永不过期
后台异步更新
面试能加分的回答:
"雪崩的本质是缓存层失效,所有压力到数据库,
可以通过过期时间分散 + 熔断降级来应对"
2.2 缓存击穿
问题:热点 key 过期瞬间 → 大量请求同时穿透到数据库
和雪崩的区别:
- 雪崩:大量 key 同时过期
- 击穿:单个热点 key 过期
解决:
1. 互斥锁
同一时间只有一个人去加载
2. 逻辑过期
热点数据永不过期,但有过期逻辑字段
过期时异步更新,不阻塞读请求
2.3 缓存穿透
问题:查询不存在的数据 → 每次都到数据库
场景:
- 恶意请求:id=-1
- 爬虫抓取:查询不存在的 ID
解决:
1. 参数校验
过滤明显非法的请求
2. 布隆过滤器
用 BloomFilter 判断是否存在
3. 缓存空值
不存在的数据也缓存,但 TTL 短一点
三、Redis 应用
3.1 Redis 的数据结构
面试官追问:"Redis 常用的数据结构有哪些?"
Redis 5 种基础数据结构:
1. String
- 缓存简单值
- SET key value
2. Hash
- 缓存对象
- HSET user:1 name "Alice"
3. List
- 有序列表(可做队列)
- LPUSH/RPOP
4. Set
- 无序去重集合
- SADD tags 1 2 3
5. Sorted Set
- 带分数的有序集合
- 排行榜、热评
面试能加分的回答:
"Redis 的价值在于 O(1) 的读写能力,
适用于高频访问、变化少的数据"
3.2 Redis 的持久化
RDB(Redis Database):
- 定时生成内存快照
- 恢复快
- 可能丢失最后一次快照后的数据
AOF(Append Only File):
- 记录所有写操作
- 丢失少
- 文件大,恢复慢
实际选择:
- 小数据量:RDB or AOF
- 大数据量:主从 + RDB
四、面试总结
缓存核心要点
┌─────────────────────────────────────────────────┐
│ 缓存核心 │
├─────────────────────────────────────────────────┤
│ │
│ 读写模式: │
│ - Cache Aside(最常用) │
│ - 写:删缓存而非更新 │
│ │
│ 三大问题: │
│ - 雪崩:过期时间分散 │
│ - 击穿:互斥锁/逻辑过期 │
│ - 穿透:布隆过滤器/空值缓存 │
│ │
│ Redis 应用: │
│ - 5 种数据结构 │
│ - O(1) 读写 │
│ │
└─────────────────────────────────────────────────┘
面试能加分的回答
1. 能解释为什么写是删除
"删除而不是更新,避免并发时的数据不一致"
2. 能解决三大问题
"雪崩靠过期时间分散,击穿靠互斥锁,穿透靠布隆过滤器"
3. 能说清 Redis 适用场景
"适合读多写少、热点数据、短期不会变化的数据"
相关概念
- Redis 主从复制 - 哨兵、集群
- 系统设计基础 - 缓存层次