程序员面试宝典

一站式面试准备平台

返回分类
system-design中级

缓存系统设计

理解缓存策略的原理、缓存问题(雪崩、击穿、穿透)的解决方案、以及 Redis 的应用

2026-04-15
阅读时间: 7分钟

缓存系统设计

缓存是系统设计中最重要的技术之一。面试官想看你不只是会用 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 适用场景
   "适合读多写少、热点数据、短期不会变化的数据"

相关概念

相关标签