日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

小白也能看懂的缓存雪崩、穿透、击穿

發布時間:2025/3/15 编程问答 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 小白也能看懂的缓存雪崩、穿透、击穿 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

作為后端開發,我想緩存是大家再熟悉不過的東西了。

我會介紹出現緩存雪崩、穿透和擊穿的業務背景、解決方案和對業務可靠性處理。事先說明,最佳解決方案一定需要結合實際業務調整,不同業務的處理不完全相同

其實我在網上也看過不少關于緩存雪崩、穿透、擊穿介紹,不知道是不是大家所做業務的不同,發現有不少小伙伴有以下疑問,比如:

  • 加隨機時間過期后,如果訪問時間剛好就是加了隨機時間后的數據,這樣豈不是白加了隨機時間?

  • 熱點數據不過期,那豈不是有越來越多的臟數據?

就以上問題,我都會在文中一一解釋,以下說的緩存都指 Redis。

我爭取把這一高頻面試題講明白,如果大家看后能在這塊內容和面試官面前談笑風生,那你就是最靚的仔。

下面,我就開始進入正題啦。

1. 緩存雪崩

即緩存同一時間大面積的失效,這個時候來了一大波請求,都懟到數據庫上,最后數據庫處理不過來崩了。

1.1 業務場景舉例

APP 首頁有大量熱點數據,在某大型活動期間,針對不同時間段需要展示不同的首頁數據。

比如在 0 點時需要替換新的首頁數據,此時舊首頁數據過期,新首頁數據剛開始加載。

而 0 點正在有個小活動開始,大批請求涌入。因為新數據剛開始加載,請求多數沒有命中緩存,請求到了數據庫,最后就把數據庫打掛了。

1.2 解決方案

再強調一下,所謂的解決方案是需要根據實際業務調整,不同業務的處理不完全相同

1.2.1 方法一

常見方式就是給過期時間加個隨機時間。

注意這個隨機時間不是幾秒哈,可以長達幾分鐘。因為如果數據量很大,按照上述例子,加上 Redis 是單線程處理數據的。那么幾秒的緩沖不一定能夠保證新數據都被加載完成。

所以過期時間寧愿設置長一點,也好過短一點。反正最后都是會過期掉,最終效果是一樣的。

而且過期時間范圍加大,key 會更加分散,這樣也是一定程度縮短 Redis 在過期 key 時候的阻塞時間。

而至于文章開頭說的:「如果訪問時間剛好就是加了隨機時間后的數據,這樣豈不是白加了隨機時間」。

現在你結合上例活動的例子,它還會是一個問題嗎?結合業務,一定要結合業務。

1.2.2 方法二

加互斥鎖,但這個方案會導致吞吐量明顯下降。所以還是要看實際業務,像上述例子就不合適用

1.2.3 方法三

熱點數據不設置過期。不過期的話,正常業務請求自然就不會打到數據庫了。

那新的問題又來了,不過期有臟數據,怎么辦?

很簡單,活動整體結束后再刪除嘛。

那像上述例子,可以怎么處理呢?

可以選擇方法一;或者提前把 0 點需要的新數據加載進 Redis,不必等到 0 點才去加載,這樣也是可以的

2. 緩存擊穿

緩存擊穿是指一個熱點 key 過期或被刪除后,導致線上原本能命中該熱點 key 的請求,瞬間大量地打到數據庫上,最終導致數據庫被擊垮。

有種千里之堤,潰于蟻穴的感覺。

2.1 業務場景舉例

出現情況一般是誤操作,比如設置錯了過期時間、誤刪除導致的。

誰還沒誤操作過呢,刪庫跑路了解一下。反正我誤刪過測試庫的數據,幸好人沒事,狗頭保命。


2.2 解決方案

2.2.1?方法一

代碼問題,該 review 的 review。

熱點數據到底要不要過期,什么時候過期要明確

既然是熱點數據,大概率是核心流程。那么該保證的核心功能還是需要保證的,減少犯錯機會。萬一出問題,那就是用戶的一波輸出了。

2.2.2 方法二

線上誤操作的事情,該加強權限管理的加強,特別是線上權限,一定需要審核,以防手抖。

3. 緩存穿透

緩存穿透是指:客戶端請求緩存和數據庫中不存在的數據,導致所有的請求都打到數據庫上。如果請求很多,數據庫依舊會掛得明明白白。

3.1 業務場景舉例

  • 數據庫主鍵 id 都是正數,然后客戶端發起了?id = -1?的查詢

  • 一個查詢接口,有一個狀態字段 status,其實 0 表示開始、1 表示結束。結果有請求一直發 status=3 的請求過來

3.2 解決方案

3.2.1 方法一

做好參數校驗,對于不合理的參數要及時 return 結束。

這點非常重點,做任何業務都一樣,對于后端來說,要有互不信任原則。

簡單來說,就是不要信任來自前端、客戶端和上游服務的請求數據,該做的校驗還是要做。

因為我們永遠都不知道用戶會寫什么奇奇怪怪的數據;又或者即使你和對接的開發約定好了要怎么傳參數,但你保不準他就沒遵守呢;退一步來說,萬一接口被破解呢。

你要保護好自己,不然到時出問題時,你和老大說,因為誰誰不遵守約定傳參導致,或者因為沒想到用戶會這么填,你看看你老大會這么說(狗頭.jpg)

3.2.2 方法二

對于查不到數據的 key,也將其短暫緩存起來。

比如 30s。這樣能避免大量相同請求瞬間打到數據庫上,減輕壓力。

但是后面肯定要去看為什么會有這樣的數據,從根本上解決問題,該方法只是緩解問題而已。

如果發現就是某些 ip 在請求,并且這些數據非法,那可以在網關層限制這些 ip 訪問

3.2.3 方法三

提供一個能迅速判斷請求是否有效的攔截機制,比如布隆過濾器,Redis 本身就具有這個功能。

讓它維護所有合法的 key,如果請求參數不合法,則直接返回。否則就從緩存或數據庫中獲取。

關于布隆過濾器可以看我之前寫的文章:淺談布隆過濾器

4. 業務可靠性處理

如開頭所說,緩存指 Redis。

  • 提高 Redis 可用性:Redis 要么用集群架構,要么用主從 + 哨兵。保證 Redis 的可用性。

沒有哨兵的主從不能自動故障轉移,所以只有主從,萬一高峰期或者在關鍵的活動時間節點掛了。

那么等出現線上告警、定位問題、溝通信息、等運維解決,一套操作下來,估計黃花菜都涼了。

  • 減少對緩存的依賴

對于熱點數據,是不是可以考慮加上本地緩存,比如:Guava、Ehcache,更簡單點,hashMap、List 什么也可以。

減少對 Redis 壓力的同時,還能提高性能,一舉兩得。

  • 業務降級

從保護下游(接口或數據庫)的角度考慮,針對大流量場景是不是可以做下限流。這樣即使緩存崩了,也不至于把下游全部拖垮。

以及該降級的功能是不是可以降級,提前寫好降級開關和降級邏輯,關鍵時候全靠它穩住。

有道無術,術可成;有術無道,止于術

歡迎大家關注Java之道公眾號

好文章,我在看??

總結

以上是生活随笔為你收集整理的小白也能看懂的缓存雪崩、穿透、击穿的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。