您好,登錄后才能下訂單哦!
這篇文章主要介紹“github緩存穿透的解決方法是什么”,在日常操作中,相信很多人在github緩存穿透的解決方法是什么問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”github緩存穿透的解決方法是什么”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
使用緩存時有三個目標:
第一,加快用戶訪問速度,提高用戶體驗
第二,降低后端負載,減少潛在的風險,保證系統平穩
第三,保證數據“盡可能”及時更新
緩存穿透是指查詢一個根本不存在的數據,緩存層和存儲層都不會命中,但是出于容錯的考慮,如果從存儲層查不到數據則不寫入緩存層
緩存層不命中
存儲層不命中,所以不將空結果寫回緩存
返回空結果
緩存穿透將導致不存在的數據每次請求都要到存儲層去查詢,失去了緩存保護后端存儲的意義。
緩存穿透問題可能會使后端存儲負載加大,由于很多后端存儲不具備高并發性,甚至可能造成后端存儲宕掉。通常可以在程序中分別統計總調用數、緩存層命中數、存儲層命中數,如果發現大量存儲層空命中,可能就是出現了緩存穿透問題。
造成緩存穿透的基本有兩個:
業務自身代碼或者數據出現問題
一些惡意攻擊、爬蟲等造成大量空命中
當存儲層不命中后,仍然將空對象保留到緩存層中,之后再訪問這個數據將會從緩存中獲取,保護了后端數據源。
緩存空對象會有兩個問題:
空值做了緩存,意味著緩存層中存了更多的鍵,需要更多的內存空間 ( 如果是攻擊,問題更嚴重 ),比較有效的方法是針對這類數據設置一個較短的過期時間,讓其自動剔除。
緩存層和存儲層的數據會有一段時間窗口的不一致,可能會對業務有一定影響。例如過期時間設置為 5 分鐘,如果此時存儲層添加了這個數據,那此段時間就會出現緩存層和存儲層數據的不一致,此時可以利用消息系統或者其他方式清除掉緩存層中的空對象。
在訪問緩存層和存儲層之前,將存在的 key 用布隆過濾器提前保存起來,做第一層攔截。例如: 一個個性化推薦系統有 4 億個用戶 ID,每個小時算法工程師會根據每個用戶之前歷史行為做出來的個性化放到存儲層中,但是最新的用戶由于沒有歷史行為,就會發生緩存穿透的行為,為此可以將所有有個性化推薦數據的用戶做成布隆過濾器。如果布隆過濾器認為該用戶 ID 不存在,那么就不會訪問存儲層,在一定程度保護了存儲層。
可以利用 Redis 的 Bitmaps 實現布隆過濾器
這種方法適用于數據命中不高,數據相對固定實時性低(通常是數據集較大)的應用場景,代碼維護較為復雜,但是緩存空間占用少。
預防和解決緩存雪崩問題,可以從以下三個方面進行著手。
1)保證緩存層服務高可用性。
和飛機都有多個引擎一樣,如果緩存層設計成高可用的,即使個別節點、個別機器、甚至是機房宕掉,依然可以提供服務
2)依賴隔離組件為后端限流并降級。
無論是緩存層還是存儲層都會有出錯的概率,可以將它們視同為資源。作為并發量較大的系統,假如有一個資源不可用,可能會造成線程全部 hang 在這個資源上,造成整個系統不可用。降級在高并發系統中是非常正常的:比如推薦服務中,如果個性化推薦服務不可用,可以降級補充熱點數據,不至于造成前端頁面是開天窗。
在實際項目中,我們需要對重要的資源 ( 例如 Redis、 MySQL、 Hbase、外部接口 ) 都進行隔離,讓每種資源都單獨運行在自己的線程池中,即使個別資源出現了問題,對其他服務沒有影響。但是線程池如何管理,比如如何關閉資源池,開啟資源池,資源池閥值管理,這些做起來還是相當復雜的,這里推薦一個 Java 依賴隔離工具 Hystrix(https://github.com/Netflix/Hystrix)
3)提前演練。在項目上線前,演練緩存層宕掉后,應用以及后端的負載情況以及可能出現的問題,在此基礎上做一些預案設定。
開發人員使用緩存 + 過期時間的策略既可以加速數據讀寫,又保證數據的定期更新,這種模式基本能夠滿足絕大部分需求。但是有兩個問題如果同時出現,可能就會對應用造成致命的危害:
當前 key 是一個熱點 key( 例如一個熱門的娛樂新聞),并發量非常大。
重建緩存不能在短時間完成,可能是一個復雜計算,例如復雜的 SQL、多次 IO、多個依賴等。
在緩存失效的瞬間,有大量線程來重建緩存,造成后端負載加大,甚至可能會讓應用崩潰。
解決思路:
1)互斥鎖 (mutex key)
只允許一個線程重建緩存,其他線程等待重建緩存的線程執行完,重新從緩存獲取數據即可
2)永遠不過期,“永遠不過期”包含兩層意思:
從緩存層面來看,確實沒有設置過期時間,所以不會出現熱點 key 過期后產生的問題,也就是“物理”不過期。
從功能層面來看,為每個 value 設置一個邏輯過期時間,當發現超過邏輯過期時間后,會使用單獨的線程去構建緩存。
方案比較:
互斥鎖 (mutex key):這種方案思路比較簡單,但是存在一定的隱患,如果構建緩存過程出現問題或者時間較長,可能會存在死鎖和線程池阻塞的風險,但是這種方法能夠較好的降低后端存儲負載并在一致性上做的比較好。
" 永遠不過期 ":這種方案由于沒有設置真正的過期時間,實際上已經不存在熱點 key 產生的一系列危害,但是會存在數據不一致的情況,同時代碼復雜度會增大。
到此,關于“github緩存穿透的解決方法是什么”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。