快取穿透、快取并發和快取雪崩是常見的由于并發量大而導致的快取問題,這里記錄下其產生原因和解決方案,
快取穿透是由惡意攻擊或無意造成的;快取并發是由設計不足造成的;快取雪崩是由快取同時失效造成的,
一、快取穿透
概念:
快取穿透指的是使用不存在的 key 進行大量的高并發查詢,這導致快取無法命中,每次請求都要穿透到后端資料庫系統進行查詢,使資料庫壓力過大,甚至使資料庫服務被壓死,
解決方案:
1、我們通常將空值快取起來,再次接收到同樣的查詢請求時,若命中快取并且值為空,就會直接回傳,不會穿透的資料庫,避免快取穿透,
2、當然,有時惡意襲擊者可以猜到我們使用了這種方案,每次都會使用不同的引數來查詢,這就需要我們對輸入的引數進行過濾,例如,如果我們使用 ID 進行查詢,則可以對 ID 的格式進行分析,如果不符合產生 ID 的規則,就直接拒絕,或者在 ID 上放入時間資訊,根據時間資訊判斷 ID 是否合法 ,或者是否是我們曾經生成的 ID,這樣可以攔截一定的無效請求,
二、快取并發
概念:
快取并發的問題通常發生在高并發的場景下,當一個快取 key 過期時,因為訪問這個快取 key 的請求量較大,多個請求同時發現快取過期,因此多個請求會同時訪問資料庫來查詢最新的資料,并且回寫快取,這樣會造成應用和資料庫的負載增加,性能降低,由于并發較高,甚至會導致資料庫被壓死,
解決方案:
1、分布式鎖
使用分布式鎖,保證對于每個 key 同時只有一個執行緒去查詢后端服務,其他執行緒沒有獲得分布式鎖的權限,因此只需要等待即可,這種方式將高并發的壓力轉移到了分布式鎖,因此對分布式鎖的考驗很大,
2、本地鎖
與分布式鎖類似,我們通過本地鎖的方式來限制只有一個執行緒去資料庫查詢資料,而其他執行緒只需等待,等前面的執行緒查詢到資料后再訪問快取,但是,這種方法只能限制一個服務節點只有一個執行緒去資料庫中查詢,如果一個服務有多個節點,則還會有多個資料庫查詢操作,也就是說在節點數量較多的情況下并沒有完全解決快取并發的問題,
3、軟過期
軟過期是指對快取中的資料設定失效時間,就是不使用快取服務器提供的過期時間,而是業務層在資料中存盤過期時間資訊,由業務程式判斷是否過期并更新,在發現了資料即將過期時,將快取的時效延長,程式可以派遣一個執行緒去資料庫中獲取最新的資料,其他執行緒這時看到延長了的過期時間,就會繼續使用舊資料,等派遣的執行緒獲取最新資料后再更新快取,也可以通過異步更新服務來更新設定軟過期的快取,這樣應用層就不用關心快取并發的問題了,
三、快取雪崩
概念:
快取雪崩指快取服務器重啟或者大量快取集中在某一個時間段內失效,給后端資料庫造成瞬間的負載升高的壓力,甚至壓垮資料庫的情況,
解決方案:
通常的解決辦法是對不同的資料使用不同的失效時間,甚至對相同的資料、不同的請求使用不同的失效時間,例如,我們要快取 user 資料,會對每個用戶的資料設定不同的快取過期時間,可以定義一個基礎時間,假設 10 秒,然后加上一個兩秒以內的亂數,過期時間為 10 ~ 12 秒,就會避免快取雪崩,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/10057.html
標籤:PHP
下一篇:node更新報錯:checkPermissions Missing write access to /usr/lib/node_modules/n
