緩存處理流程
前台請求,后台先從緩存中取數據,取到直接返回結果,取不到時從數據庫中取,數據庫取到更新緩存,並返回結果,數據庫也沒取到,那直接返回空結果。
緩存穿透
描述:
緩存穿透是指用戶對緩存和數據庫中都沒有的數據不斷發起請求,比如用一個不存在的用戶id獲取用戶信息,不論緩存還是數據庫都沒有,這時的用戶很可能是攻擊者,攻擊會導致數據庫壓力過大。
解決方案:
-
對空值緩存:如果一個查詢返回的數據為空(不管是數據是否不存在),我們仍然把這個空結果(null)進行緩存,設置空結果的過期時間會很短,最長不超過五分鍾,這樣可以防止攻擊用戶反復用同一個id暴力攻擊。
-
設置可訪問的名單(白名單):
使用bitmaps類型定義一個可以訪問的名單,名單id作為bitmaps的偏移量,每次訪問和bitmap里面的id進行比較,如果訪問id不在bitmaps里面,進行攔截,不允許訪問。
-
采用布隆過濾器:布隆過濾器可以用於檢索一個元素是否在一個集合中。它的優點是空間效率和查詢時間都遠遠超過一般的算法,缺點是有一定的誤識別率和刪除困難。將所有可能存在的數據哈希到一個足夠大的bitmaps中,一個一定不存在的數據會被 這個bitmaps攔截掉,從而避免了對底層存儲系統的查詢壓力。
-
進行實時監控:當發現Redis的命中率開始急速降低,需要排查訪問對象和訪問的數據,和運維人員配合,可以設置黑名單限制服務。
緩存擊穿
描述:
緩存擊穿是指某個 key 對應的數據在后端數據庫中存在,但在redis緩存中過期,此時若有大量並發請求過來,這些請求發現緩存過期一般都會從后端數據庫加載數據並回設到緩存,這個時候大並發的請求可能會瞬間把后端數據庫壓垮。一般都是由於某個 key 剛好過期了,而此時突然有大量的訪問使用這個 key。
解決方案:
-
預先設置熱門數據:在redis高峰訪問之前,把一些熱門數據提前存入到redis里面,加大這些熱門數據key的時長。
-
實時調整:現場監控哪些數據熱門,實時調整key的過期時長。
-
加互斥鎖:流程如下圖所示
緩存雪崩
描述:
緩存雪崩是指緩存中數據大批量過期,而查詢數據量巨大,引起數據庫壓力過大甚至down機。
與緩存擊穿的區別:
緩存擊穿指在某一極小時間段內,對同一過期數據的大量訪問;(大量請求都訪問某一個過期的key)
緩存雪崩指在某一極小時間段內,對很多已過期的不同數據的大量訪問;(大量請求都訪問某一批過期的key)
解決方案:
-
將緩存過期的時間分散開:
比如我們可以在原有的失效時間基礎上增加一個隨機值,比如1-5分鍾隨機,這樣每一個緩存的過期時間的重復率就會降低,防止同一時間大量數據過期現象發生。
-
構建多級緩存架構:nginx緩存 + redis緩存 +其他緩存(ehcache等)
-
設置過期標志更新緩存:
記錄緩存數據是否過期(設置提前量),如果過期會觸發通知另外的線程在后台去更新實際key的緩存。