一. 本文對Redis中[緩存穿透]、[緩存擊穿]、[緩存雪崩]三種現象產生原因、解決方法進行說明
二. 緩存穿透
1. 原因
緩存不存在或已過期,請求直接打到數據庫層
2. 解決方法
- 緩存永不失效
1. 通過設置無過期時間的緩存
2. 定時任務或異步線程定期更新緩存
3. 發現緩存即將過期時延長過期時間(過期時間放在緩存中)
- 利用互斥鎖保證同一時刻只有一個請求可以穿過不存在的緩存直接查數據庫,其它請求阻塞,直到拿到鎖,再從緩存中獲取數據。但使用互斥鎖會導致系統吞吐量下降
static Object lockObj = new Object();
synchronized (lockObj) {
value = redis.get(key);
if (StringUtils.isNotBlank(value)) {
return value;
}
redis.set(key, value, time);
return value;
}
三. 緩存擊穿
1. 原因
緩存不存在或已過期,數據庫也不存在數據
2. 解決方法
- 數據庫不存在數據時,使用一個默認值回寫緩存
- 布隆過濾器
- 互斥鎖
四. 緩存雪崩
1. 原因
同一時刻大量緩存失效
2. 解決方法
- 緩存的過期時間儘量均勻分佈,避免同時失效
- 熱點緩存永不過期
- 互斥鎖