什么是缓存击穿?
緩存擊穿、緩存并發(fā)和緩存雪崩是常見的由于并發(fā)量大而導(dǎo)致的緩存問題,本節(jié)講解其產(chǎn)生原因和解決方案。
緩存擊穿通常是由惡意攻擊或者無意造成的;緩存并發(fā)是由設(shè)計不足造成的;緩存雪崩是由緩存同時失效造成的,三種問題都比較典型,也是難以防范和解決的。本節(jié)給出通用的解決方案,以供在緩存設(shè)計的過程中參考和使用。
緩存擊穿
緩存擊穿指的是使用不存在的key進行大量的高并發(fā)查詢,這導(dǎo)致緩存無法命中,每次請求都要擊穿到后端數(shù)據(jù)庫系統(tǒng)進行查詢,使數(shù)據(jù)庫壓力過大,甚至使數(shù)據(jù)庫服務(wù)被壓死。
我們通常將空值緩存起來,再次接收到同樣的查詢請求時,若命中緩存并且值為空,就會直接返回,不會透傳到數(shù)據(jù)庫,避免緩存擊穿。當(dāng)然,有時惡意襲擊者可以猜到我們使用了這種方案,每次都會使用不同的參數(shù)來查詢,這就需要我們對輸入的參數(shù)進行過濾,例如,如果我們使用ID進行查詢,則可以對ID的格式進行分析,如果不符合產(chǎn)生ID的規(guī)則,就直接拒絕,或者在ID上放入時間信息,根據(jù)時間信息判斷ID是否合法,或者是否是我們曾經(jīng)生成的ID,這樣可以攔截一定的無效請求。
當(dāng)然,每個設(shè)計人員都應(yīng)該對服務(wù)的可用性和健壯性負責(zé),應(yīng)該建設(shè)健壯的服務(wù),讓我們的服務(wù)像不倒翁一樣,因此,我們需要對服務(wù)設(shè)計限流和熔斷等功能,請參考《分布式服務(wù)架構(gòu):原理、設(shè)計與實戰(zhàn)》中第1章關(guān)于微服務(wù)設(shè)計模式的內(nèi)容。
緩存并發(fā)
緩存并發(fā)的問題通常發(fā)生在高并發(fā)的場景下,當(dāng)一個緩存key過期時,因為訪問這個緩存key 的請求量較大,多個請求同時發(fā)現(xiàn)緩存過期,因此多個請求會同時訪問數(shù)據(jù)庫來查詢最新數(shù)據(jù),并且回寫緩存,這樣會造成應(yīng)用和數(shù)據(jù)庫的負載增加,性能降低,由于并發(fā)較高,甚至?xí)?dǎo)致數(shù)據(jù)庫被壓死。
我們通常有3種方式來解決這個問題。
分布式鎖
使用分布式鎖,保證對于每個key同時只有一個線程去查詢后端服務(wù),其他線程沒有獲得分布式鎖的權(quán)限,因此只需要等待即可。這種方式將高并發(fā)的壓力轉(zhuǎn)移到了分布式鎖,因此對分布式鎖的考驗很大。
本地鎖
與分布式鎖類似,我們通過本地鎖的方式來限制只有一個線程去數(shù)據(jù)庫中查詢數(shù)據(jù),而其他線程只需等待,等前面的線程查詢到數(shù)據(jù)后再訪問緩存。但是,這種方法只能限制一個服務(wù)節(jié)點只有一個線程去數(shù)據(jù)庫中查詢,如果一個服務(wù)有多個節(jié)點,則還會有多個數(shù)據(jù)庫查詢操作,也就是說在節(jié)點數(shù)量較多的情況下并沒有完全解決緩存并發(fā)的問題。
軟過期
軟過期指對緩存中的數(shù)據(jù)設(shè)置失效時間,就是不使用緩存服務(wù)提供的過期時間,而是業(yè)務(wù)層在數(shù)據(jù)中存儲過期時間信息,由業(yè)務(wù)程序判斷是否過期并更新,在發(fā)現(xiàn)了數(shù)據(jù)即將過期時,將緩存的時效延長,程序可以派遣一個線程去數(shù)據(jù)庫中獲取最新的數(shù)據(jù),其他線程這時看到延長了的過期時間,就會繼續(xù)使用舊數(shù)據(jù),等派遣的線程獲取最新數(shù)據(jù)后再更新緩存。
也可以通過異步更新服務(wù)來更新設(shè)置軟過期的緩存,這樣應(yīng)用層就不用關(guān)心緩存并發(fā)的問題了。
緩存雪崩
緩存雪崩指緩存服務(wù)器重啟或者大量緩存集中在某一個時間段內(nèi)失效,給后端數(shù)據(jù)庫造成瞬時的負載升高的壓力,甚至壓垮數(shù)據(jù)庫的情況。
通常的解決辦法是對不同的數(shù)據(jù)使用不同的失效時間,甚至對相同的數(shù)據(jù)、不同的請求使用不同的失效時間,例如,我們要緩存user數(shù)據(jù),會對每個用戶的數(shù)據(jù)設(shè)置不同的緩存過期時間,可以定義一個基礎(chǔ)時間,假設(shè)10秒,然后加上一個兩秒以內(nèi)的隨機數(shù),過期時間為10~12秒,就會避免緩存雪崩。
原文發(fā)布時間為:2018-07-22
本文作者:李艷鵬
本文來自云棲社區(qū)合作伙伴“程序員小灰”,了解相關(guān)信息可以關(guān)注“程序員小灰”
總結(jié)
- 上一篇: drf中的各种view,viewset
- 下一篇: 仿LordPE获取PE结构