首先來了解幾個概念:
緩存穿透:大量請求根本不存在的key
緩存雪崩:redis中大量key集體過期
緩存擊穿:redis中一個熱點key過期(大量用戶訪問該熱點key,但是熱點key過期)
穿透解決方案
對空值進行緩存
設置白名單
使用布隆過濾器
網警
雪崩解決方案
進行預先的熱門詞匯的設置,進行key時長的調整
實時調整,監控哪些數據是熱門數據,實時的調整key的過期時長
使用鎖機制
擊穿解決方案
進行預先的熱門詞匯的設置,進行key時長的調整
實時調整,監控哪些數據是熱門數據,實時的調整key的過期時長
使用鎖機制
三者出現的根本原因在于Redis命中率下降,請求直接打在DB上。
正常情況下,大量的資源請求都會被redis響應,在redis得不到響應的小部分請求才會去請求DB,這樣DB的壓力是非常小的,是可以正常工作的(如下圖)
如果大量的請求在redis上得不到響應,那么就會導致這些請求會直接去訪問DB,導致DB的壓力瞬間變大而卡死或者宕機。
大量的高并發的請求打在redis上
這些請求發現redis上并沒有需要請求的資源,redis命中率降低
因此這些大量的高并發請求轉向DB(數據庫服務器)請求對應的資源
DB壓力瞬間增大,直接將DB打垮,進而引發一系列“災害”
如下圖所示
那么為什么redis會沒有需要訪問的數據呢?通過分析大致可以總結為三種情況,也就對應著redis的雪崩、穿透和擊穿
情景分析
緩存穿透
緩存穿透產生的原因:請求根本不存在的資源(DB本身就不存在,Redis更是不存在)
舉例(情景在線):客戶端發送大量的不可響應的請求
當大量的客戶端發出類似于:http://localhost:8080/user/19833?id=-3872 的請求,就可能導致出現緩存穿透的情況。因為數據庫DB中本身就沒有id=-3872的用戶的數據,所以Redis也沒有對應的數據,那么這些請求在redis就得不到響應,就會直接打在DB上,導致DB壓力過大而卡死情景在線或宕機。
緩存穿透很有可能是黑客攻擊所為,黑客通過發送大量的高并發的無法響應的請求給服務器,由于請求的資源根本就不存在,DB就很容易被打垮了。
解決方案
對空值進行緩存:
類似于上面的例子,雖然數據庫中沒有id=-3872的用戶的數據,但是在redis中對他進行緩存(key=-3872,value=null),這樣當請求到達redis的時候就會直接返回一個null的值給客戶端,避免了大量無法訪問的數據直接打在DB上
實時監控:
對redis進行實時監控,當發現redis中的命中率下降的時候進行原因的排查,配合運維人員對訪問對象和訪問數據進行分析查詢,從而進行黑名單的設置限制服務(拒絕黑客攻擊)
使用布隆過濾器
使用BitMap作為布隆過濾器,將目前所有可以訪問到的資源通過簡單的映射關系放入到布隆過濾器中(哈希計算),當一個請求來臨的時候先進行布隆過濾器的判斷,如果有那么才進行放行,否則就直接攔截
接口校驗
類似于用戶權限的攔截,對于id=-3872這些無效訪問就直接攔截,不允許這些請求到達Redis、DB上。
注意事項:
使用空值作為緩存的時候,key設置的過期時間不能太長,防止占用太多redis資源
使用空值作為緩存只能防止黑客重復使用相同的id暴力攻擊,但是如果黑客使用動態的無效id攻擊就沒有效果(需要配合網警)
使用布隆過濾器也是有哈希沖突的可能
緩存雪崩
緩存雪崩產生的原因:redis中大量的key集體過期
舉例:
當redis中的大量key集體過期,可以理解為redis中的大部分數據都被清空了(失效了),那么這時候如果有大量并發的請求來到,那么redis就無法進行有效的響應(命中率急劇下降),請求就都打到DB上了,到時DB直接崩潰。
解決方案:
將失效時間分散開
通過使用自動生成隨機數使得key的過期時間是隨機的,防止集體過期
使用多級架構
使用nginx緩存+redis緩存+其他緩存,不同層使用不同的緩存,可靠性更強
設置緩存標記
記錄緩存數據是否過期,如果過期會觸發通知另外的線程在后臺去跟新實際的key
使用鎖或者隊列的方式
如果查不到就加上排它鎖,其他請求只能進行等待
緩存擊穿
產生緩存雪崩的原因:redis中的某個熱點key過期,但是此時有大量的用戶訪問該過期key
舉例:
類似于“某男明星塌房事件”上了熱搜,這時候大量的“粉絲”都在訪問該熱點事件,但是可能優于某種原因,redis的這個熱點key過期了,那么這時候大量高并發對于該key的請求就得不到redis的響應,那么就會將請求直接打在DB服務器上,導致整個DB癱瘓。
解決方案:
提前對熱點數據進行設置
類似于新聞、某博等軟件都需要對熱點數據進行預先設置在redis中
監控數據,適時調整
監控哪些數據是熱門數據,實時的調整key的過期時長
使用鎖機制
最后的防線,當熱點key過期,那么就使用鎖機制防止大量的請求直接打在DB
-
緩存
+關注
關注
1文章
241瀏覽量
26724 -
過濾器
+關注
關注
1文章
432瀏覽量
19684 -
key
+關注
關注
0文章
51瀏覽量
12836
原文標題:緩存被穿透了怎么辦?
文章出處:【微信號:magedu-Linux,微信公眾號:馬哥Linux運維】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論