7.5 KiB
tags, create time
| tags | create time | ||||||
|---|---|---|---|---|---|---|---|
|
2026-08-09 12:00 |
缓存穿透击穿雪崩解决方案_测试题
概述
本测试覆盖 Redis 缓存三大经典问题——穿透(Penetration)、击穿(Breakdown)和雪崩(Avalanche)。共 10 道题:6 道选择题、3 道填空题、1 道简答题,考察对各自成因的区分理解和对应方案的设计能力。
一、选择题(6道,由浅入深)
难度阶梯: Q1-Q2 基础概念 → Q3-Q4 核心原理 → Q5-Q6 深入应用/边界场景
Q1(基础)— 考察定义层面
以下哪种现象描述的是"缓存穿透"?
A. 热点 key 过期时大量并发请求同时查到缓存为空,纷纷去查 DB B. 大量 key 在同一时刻过期导致请求洪水面涌向下流 C. 恶意用户反复查询数据库中不存在的 key,每次缓存都 miss 直接打到 DB D. 单个 key 的访问频率远高于平均水平,超过 Redis 实例处理能力
Q2(基础)— 考察行为判断
布隆过滤器(Bloom Filter)在查询某个 key 时返回"可能存在",这表示:
A. 该 key 一定存在于数据集中 B. 该 key 一定不存在于数据集中 C. 该 key 可能存在也可能不存在(允许 False Positive) D. 布隆过滤器出错了
Q3(进阶)— 考察核心原理
关于布隆过滤器的误判率公式 p ≈ (1 - e^(-kn/m))^k,其中 m 是位数组大小,n 是元素数量,k 是哈希函数个数。当 m/n = 10、k = 7 时,误判率约为:
A. 50% B. 10% C. 0.8% D. 0.001%
Q4(进阶)— 考察对比辨析
互斥锁方案和逻辑 TTL 方案用于防止缓存击穿,以下哪项对比是正确的?
A. 互斥锁方案一致性弱但性能开销大 B. 逻辑 TTL 方案强一致且无锁开销 C. 互斥锁方案强一致但有死锁风险需要超时机制 D. 两者都能完全避免 DB 压力增加
Q5(深入)— 考察场景推理
某社交媒体平台的点赞数存储在 Redis 中,特点是不存在无效 key(key 都是有效的),但热点帖子点赞数的读取量极高(QPS 达数万)。对于这种场景,最有效的防击穿策略是:
A. 布隆过滤器预加载所有有效 user_id B. 永不过期加后台异步刷新的逻辑 TTL 方案 C. 多层队列接力 DLX 重试模式 D. 将点赞数存入 MySQL 而不使用缓存
Q6(深入)— 考察源码级别细节
在完整的防御型缓存获取方法中,三道防线分别是什么顺序?
A. 读缓存 → 布隆过滤器 → 分布式锁 B. 分布式锁 → 读缓存 → 布隆过滤器 C. 布隆过滤器 → 读缓存 → 分布式锁 D. 读缓存 → 分布式锁 → 布隆过滤器
二、填空题(3道)
F1 — 填空
根据布隆过滤器最优参数公式,当已知位数组大小 m 和元素数量 n 时,最优哈希函数个数 k = ______ × ln(2)。
提示: 回顾公式中的关键变量关系。
F2 — 填空
雪崩的核心成因是大量 key 设置相同的过期时间,到期时 ______ ,请求洪水般涌向下游数据库。
提示: 用一个两字词语描述这个状态变化。
F3 — 填空
互斥锁方案防止击穿的代码模式中,必须先做双重检查(Double Check):先尝试获取锁,成功后再从缓存读一次值,如果仍为 nil 才真正查 DB。这是因为其他线程可能已经在锁等待期间完成了重建。如果不做双重检查,会导致 ______ 。
提示: 思考如果没有 double check 会重复执行什么操作。
三、简答题(1道)
S1
一个电商平台的商品 SKU 查询系统有以下特征:
- SKU ID 的范围已知且相对稳定(约 100 万个有效 ID)
- 查询流量不稳定,有时会出现恶意扫描
- 爆款商品单秒 QPS 可达 5000+
- 运营人员频繁更新商品价格信息
请设计一套三层防御方案来保护后端数据库,回答以下问题:
- 每层使用什么技术?防护什么问题?
- 第一层布隆过滤器的参数如何设置(m、n、k)?
- TTL 随机化的具体参数建议是什么?
答题框架提示:
- 穿透/击穿/雪崩三层对应的技术方案
- 布隆过滤器的参数计算
- TTL 参数选择和理由
参考答案与解析
选择题答案
| 题号 | 正确答案 | 解析 |
|---|---|---|
| Q1 | C | 缓存穿透的定义:恶意或异常查询不断访问数据库中不存在的 key,每次缓存 miss 导致请求直达 DB。A 是击穿;B 是雪崩;D 是热点 Key 问题。 |
| Q2 | C | 布隆过滤器的特性:返回"一定不在"表示必定不存在(No False Negative),返回"可能存在"表示可能在(可能有 False Positive)。这是空间效率的代价。 |
| Q3 | C | 当 m/n = 10、k = 7 时,误判率约 0.8%。这是面试常考的经典参数组合。增大 m/n 可进一步降低误判率(如 m/n = 20 时降至 0.02%)。 |
| Q4 | C | 互斥锁方案保证强一致(新值写入后才可读到),但存在死锁风险——如果重建过程抛出异常没有释放锁,其他线程永远阻塞。必须用 defer unlock 或超时机制。B 错误——逻辑 TTL 是最终一致而非强一致。 |
| Q5 | B | 点赞数几乎不可能穿透(key 都是有效的),重点防击穿。永不过期加后台异步刷新(逻辑 TTL)方案最合适——物理上不设过期时间,内存维护逻辑过期时间,发现过期后异步触发重建,读取到的仍是旧值(无脑 hit),直到新缓存写入成功。 |
| Q6 | C | 正确的三层防线顺序:第1道——布隆过滤器拦截不存在的 key;第2道——读缓存命中直接返回;第3道——分布式锁防止击穿,只有一个线程查 DB 回填。这个顺序确保最轻量级的检查在最前面。 |
填空题答案
| 题号 | 答案 | 解析 |
|---|---|---|
| F1 | m/n | 最优哈希函数数 k = (m/n) * ln(2),此时误判率最低。ln(2) ≈ 0.693,所以 k 约等于 0.693 * m/n。 |
| F2 | 集中失效 | 大量 key 同时过期意味着原本被缓存拦截的请求突然全部穿透到数据库,形成集中的查询洪峰,超出系统的承载能力。通过在 TTL 上加随机偏移可以分散过期时间点。 |
| F3 | 重复查 DB / 重复重建 | 双重检查确保:即使成功获得锁,也要再读一次缓存——因为在这之前另一个已经持有锁的线程可能已完成重建并写回缓存。不做双重检查会浪费一次 DB 查询。 |
简答题参考答案
S1:参考答案要点:
- 第一层——布隆过滤器:预加载所有 100 万有效 SKU ID,拦截不存在的 key 查询,防止穿透。第二层——互斥锁:对热点商品 sku 加分布式锁,防止击穿。第三层——TTL 随机化:设置基础 TTL 加减随机波动,防止雪崩。
- 布隆过滤器参数:n = 100万,取 m/n = 10 则 m = 1000万位(约 1.2MB),k = 7。误判率约 0.8%,对业务可接受。也可取 m/n = 20 进一步降低到 0.02%。
- TTL 随机化:商品价格在运营更新后立即写入 DB 并 DEL 缓存,下次读取时 SET 一个新的带随机抖动的 TTL。建议 baseMinutes=10, jitterPercent=30,使实际 TTL 落在 [7, 13] 分钟均匀分布。
评分标准:答出任意 2 个要点即可得满分;完全正确需覆盖三层防御方案、布隆参数计算和 TTL 策略三个维度。