Redis快取穿透 快取擊穿 快取雪崩

2021-10-03 12:20:47 字數 1909 閱讀 9096

4、總結

一般企業都會用到mysql等關係型資料庫,當訪問量不大的時候還可以支撐;當併發量高的時候,比如商品搶購或者主頁訪問瞬間較大的時候,請求直接到達db,可能會導致系統效能急劇下降以致癱瘓。db是面向磁碟的,磁碟io是比較重的操作,效能較低。為了克服上述的問題,通常需要在客戶端和db之間引入一層快取nosql技術,這是一種基於記憶體的資料庫,並提供一定的持久化功能,比如redis。但是引入快取之後,又有可能出現快取穿透等問題。

快取穿透:key對應的資料在資料來源並不存在,每次針對此key的請求從快取獲取不到,請求都會到資料來源,從而可能壓垮資料來源。比如用乙個不存在的使用者id獲取使用者資訊,不論快取還是資料庫都沒有,若黑客利用此漏洞進行攻擊可能壓垮資料庫。

快取擊穿:key對應的資料存在,但在redis中過期,此時若有大量併發請求過來,這些請求發現快取過期一般都會從後端db載入資料並回設到快取,這個時候大併發的請求可能會瞬間把後端db壓垮。

快取雪崩:當快取伺服器重啟或者大量快取集中在某乙個時間段失效,這樣在失效的時候,也會給後端系統(比如db)帶來很大壓力。

查詢乙個一定不存在的資料,快取不命中,最終達到db,查詢不到資料又不寫入快取,導致每次都要查db,失去快取的意義。

方案:布隆過濾器,維護乙個足夠大的bitmap,不存在的key一定會被攔截到,降低對底層db的查詢壓力

簡單粗暴的方法,如果從db重查詢為空,則快取乙個預設的值代表空值,過期時間設定較短些,最長不超過5min

粗暴方式的偽**:

//偽**

public object getvalue()

cachevalue = redishelper.

get(cachekey);if

(cachevalue != null)

else

redishelper.

add(cachekey, cachevalue, cachetime)

;return cachevalue;

}}

熱點key(某些時間點被超高併發訪問)失效,請求直達db。

方案:設定永不過期,另起排程任務定時更新key的值

業界比較常用的做法,是使用mutex。簡單地來說,就是在快取失效的時候(判斷拿出來的值為空),不是立即去load db,而是先使用快取工具的某些帶成功操作返回值的操作(比如redis的setnx或者memcache的add)去set乙個mutex key,當操作返回成功時,再進行load db的操作並回設快取;否則,就重試整個get快取的方法。setnx,是「set if not exists」的縮寫,也就是只有不存在的時候才設定,可以利用它來實現鎖的效果。

互斥鎖偽**:

public string get

(key)

else

}else

}

與快取擊穿的區別在於這裡針對多個key,快取擊穿針對乙個key。

方案:加鎖排隊:減輕資料庫的壓力,並沒有提高系統吞吐量。假設在高併發下,快取重建期間key是鎖著的,這是過來1000個請求999個都在阻塞的。同樣會導致使用者等待超時,這是個治標不治本的方法!

設定過期標誌更新快取

為key設定不同的隨機的快取失效時間

設定過期標誌更新快取偽**

public object get()

else);

return cachevalue;

}}

解釋說明:

針對業務系統,永遠都是具體情況具體分析;一切不以業務為基礎的框架設計都是耍流氓,所以還是要具體問題具體分析,找出乙個最合適的方案。

參考:

Redis 快取穿透 快取擊穿 快取雪崩

快取穿透是指快取和資料庫中都沒有的資料,而使用者不斷發起請求,如發起為id為小於0的資料或id為特別大等不存在的資料。這時的使用者很可能是攻擊者,攻擊會導致資料庫壓力過大。舉例 通過分類id查詢廣告集合 param categoryid 廣告分類id return 廣告集合 public listf...

Redis快取穿透 快取擊穿 快取雪崩

指的是,redis快取中和資料庫中都沒有的資料,使用者不斷向伺服器發起請求,導致資料庫壓力過大。一般的流程查詢流程存在redis快取穿透bug 沒獲取到資料,到資料庫中查詢 如果一直沒獲取和查詢到資料,使用者不斷發起請求,資料庫就會不斷地進行查詢操作,導致資料庫壓力增大,導致快取擊穿。解決方案 阻止...

REDIS快取雪崩 快取穿透 快取擊穿

快取雪崩 同一時刻有大量key失效,導致大量請求到資料庫 解決方案1 key失效時間加上隨機值,或者更高階的演算法分散失效時間。解決方案2 沒有資料時也cache下,過期時間可設定短點,不把過多請求打到db去 快取穿透 當查詢redis中沒有的資料時,該查詢會下沉到資料庫層,同時資料庫層也沒有該資料...