redis-緩存崩潰
緩存崩潰
作者:w08e
redis實戰之各種崩潰 雪崩 擊穿 穿透 以及預熱
緩存雪崩
回答話術
緩存雪崩是應用系統指在某個時間點上,緩存中的大部分數據同時失效,導致大量的請求直接訪問底層數據庫或后端服務,從而造成數據庫負載劇增,甚至導致數據庫崩潰的情況。

通常情況下,緩存中的數據會設置不同的過期時間,以避免同時失效的情況。然而,如果某個不可控的事件導致了大量緩存同時失效,就會出現緩存雪崩。
需要從以下幾個方面去解決緩存雪崩問題:
1. 設置不同的過期時間
可以通過設置隨機過期時間或者固定過期時間引入隨機偏移量兩種方案,一定程度上緩解緩存雪崩問題。,集群部署也可以把熱點數據放到不同的服務。
2. 緩存預熱
在系統啟動或者某個特殊節點前,將熱門數據預先加載到緩存中,避免在高并發或者其他情況數據不在緩存還需額外請求數據庫加載的情況。
3. 設置部分key永不過期
對于一些熱點數據,可以設置永不過期,以保證這部分數據始終在緩存中可用。同時,需要保障緩存設置的內存淘汰策略是不淘汰或者從帶過期時間 Key 中去淘汰。
- 電商系統:比如需要參加秒殺的商品數據,我們為了避免因設計過期時間自動過期或者不合適的 Redis 過期策略自動清楚,需要將參與秒殺的商品數據直接設置為永不過期。
緩存穿透
回答話術
緩存擊穿指在高并發的系統中,一個熱點數據緩存過期或者在緩存中不存在,導致大量并發請求直接訪問數據庫,從而給數據庫造成巨大壓力,甚至可能引起宕機。
具體來說,當某個熱點數據在緩存中過期時,如果此時有大量并發請求同時訪問這個數據,由于緩存中不存在,所有請求都會直接訪問數據庫,導致數據庫負載急劇增加。

一般來說,解決緩存擊穿的主要方法分為三種:熱點數據永不過期、熱點數據預加載以及加分布式鎖。
1. 熱點數據預熱
在活動開始之前,就將已知熱點數據加載到緩存中,避免出現第一次請求直接打到數據庫的情況。
2. 數據永不過期
熱點數據永不過期,指的就是可以預知的熱點數據,在活動開始前,設置過期時間為 -1。這樣的話,就不會有緩存擊穿的風險。
這個可以搭配熱點數據預加載一起完成。等對應熱點緩存的活動結束后,這些數據訪問量就比較低了,可以通過后臺任務的方案對指定緩存設置過期時間,這樣可以有效降低 Redis 存儲壓力。
3. 分布式鎖
分布式鎖的解決方案就是保證只有一個請求可以訪問數據庫,其它請求等待結果。這樣可以避免大量的請求同時訪問數據庫。
ps: 分布式鎖需要注意雙檢查,也就是獲取到鎖后需要再次嘗試從緩存中獲取數據,避免等待鎖的請求再次查詢db。
特殊情況也可以考慮
trylock直接報錯 而不是一直阻塞等待鎖。
緩存擊穿
回答話術
緩存穿透是指由于請求沒有辦法命中緩存,因此就會直接打到數據庫,當請求量較大時,大量的請求就可能會直接把數據庫打掛。
通常情況下,緩存是為了提高數據訪問速度,避免頻繁查詢數據庫。但如果攻擊者故意請求緩存中不存在的數據,就會導致緩存不命中,請求直接訪問數據庫。
簡單的情況 比如數據主鍵是自增的,如果某個請求是負數或者id為特別大的,緩存沒有 大量請求到db 有可能給db打掛。
緩存穿透通常有幾種解決辦法: 參數檢驗空值緩存、鎖、布隆過濾器;
1. 參數校驗,空值緩存
對一些非法的參數做一些校驗,比如-1直接 return了 不去查詢redis或者db,
當查詢結果為空時,也將結果進行緩存,但是設置一個較短的過期時間。這樣在接下來的一段時間內,如果再次請求相同的數據,就可以直接從緩存中獲取,而不是再次訪問數據庫,可以一定程度上解決緩存穿透問題。
不過這種方式也有小問題,這種方式同時也會在短時間內會造成緩存系統大量的內存占用,徹底解決這種海量惡意請求還是需要一套風控系統。
2. 加鎖
當請求發現緩存不存在時,可以使用鎖機制來避免多個相同的請求同時訪問數據庫,只讓一個請求去加載數據,其他請求等待。
這種方式可以解決數據庫壓力過大問題,如果會出現“誤殺”現象,那就是如果緩存中不存在但是數據庫存在這種情況,也會等待獲取鎖,用戶等待時間過長,不推薦使用。
3. 布隆過濾器
布隆過濾器是一種數據結構,可以用于判斷一個元素是否存在于一個集合中。它可以在很大程度上減輕緩存穿透問題,因為它可以快速判斷一個數據是否可能存在于緩存中。
這種方式較為推薦,可以將所有存量數據全部放入布隆過濾器,然后如果緩存中不存在數據,緊接著判斷布隆過濾器是否存在,如果存在訪問數據庫請求數據,如果不存在直接返回錯誤響應即可。
簡單來說他因為你對你不一定對 存在誤差率,但是他認為你錯就一定錯。
5. 組合使用 布隆過濾器+空對象+分布式鎖
上面的這些方案或多或少都會有些問題,應該用三者進行組合用來解決緩存穿透問題。
如果說緩存不存在,那么就通過布隆過濾器進行初步篩選,然后判斷是否存在緩存空值,如果存在直接返回失敗。如果不存在緩存空值,使用鎖機制避免多個相同請求同時訪問數據庫。最后,如果請求數據庫為空,那么將為空的 Key 進行空對象值緩存。
緩存預熱
聊完緩存常見的問題,現在聊聊預熱,上面三個常見問題雪崩和擊穿都可以通過預熱解決,讓我們分析一下。
回答話術
緩存預熱是在系統啟動或者運行過程中,提前將部分數據加載到緩存中,以確保在實際請求到來時,緩存已經包含了部分常用數據,從而提升系統的響應速度。

可以使用項目啟動預熱 或者xxjob定時或者把需要預熱的消息放到消息隊列然后通過消費者線程從消息隊列中獲取數據,并執行相應的數據讀取流程最終存儲到 Redis 中。

浙公網安備 33010602011771號