Redis 快取穿透 快取併發 快取雪崩

2021-08-26 09:45:10 字數 2198 閱讀 4849

快取穿透、快取併發、快取雪崩是常見的由於高併發而導致的快取問題。下面講解其產生原因和解決方案。

快取穿透通常是由於惡意攻擊或無意造成的;快取併發是由於設計不足造成的;快取雪崩是由於大量快取同時失效造成的。三種問題都比較典型,是難以防範和解決的。下面講解其解決方案,以便在快取設計中進行參考。

1、快取穿透

快取穿透是指使用者使用不存在的key進行大量的高併發查詢,這種請求不能命中快取,每次請求都要穿透到後端資料庫系統進行查詢,使資料庫壓力過大,導致資料庫連線異常。

解決方案

(一) 採用互斥鎖,每次請求資料庫之前先獲取鎖,獲得鎖了再訪問資料庫,沒得到鎖,則休眠一段時間重試。

(二) 採用非同步更新策略,無論key 是否取到值,都直接返回。value值中維護乙個快取失效的時間,快取如果過期,則非同步起乙個執行緒去讀資料庫,更新快取。需要做快取預熱 (專案啟動前,先載入快取)操作。

(三) 提供能迅速判斷請求是否有效的攔截機制,比如,布隆過濾器,內部維護一系列合法有效的key。迅速判斷出,請求所攜帶的key是否有效。如果不合法,則直接返回。

(四) 將請求得到的空值快取起來,再次接收到同樣的查詢請求時,若命中快取且值為空,就直接返回,不會穿透到資料庫,避免快取穿透。如果攻擊者猜到了我們的使用這種方案,每次都使用不同的引數查詢,這就需要我們對輸入的引數進行過濾。例如,如果我們使用id 進行查詢,我們可以對id的格式進行分析,如果不符合格式,就直接拒絕;或者在id上放上時間資訊,根據時間資訊判斷id是否合法;或者是否是我們曾經生成過的id,這樣可以攔截一定的請求。

2、快取併發

快取併發的問題通常發生在高併發的場景下,分兩種情況:

第一種:當乙個快取key過期時,因為訪問這個快取key 的請求量較大,多個請求同時發現快取過期,因此多個請求會同時訪問資料庫來查詢最新資料,並且回寫快取,這樣會造成應用和資料庫的負載增加,效能降低,由於併發較高,甚至會導致資料庫被壓死。

第二種:多個子系統去set同乙個key,網上給的大多數解決方案都是使用redis事務機制,但是這是行不通的,因為生產中redis都是集群部署,做了資料分片操作,乙個事務涉及多個key的時候,這些key不一定都儲存在乙個redis-server上。

第一種快取併發(get併發)的解決方案:

(一)分布式鎖,保證對於每個key同時只有乙個執行緒去查詢資料庫,其他執行緒沒有獲得分布式鎖,只需等待即可。這種方式將高併發壓力轉移到了分布式鎖,因此對分布式鎖壓力很大。

(二)本地鎖,與分布式鎖一樣,我們採用本地鎖限制只有乙個執行緒去查詢資料庫,而其他執行緒只需要等待,等前面的執行緒查到資料後再訪問快取,這種方式只能限制乙個服務節點只有乙個執行緒去查詢資料庫,如果乙個服務有多個節點,則還會有多個資料庫查詢操作,也就是在節點數量較多 ( 服務多節點部署 ) 的情況下不能完全解決快取併發問題。

(三)軟過期,軟過期是指對快取中的資料設定失效時間,就是不使用快取服務提供的過期時間,而是業務層在資料中儲存過期時間資訊 ( 可以考慮優先佇列或者最小堆實現 ),由業務程式判斷快取是否過期並更新,在發現資料即將過期時,將快取的時效延長,同時程式可以派遣乙個新執行緒去資料庫獲取最新資料,其他執行緒看到延長了過期時間,就會繼續使用舊資料,等派遣的執行緒獲取到最新資料在更新快取。

第二種快取併發(set併發)的解決方案:

(一) 如果對這個進行set 操作,不要求順序

這種情況下,準備乙個分布式鎖,大家去搶鎖,搶到鎖就做set操作即可,比較簡單。

(二) 如果這個key進行set 操作,要求順序

假設有乙個key1,系統a要將key1設定為value1 ,系統b要將key1設定為 value2,系統c要將key1 設定為value3.

期望key1的value值按照 value1 –> value2 –> value3的順序變化。這時候我們在插入到資料資料庫的時候,需要儲存乙個時間戳。假設時間戳如下:

系統a key1 

系統b key1

系統c key1

那麼,假設這會系統b先搶到鎖,將key1 設定為。接下來系統a搶到鎖,發現自己的valuea的時間戳早於快取中的時間戳,那麼不做set操作了。以此類推。

(三) 使用訊息佇列,將set變成序列訪問。

3、快取雪崩

Redis快取穿透 快取併發 快取雪崩

一 快取穿透 1.產生原因 查詢方式是先查詢快取 如果快取不存在則查詢資料庫 將查詢的結果回寫到快取 穿透的概念是快取不存在的情況下查詢資料庫 高併發應用下可能造成資料庫壓力過大 2.解決方案 2.1 將對應的key為空的值也快取起來,減少資料庫的查詢 2.2 校驗key值的合法性 防止惡意攻擊 二...

Redis 十四 快取雪崩 快取穿透 快取併發

快取雪崩 資料未載入到快取中,或者快取同一時間大面積的失效,從而導致所有請求都去查資料庫,導致資料庫cpu和記憶體負載過高,甚至宕機。比如乙個雪崩的簡單過程 1 redis集群大面積故障 2 快取失效,但依然大量請求訪問快取服務redis 3 redis大量失效後,大量請求轉向到mysql資料庫 4...

redis的快取穿透 快取併發 快取失效

學習 截選乙個集體快取失效解決辦法 引起這個問題的主要原因還是高併發的時候,平時我們設定乙個快取的過期時間時,可能有一些會設定1分鐘啊,5分鐘這些,併發很高時可能會出在某乙個時間同時生成了很多的快取,並且過期時間都一樣,這個時候就可能引發一當過期時間到後,這些快取同時失效,請求全部 到db,db可能...