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