【面試官】你可以說一下快取擊穿、穿透、雪崩的區別和解決方法嗎?
資料獲取的流程,一般是前端請求,後臺先從快取中取資料,快取取不到則去資料庫中取,資料庫取到了則返回給前端,然後更新快取,如果資料庫取不到則返回空資料給前端
流程圖:
假如快取的資料沒有,後臺則會一直請求資料庫,對資料庫造成壓力,如果是請求量大或者惡意請求則會導致資料庫崩潰,我們一般稱為快取穿透、快取擊穿、快取雪崩。
1、快取穿透
描述:快取穿透是指快取和資料庫中都沒有的資料,而使用者不斷髮起請求,如發起為id為“-1”的資料或id為特別大(不存在的資料)。這時的使用者很可能是攻擊者,攻擊會導致資料庫壓力過大。
快取穿透
解決:
介面層增加校驗,如使用者鑑權校驗,id做基礎校驗,比如 id<=0的直接攔截;
從快取取不到的資料,在資料庫中也沒有取到,這時也可以將key-value對寫為key-null,直接返回空值。快取有效時間可以設定短點,如30秒(設定太長會導致正常情況也沒法使用)。這樣可以防止攻擊使用者反覆用同一個id暴力攻擊。
利用互斥鎖,快取失效的時候,先去獲得鎖,得到鎖了,再去請求資料庫。沒得到鎖,則休眠一段時間重試。
非同步更新。直接返回一個空值,然後啟動一個執行緒去資料庫讀資料,更新快取,比如專案啟動前先載入快取。
最常見的則是採用布隆過濾器,將所有可能存在的資料雜湊到一個足夠大的bitmap中,一個一定不存在的資料會被 這個bitmap攔截掉,從而避免了對底層儲存系統的查詢壓力。
【文章福利】需要C/C++ Linux伺服器架構師學習資料加群812855908(資料包括C/C++,Linux,golang技術,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒體,CDN,P2P,K8S,Docker,TCP/IP,協程,DPDK,ffmpeg等)
2、快取擊穿
描述:快取擊穿是指快取中沒有但資料庫中有的資料,當一個key非常熱點(類似於爆款),在不停的扛著大併發,大併發集中對這一個點進行訪問;當這個key在失效的瞬間,持續的大併發就穿破快取,直接請求資料庫,就像在一個屏障上鑿開了一個洞。
快取擊穿
解決:
設定熱點資料永遠不過期。
加互斥鎖。(或者分散式鎖)
如果快取中有資料,則直接返回,如果沒有,則第一個進入的執行緒先去查詢資料庫,並加上鎖,其他執行緒則等待,這樣就能防止去資料庫查重複資料、重複更新快取了。
3、快取雪崩
快取雪崩是指快取中資料大批量到過期時間,大批量資料同一時間過期,導致請求量全部請求到資料庫,造成資料庫當機。
快取雪崩
解決:
給快取失效時間,加上一個隨機值,避免大量快取集體失效。
雙快取:快取A和B,比如A的失效時間是20分鐘,B不失效。比如從A中沒讀到,就去B中讀,然後非同步起一個執行緒同步到A。
關於互斥鎖,可以看看下面這個例子:
Redis
如果是使用Redis,可以使用Redis的SETNX,也就是隻有不存在的時候才設定,可以利用它來實現鎖的效果。
public String get(key) {
String value = redis.get(key);
if (value == null) { //代表快取值過期
//設定3min的超時,防止del操作失敗的時候,下次快取過期一直不能load db
if (redis.setnx(key_mutex, 1, 3 * 60) == 1) { //代表設定成功
value = db.get(key);
redis.set(key, value, expire_secs);
redis.del(key_mutex);
} else { //這個時候代表同時候的其他執行緒已經load db並回設到快取了,這時候重試獲取快取值即可
sleep(50);
get(key); //重試
}
} else {
return value;
}
}
memcache
if (memcache.get(key) == null) {
// 3 min timeout to avoid mutex holder crash
if (memcache.add(key_mutex, 3 * 60 * 1000) == true) {
value = db.get(key);
memcache.set(key, value);
memcache.delete(key_mutex);
} else {
sleep(50);
retry();
}
}
4、快取預熱
快取預熱就是系統上線後,後者系統在重啟的時候,將相關的快取資料直接載入到Redis。這樣就可以避免在使用者請求的時候,先查詢資料庫,然後再將資料快取的問題,使用者直接查詢事先被預熱的快取資料。
解決:
上線時加個介面,手動觸發載入快取,或者定時重新整理快取。
資料量不大,可以在專案啟動的時候自動進行載入。
關注公眾號,分享更多你感興趣的網際網路技術內容!
相關文章
- 快取穿透、快取擊穿、快取雪崩區別和解決方案快取穿透
- 快取穿透、快取擊穿、快取雪崩區別快取穿透
- 面試官:快取穿透、快取雪崩和快取擊穿是什麼?面試快取穿透
- Redis的快取穿透、快取雪崩、快取擊穿的區別Redis快取穿透
- 面試總結 —— Redis “快取穿透”、“快取擊穿”、“快取雪崩”面試Redis快取穿透
- 快取穿透、快取擊穿、快取雪崩快取穿透
- 快取穿透、快取雪崩、快取擊穿快取穿透
- 快取穿透、快取擊穿、快取雪崩的場景以及解決方法快取穿透
- Redis快取擊穿、快取穿透、快取雪崩Redis快取穿透
- [Redis]快取穿透/快取擊穿/快取雪崩Redis快取穿透
- 快取穿透,快取擊穿,快取雪崩解決方案分析快取穿透
- 來說說快取穿透、快取擊穿、快取雪崩都是什麼?怎麼解決?快取穿透
- 【高併發】面試官:講講什麼是快取穿透?擊穿?雪崩?如何解決?面試快取穿透
- Redis快取穿透,擊穿和雪崩Redis快取穿透
- Redis 面試常見問題———快取雪崩、快取擊穿以及快取穿透Redis面試快取穿透
- 快取穿透、快取擊穿、快取雪崩概念及解決方案快取穿透
- 【Redis】快取穿透,快取擊穿,快取雪崩及解決方案Redis快取穿透
- REDIS快取穿透,快取擊穿,快取雪崩原因+解決方案Redis快取穿透
- Redis系列:快取擊穿.穿透.雪崩(九)Redis快取穿透
- Redis 快取擊穿(失效)、快取穿透、快取雪崩怎麼解決?Redis快取穿透
- 快取穿透、快取擊穿、快取雪崩、快取預熱快取穿透
- Redis系列 - 快取雪崩、擊穿、穿透及解決方案Redis快取穿透
- Redis 快取擊穿、穿透、雪崩的原因以及解決方案Redis快取穿透
- Redis詳解(十二)------ 快取穿透、快取擊穿、快取雪崩Redis快取穿透
- 什麼是redis快取雪崩、快取穿透、快取擊穿Redis快取穿透
- Redis——快取穿透、快取擊穿、快取雪崩、分散式鎖Redis快取穿透分散式
- 快取穿透、快取雪崩和快取擊穿是什麼?快取穿透
- 怎麼學Redis 快取穿透、擊穿、雪崩Redis快取穿透
- 關於快取穿透、快取擊穿、快取雪崩的模擬與解決(Redis)快取穿透Redis
- Redis快取穿透、快取雪崩、快取擊穿好好說說Redis快取穿透
- 小白也能看懂的快取雪崩、穿透、擊穿快取穿透
- 原來快取也會雪崩、擊穿、穿透啊!快取穿透
- 【專項測試系列】-快取擊穿、穿透、雪崩專項測試快取穿透
- 一文讀懂快取穿透、快取擊穿、快取雪崩及其解決方案快取穿透
- 如何設計快取系統:快取穿透,快取擊穿,快取雪崩解決方案分析快取穿透
- 一文徹底弄懂並解決Redis的快取雪崩,快取擊穿,快取穿透Redis快取穿透
- Redis快取穿透/快取雪崩/快取擊穿(案例:產生的原因 解決方案利/弊)Redis快取穿透
- 老司機帶你玩轉面試(2):Redis 過期策略以及快取雪崩、擊穿、穿透面試Redis快取穿透