快取擊穿、快取併發和快取雪崩是常見的由於併發量大而導致的快取問題,本節講解其產生原因和解決方案。
快取擊穿通常是由惡意攻擊或者無意造成的;快取併發是由設計不足造成的;快取雪崩是由快取同時失效造成的,三種問題都比較典型,也是難以防範和解決的。本節給出通用的解決方案,以供在快取設計的過程中參考和使用。
快取擊穿
快取擊穿指的是使用不存在的key進行大量的高併發查詢,這導致快取無法命中,每次請求都要擊穿到後端資料庫系統進行查詢,使資料庫壓力過大,甚至使資料庫服務被壓死。
我們通常將空值快取起來,再次接收到同樣的查詢請求時,若命中快取並且值為空,就會直接返回,不會透傳到資料庫,避免快取擊穿。當然,有時惡意襲擊者可以猜到我們使用了這種方案,每次都會使用不同的引數來查詢,這就需要我們對輸入的引數進行過濾,例如,如果我們使用id進行查詢,則可以對id的格式進行分析,如果不符合產生id的規則,就直接拒絕,或者在id上放入時間資訊,根據時間資訊判斷id是否合法,或者是否是我們曾經生成的id,這樣可以攔截一定的無效請求。
當然,每個設計人員都應該對服務的可用性和健壯性負責,應該建設健壯的服務,讓我們的服務像不倒翁一樣,因此,我們需要對服務設計限流和熔斷等功能,請參考《分布式服務架構:原理、設計與實戰》中第1章關於微服務設計模式的內容。
快取併發
快取併發的問題通常發生在高併發的場景下,當乙個快取key過期時,因為訪問這個快取key 的請求量較大,多個請求同時發現快取過期,因此多個請求會同時訪問資料庫來查詢最新資料,並且回寫快取,這樣會造成應用和資料庫的負載增加,效能降低,由於併發較高,甚至會導致資料庫被壓死。
分布式鎖
使用分布式鎖,保證對於每個key同時只有乙個執行緒去查詢後端服務,其他執行緒沒有獲得分布式鎖的許可權,因此只需要等待即可。這種方式將高併發的壓力轉移到了分布式鎖,因此對分布式鎖的考驗很大。
本地鎖
與分布式鎖類似,我們通過本地鎖的方式來限制只有乙個執行緒去資料庫中查詢資料,而其他執行緒只需等待,等前面的執行緒查詢到資料後再訪問快取。但是,這種方法只能限制乙個服務節點只有乙個執行緒去資料庫中查詢,如果乙個服務有多個節點,則還會有多個資料庫查詢操作,也就是說在節點數量較多的情況下並沒有完全解決快取併發的問題。
軟過期
軟過期指對快取中的資料設定失效時間,就是不使用快取服務提供的過期時間,而是業務層在資料中儲存過期時間資訊,由業務程式判斷是否過期並更新,在發現了資料即將過期時,將快取的時效延長,程式可以派遣乙個執行緒去資料庫中獲取最新的資料,其他執行緒這時看到延長了的過期時間,就會繼續使用舊資料,等派遣的執行緒獲取最新資料後再更新快取。
也可以通過非同步更新服務來更新設定軟過期的快取,這樣應用層就不用關心快取併發的問題了。
快取雪崩
快取雪崩指快取伺服器重啟或者大量快取集中在某乙個時間段內失效,給後端資料庫造成瞬時的負載公升高的壓力,甚至壓垮資料庫的情況。
通常的解決辦法是對不同的資料使用不同的失效時間,甚至對相同的資料、不同的請求使用不同的失效時間,例如,我們要快取user資料,會對每個使用者的資料設定不同的快取過期時間,可以定義乙個基礎時間,假設10秒,然後加上乙個兩秒以內的隨機數,過期時間為10~12秒,就會避免快取雪崩。
什麼是快取穿透 快取雪崩 快取擊穿
快取穿透是指查詢乙個一定不存在的資料時,由於在快取中沒有這個key,這時會到db中去查詢,可是db中也沒有這條資料,這時也無法寫入快取,這就造成了快取穿透,如果這時有人利用這個漏洞頻繁攻擊應用,db就可能掛掉了 解決方案 可以把key存入快取中,value設定為空,過期時間最多不超過5分鐘 快取雪崩...
什麼是redis快取穿透,快取雪崩,快取擊穿
一.快取穿透 快取穿透是指查詢資料庫中一定不存在的資料,我們正常的操作流程,在查詢資料庫前,先去查詢快取,如果key不存在或者key過期失效,再去查詢資料庫,並把查詢到的物件放到快取中,如果查詢到的資料為null,不新增快取。流程 二.快取雪崩 快取雪崩可以理解為在某個時間段,快取集中過期,然後這段...
什麼是Redis快取穿透 快取雪崩 快取擊穿
快取穿透,是指查詢乙個資料庫一定不存在的資料。正常的使用快取流程大致是,資料查詢先進行快取查詢,如果key不存在或者key已經過期,再對資料庫進行查詢,並把查詢到的物件,放進快取。如果資料庫查詢物件為空,則不放進快取。採用快取空值的方式,也就是 流程 中第5步,如果從資料庫查詢的物件為空,也放入快取...