成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

一篇學會緩存穿透、緩存擊穿、緩存雪崩

存儲 存儲架構
當查詢數據庫和緩存都無數據時,因為數據庫查詢無數據,出于容錯考慮,不會將結果保存到緩存中,因此每次請求都會去查詢數據庫,這種情況就叫做緩存穿透。

大家好,我是樓仔!

今天寫的這個主題內容,其實非?;A,但是作為高并發非常重要的幾個場景,絕對繞不開,估計大家面試時,也經常會遇到。

這個主題的文章,網上非常多,本來想直接轉載一篇,但是感覺沒有合適的,要么文章不夠精煉,要么就是精簡過頭,所以還是自己寫一篇吧。

內容雖然基礎,但我還是秉承以往的寫作風格,參考眾多優秀的博客后,打算寫一篇能通俗易懂,又不失全面的文章。

前言

我們先看一下正常情況的查詢過程:

  • 先查詢 Redis,如果查詢成功,直接返回,查詢不存在,去查詢 DB;
  • 如果 DB 查詢成功,數據回寫 Redis,查詢不存在,直接返回。

緩存穿透

定義:當查詢數據庫和緩存都無數據時,因為數據庫查詢無數據,出于容錯考慮,不會將結果保存到緩存中,因此每次請求都會去查詢數據庫,這種情況就叫做緩存穿透。

紅色的線條,就是緩存穿透的場景,當查詢的 Key 在緩存和 DB 中都不存在時,就會出現這種情況。

可以想象一下,比如有個接口需要查詢商品信息,如果有惡意用戶模擬不存在的商品 ID 發起請求,瞬間并發量很高,估計你的 DB 會直接掛掉。

可能大家第一反應就是對入參進行正則校驗,過濾掉無效請求,對!這個沒錯,那有沒有其它更好的方案呢?

緩存空值

當我們從數據庫中查詢到空值時,我們可以向緩存中回種一個空值,為了避免緩存被長時間占用,需要給這個空值加一個比較短的過期時間,例如 3~5 分鐘。

不過這個方案有個問題,當大量無效請求穿透過來時,緩存內就會有有大量的空值緩存,如果緩存空間被占滿了,還會因剔除掉一些已經被緩存的用戶信息,反而會造成緩存命中率的下降,所以這個方案,需要評估緩存容量。

如果緩存空值不可取,這時你可以考慮使用布隆過濾器。

布隆過濾器

布隆過濾器是由一個可變長度為 N 的二進制數組與一組數量可變 M 的哈希函數構成,說的簡單粗暴一點,就是一個 Hash Map。

原理相當簡單:比如元素 key=#3,假如通過 Hash 算法得到一個為 9 的值,就存在這個 Hash Map 的第 9 位元素中,通過標記 1 標識該位已經有數據,如下圖所示,0 是無數據,1 是有數據。

所以通過該方法,會得到一個結論:在 Hash Map 中,標記的數據,不一定存在,但是沒有標記的數據,肯定不存在。

為什么“標記的數據,不一定存在”呢?因為 Hash 沖突!

比如 Hash Map 的長度為 100,但是你有 101 個請求,假如你運氣好到爆,這 100 個請求剛好均勻打在長度為 100 的 Hash Map 中,此時你的 Hash Map 已經全部標記為 1。

當第 101 個請求過來時,就 100% 出現 Hash 沖突,雖然我沒有請求過,但是得到的標記卻為 1,導致布隆過濾器沒有攔截。

如果需要減少誤判,可以增加 Hash Map 的長度,并選擇卻分度更高的 Hash 函數,比如多次對 key 進行 hash。

除了 Hash 沖突,布隆過濾器其實會帶來一個致命的問題:布隆過濾器更新失敗。

比如有一個商品 ID 第一次請求,當 DB 中存在時,需要在 Hash Map 中標記一下,但是由于網絡原因,導致標記失敗,那么下次這個商品 ID 重新發起請求時,請求會被布隆過濾器攔截,比如這個是雙11的爆款商品庫存,明明有 10W 件商品,你卻提示庫存不存在,領導可能會說“明天你可以不用來了”。

所以如果使用布隆過濾器,在對 Hash Map 進行數據更新時,需要保證這個數據能 100% 更新成功,可以通過異步、重試的方式,所以這個方案有一定的實現成本和風險。

緩存擊穿

定義:某個熱點緩存在某一時刻恰好失效,然后此時剛好有大量的并發請求,此時這些請求將會給數據庫造成巨大的壓力,這種情況就叫做緩存擊穿。

這個其實和“緩存穿透”流程圖一樣,只是這個的出發點是“某個熱點緩存在某一時刻恰好失效”,比如某個非常熱門的爆款商品,緩存突然失效,流量直接全部打到 DB,造成某一時刻數據庫請求量過大,更強調瞬時性。

