
緩存穿透key對應(yīng)的數(shù)據(jù)在數(shù)據(jù)源并不存在緩存擊穿key對應(yīng)的數(shù)據(jù)存在但在redis中過期緩存雪崩key對應(yīng)的數(shù)據(jù)存在但在redis中過期針對很多key緩存抱歉上一版可能因為分隔行/對齊不規(guī)范導(dǎo)致渲染錯位。重新給一個標(biāo)準(zhǔn) Markdown 表格對比項緩存穿透緩存擊穿緩存雪崩簡單含義key 對應(yīng)的數(shù)據(jù)在數(shù)據(jù)源中也不存在緩存和數(shù)據(jù)庫都查不到某個熱點 key 對應(yīng)的數(shù)據(jù)存在但該 key 在 Redis 中過期很多 key 對應(yīng)的數(shù)據(jù)存在但大量 key 在 Redis 中同時過期或 Redis 整體不可用主要原因請求查詢不存在的數(shù)據(jù)緩存無法命中每次都打到數(shù)據(jù)庫惡意請求可利用這一點壓垮數(shù)據(jù)庫熱點 key 過期瞬間大量并發(fā)請求同時打到數(shù)據(jù)庫大量 key 過期時間相同Redis 故障緩存集中失效請求瞬間壓到數(shù)據(jù)庫解決方式緩存空值并設(shè)置較短過期時間布隆過濾器攔截不存在 key參數(shù)校驗接口限流加互斥鎖只放一個請求回源數(shù)據(jù)庫熱點 key 邏輯過期熱點數(shù)據(jù)預(yù)熱必要時熱點 key 不設(shè)過期過期時間加隨機值避免同時失效Redis 高可用部署多級緩存限流降級緩存預(yù)熱一、緩存穿透1.問題描述應(yīng)用服務(wù)器壓力變大redis命中率降低一直查詢數(shù)據(jù)庫redis查詢不到數(shù)據(jù)庫出現(xiàn)很多非正常的url訪問key對應(yīng)的數(shù)據(jù)在數(shù)據(jù)源并不存在每次針對此key的請求從緩存獲取不到請求都會壓到數(shù)據(jù)源從而可能壓垮數(shù)據(jù)源。比如用一個不存在的用戶id獲取用戶信息不論緩存還是數(shù)據(jù)庫都沒有若黑客利用此漏洞進(jìn)行攻擊可能壓垮數(shù)據(jù)庫。2.解決方案一個一定不存在緩存及查詢不到的數(shù)據(jù)由于緩存是不命中時被動寫的并且出于容錯考慮如果從存儲層查不到數(shù)據(jù)則不寫入緩存這將導(dǎo)致這個不存在的數(shù)據(jù)每次請求都要到存儲層去查詢失去了緩存的意義。解決方案1 對空值緩存如果一個查詢返回的數(shù)據(jù)為空不管是數(shù)據(jù)是否不存在我們?nèi)匀话堰@個空結(jié)果null進(jìn)行緩存設(shè)置空結(jié)果的過期時間會很短最長不超過五分鐘2 設(shè)置可訪問的名單白名單使用bitmaps類型定義一個可以訪問的名單名單id作為bitmaps的偏移量每次訪問和bitmap里面的id進(jìn)行比較如果訪問id不在bitmaps里面進(jìn)行攔截不允許訪問。3 采用布隆過濾器實際上是一個很長的二進(jìn)制向量(位圖)和一系列隨機映射函數(shù)哈希函數(shù)。布隆過濾器可以用于檢索一個元素是否在一個集合中。它的優(yōu)點是空間效率和查詢時間都遠(yuǎn)遠(yuǎn)超過一般的算法缺點是有一定的誤識別率和刪除困難。)將所有可能存在的數(shù)據(jù)哈希到一個足夠大的bitmaps中一個一定不存在的數(shù)據(jù)會被 這個bitmaps攔截掉從而避免了對底層存儲系統(tǒng)的查詢壓力。4 進(jìn)行實時監(jiān)控當(dāng)發(fā)現(xiàn)Redis的命中率開始急速降低需要排查訪問對象和訪問的數(shù)據(jù)和運維人員配合可以設(shè)置黑名單限制服務(wù)二、緩存擊穿1.問題描述數(shù)據(jù)庫的訪問壓力瞬時增加redis里面沒有出現(xiàn)大量的key過期redis正常運行redis的某個key過期了大量訪問使用這個keykey對應(yīng)的數(shù)據(jù)存在但在redis中過期此時若有大量并發(fā)請求過來這些請求發(fā)現(xiàn)緩存過期一般都會從后端DB加載數(shù)據(jù)并回設(shè)到緩存這個時候大并發(fā)的請求可能會瞬間把后端DB壓垮。2.解決方案key可能會在某些時間點被超高并發(fā)地訪問是一種非常“熱點”的數(shù)據(jù)。這個時候需要考慮一個問題緩存被“擊穿”的問題。解決問題1預(yù)先設(shè)置熱門數(shù)據(jù)在redis高峰訪問之前把一些熱門數(shù)據(jù)提前存入到redis里面加大這些熱門數(shù)據(jù)key的時長2實時調(diào)整現(xiàn)場監(jiān)控哪些數(shù)據(jù)熱門實時調(diào)整key的過期時長3使用鎖1.就是在緩存失效的時候判斷拿出來的值為空不是立即去load db。2.先使用緩存工具的某些帶成功操作返回值的操作比如Redis的SETNX去set一個mutex key3.當(dāng)操作返回成功時再進(jìn)行l(wèi)oad db的操作并回設(shè)緩存,最后刪除mutex key4.當(dāng)操作返回失敗證明有線程在load db當(dāng)前線程睡眠一段時間再重試整個get緩存的方法。三、緩存雪崩1.問題描述數(shù)據(jù)庫壓力變大服務(wù)器崩潰在極少的時間段查詢大量的key的集中過期情況key對應(yīng)的數(shù)據(jù)存在但在redis中過期此時若有大量并發(fā)請求過來這些請求發(fā)現(xiàn)緩存過期一般都會從后端DB加載數(shù)據(jù)并回設(shè)到緩存這個時候大并發(fā)的請求可能會瞬間把后端DB壓垮。緩存雪崩與緩存擊穿的區(qū)別在于這里針對很多key緩存前者則是某一個key正常訪問緩存失效瞬間2.解決方案緩存失效時的雪崩效應(yīng)對底層系統(tǒng)的沖擊非??膳陆鉀Q方案1 構(gòu)建多級緩存架構(gòu)nginx緩存 redis緩存 其他緩存ehcache等2 使用鎖或隊列用加鎖或者隊列的方式保證來保證不會有大量的線程對數(shù)據(jù)庫一次性進(jìn)行讀寫從而避免失效時大量的并發(fā)請求落到底層存儲系統(tǒng)上。不適用高并發(fā)情況3 設(shè)置過期標(biāo)志更新緩存記錄緩存數(shù)據(jù)是否過期設(shè)置提前量如果過期會觸發(fā)通知另外的線程在后臺去更新實際key的緩存。4 將緩存失效時間分散開比如我們可以在原有的失效時間基礎(chǔ)上增加一個隨機值比如1-5分鐘隨機這樣每一個緩存的過期時間的重復(fù)率就會降低就很難引發(fā)集體失效的事件。