快取穿透問題解決!!!

2021-09-01 13:07:56 字數 1497 閱讀 7511

快取穿透是指查詢乙個一定不存在的資料,由於快取是不命中時被動寫的,並且出於容錯考慮,如果從儲存層查不到資料則不寫入快取,這將導致這個不存在的資料每次請求都要到儲存層去查詢,失去了快取的意義。在流量大時,可能db就掛掉了,要是有人利用不存在的key頻繁攻擊我們的應用,這就是漏洞。

有很多種方法可以有效地解決快取穿透問題,最常見的則是採用布隆過濾器,將所有可能存在的資料雜湊到乙個足夠大的bitmap中,乙個一定不存在的資料會被 這個bitmap攔截掉,從而避免了對底層儲存系統的查詢壓力。另外也有乙個更為簡單粗暴的方法(我們採用的就是這種),如果乙個查詢返回的資料為空(不管是數 據不存在,還是系統故障),把這個空結果進行快取,但它的過期時間會很短,最長不超過五分鐘

快取雪崩是指在我們設定快取時採用了相同的過期時間,導致快取在某一時刻同時失效,請求全部**到db,db瞬時壓力過重雪崩。

這個沒有完美解決辦法,但可以分析使用者行為,盡量讓失效時間點均勻分布。大多數系統設計者考慮用加鎖或者佇列的方式保證快取的單執行緒(程序)寫,從而避免失效時大量的併發請求落到底層儲存系統上

1. 加鎖排隊. 限流-- 限流演算法. 1.計數 2.滑動視窗 3.  令牌桶token bucket 4.漏桶 leaky bucket [1]

在快取失效後,通過加鎖或者佇列來控制讀資料庫寫快取的執行緒數量。比如對某個key只允許乙個執行緒查詢資料和寫快取,其他執行緒等待。

業界比較常用的做法,是使用mutex。簡單地來說,就是在快取失效的時候(判斷拿出來的值為空),不是立即去load db,而是先使用快取工具的某些帶成功操作返回值的操作(比如redis的setnx或者memcache的add)去set乙個mutex key,當操作返回成功時,再進行load db的操作並回設快取;否則,就重試整個get快取的方法。

setnx,是「set if not exists」的縮寫,也就是只有不存在的時候才設定,可以利用它來實現鎖的效果。

2.資料預熱

可以通過快取reload機制,預先去更新快取,再即將發生大併發訪問前手動觸發載入快取不同的key,設定不同的過期時間,讓快取失效的時間點盡量均勻

3.做二級快取,或者雙快取策略。

a1為原始快取,a2為拷貝快取,a1失效時,可以訪問a2,a1快取失效時間設定為短期,a2設定為長期。

4.快取永遠不過期

這裡的「永遠不過期」包含兩層意思:

(1) 從快取上看,確實沒有設定過期時間,這就保證了,不會出現熱點key過期問題,也就是「物理」不過期。

(2) 從功能上看,如果不過期,那不就成靜態的了嗎?所以我們把過期時間存在key對應的value裡,如果發現要過期了,通過乙個後台的非同步執行緒進行快取的構建,也就是「邏輯」過期.

從實戰看,這種方法對於效能非常友好,唯一不足的就是構建快取時候,其餘執行緒(非構建快取的執行緒)可能訪問的是老資料,但是對於一般的網際網路功能來說這個還是可以忍受。

快取失效 快取穿透問題解決方案

快取失效 快取雪崩 引起這個原因的主要因素是高併發下,我們一般設定乙個快取的過期時間時,可能有一些會設定5分鐘啊,10分鐘這些 併發很高時可能會出在某乙個時間同時生成了很多的快取,並且過期時間在同一時刻,這個時候就可能引發 當過期時間到後,這些快取同時失效,請求全部 到db,db可能會壓力過重。處理...

快取雪崩和快取穿透問題解決方案

快取雪崩 簡介 快取同一時間大面積的失效,所以,後面的請求都會落到資料庫上,造成資料庫短時間內承受大量請求而崩掉。快取穿透 簡介 一般是黑客故意去請求快取中不存在的資料,導致所有的請求都落到資料庫上,造成資料庫短時間內承受大量請求而崩掉。解決辦法 有很多種方法可以有效地解決快取穿透問題,最常見的則是...

Redis 擴充套件 快取雪崩和快取穿透問題解決方案

快取同一時間大面積失效,所以,後面的請求都會落到資料庫上,造成資料庫短時間內承受大量的請求而崩掉。解決辦法 快取雪崩解決方案 一般是故意請求快取中不存在的資料,導致所有的請求都落到資料庫上,造成資料庫短時間內承受大量的請求而崩掉。解決辦法 只要用到快取,就可能會涉及到快取與資料庫雙儲存雙寫,只要是雙...