解決問題的方法主要有 2 種:

  • 分布式鎖:只有拿到鎖的第一個線程去請求數據庫,然后插入緩存,當然每次拿到鎖的時候都要去查詢一下緩存有沒有,這種在高并發場景下,個人不太建議用分布式鎖,會影響查詢效率;
  • 設置永不過期:對于某些熱點緩存,我們可以設置永不過期,這樣就能保證緩存的穩定性,但需要注意在數據更改之后,要及時更新此熱點緩存,不然就會造成查詢結果的誤差,比如熱門商品,都先預熱到數據庫,后續再下線掉。

網上還有“緩存續期”的方式,比如緩存 30 分鐘失效,可以搞個定時任務,每 20 分鐘跑一次,感覺這種方式不倫不類,僅供大家參考。

緩存雪崩

定義:在短時間內有大量緩存同時過期,導致大量的請求直接查詢數據庫,從而對數據庫造成了巨大的壓力,嚴重情況下可能會導致數據庫宕機的情況叫做緩存雪崩。

如果說“緩存擊穿”是單兵反抗,那“緩存雪崩”就是集體起義了,那什么情況會出現緩存雪崩呢?

  • 短時間內有大量緩存同時過期;
  • 緩存服務宕機,導致某一時刻發生大規模的緩存失效。

那么有哪些解決方案呢?

  • 緩存添加隨機時間:可在設置緩存時添加隨機時間,比如 0~60s,這樣就可以極大的避免大量的緩存同時失效;
  • 分布式鎖:加一個分布式鎖,第一個請求將數據持久化到緩存后,其它的請求才能進入;
  • 限流和降級:通過限流和降級策略,減少請求的流量;
  • 集群部署:Redis 通過集群部署、主從策略,主節點宕機后,會切換到從節點,保證服務的可用性。

緩存添加隨機時間示例:

// 緩存原本的失效時間
int exTime = 10 * 60;
// 隨機數生成類
Random random = new Random();
// 緩存設置
jedis.setex(cacheKey, exTime + random.nextInt(1000) , value);
責任編輯:武曉燕 來源: 樓仔
相關推薦

2019-10-12 14:19:05

Redis數據庫緩存

2023-03-10 13:33:00

緩存穿透緩存擊穿緩存雪崩

2019-11-05 14:24:31

緩存雪崩框架

2021-06-05 09:01:01

Redis緩存雪崩緩存穿透

2020-03-16 14:57:24

Redis面試雪崩

2022-03-08 00:07:51

緩存雪崩數據庫

2023-04-14 07:34:19

2022-11-18 14:34:28

2025-06-30 01:55:00

2023-11-10 14:58:03

2024-03-12 10:44:42

2023-12-06 13:38:00

Redis緩存穿透緩存擊穿

2020-10-13 07:44:40

緩存雪崩 穿透

2021-12-25 22:28:27

緩存穿透緩存擊穿緩存雪崩

2020-10-23 10:46:03

緩存雪崩擊穿

2020-12-28 12:37:36

緩存擊穿穿透

2020-03-05 09:09:18

緩存原因方案

2022-07-11 07:36:36

緩存緩存雪崩緩存擊穿

2024-04-07 00:00:02

Redis雪崩緩存

2024-04-18 11:43:28

緩存數據庫Redis
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 黄免费观看 | 91精品国产综合久久久久久 | 国产中的精品av涩差av | 免费在线黄色av | 国产精品一卡 | 成年人在线观看视频 | 欧美性受xxxx白人性爽 | 精品国产免费一区二区三区五区 | 亚州影院 | 国产探花| 毛色毛片免费看 | 日韩网站免费观看 | 中文字幕 在线观看 | 国产精品99久久久久久久vr | 日韩欧美三级 | 亚洲免费视频一区 | 欧美性生活网 | 精品av | 九九久久久 | 国产男女精品 | 亚洲日本欧美日韩高观看 | 亚洲日本一区二区 | 亚洲视频免费观看 | 在线精品亚洲欧美日韩国产 | 97人澡人人添人人爽欧美 | 国产成人精品午夜 | 嫩呦国产一区二区三区av | 日本成人片在线观看 | 免费一级欧美在线观看视频 | 久久久久国产一区二区三区 | 孕妇一级毛片 | 中文字幕在线观看视频网站 | 一区二区三区免费 | 青青草在线视频免费观看 | 亚洲视频在线观看 | 精品影院| 成人免费视频在线观看 | 天天干视频网 | 亚洲视屏| 国产一区二区三区四区五区3d | 欧美全黄|