1、緩存雪崩
緩存雪崩,是指在某一時間段,緩存集中過期失效。所有原本應(yīng)該訪問緩存的請求都去查詢數(shù)據(jù)庫而對數(shù)據(jù)庫CPU和內(nèi)存造成巨大壓力,嚴(yán)重的會造成數(shù)據(jù)庫宕機(jī),從而形成一系列連鎖反應(yīng),造成整個系統(tǒng)崩潰。
1.1、解決方案
(一)加鎖或者隊(duì)列
可以考慮用加鎖或者隊(duì)列的方式防止大量線程對數(shù)據(jù)庫的一次性進(jìn)行讀寫,避免緩存失效時對數(shù)據(jù)庫造成的巨大沖擊。
(二)協(xié)調(diào)Redis過期時間
分析用戶行為,盡量讓緩存失效的時間均勻分布,最次也得隨機(jī)分布,尤其是一些訪問大的接口。
(三)?二級緩存
做二級緩存,A1為原始緩存,A2為拷貝緩存,A1失效時,可以訪問A2,A1緩存失效時間設(shè)置為短期,A2設(shè)置為長期。
2、緩存穿透
緩存穿透,是指查詢一個一定不存在的數(shù)據(jù)。由于緩存不命中,并且出于容錯考慮,如果從數(shù)據(jù)庫查不到數(shù)據(jù)則不寫入緩存,這將導(dǎo)致這個不存在的數(shù)據(jù)每次請求都要到數(shù)據(jù)庫去查詢,失去了緩存的意義。
2.1、解決方案
(一)布隆過濾器(BloomFilter)
采用布隆過濾器,將所有可能存在的數(shù)據(jù)哈希到一個足夠大的bitmap中,一個一定不存在的數(shù)據(jù)會被這個bitmap攔截掉,從而避免了對底層存儲系統(tǒng)的查詢壓力。由于請求的參數(shù)是不合法的(每次都請求不存在的參數(shù)),于是我們可以使用布隆過濾器(BloomFilter)或者壓縮filter提前攔截,不合法就不讓這個請求到數(shù)據(jù)庫層。
(二)?將空對象記錄在緩存中
如果數(shù)據(jù)庫返回信息為null,也可以將這個空對象設(shè)置到緩存里邊去。下次再請求的時候,就可以從緩存里邊獲取了,將空對象設(shè)置一個較短的過期時間。
3、緩存擊穿
緩存擊穿,是指的是熱點(diǎn)key在某個特殊的場景時間內(nèi)恰好失效了,恰好有大量并發(fā)請求過來了,造成DB壓力。
3.1、解決方案
(一)加鎖或者隊(duì)列
和緩存雪崩解決方案相同。
(二)過期時間可以無限調(diào)長
將熱點(diǎn)key過期時間無限調(diào)長,然后通過job服務(wù)來管理這些熱點(diǎn)key不會過期,保證熱點(diǎn)key(尤其是像排行榜、首頁熱度等需要大量計(jì)算的熱點(diǎn)key)的穩(wěn)定性。需要注意的是,job服務(wù)本身也存在不穩(wěn)定性,比如部署job的服務(wù)掛了之類的。