緩存擊穿、緩存穿透、緩存雪崩是什么?區別是什么?如何避免?


Redis數據類型

Redis支持五種數據類型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)

緩存穿透,擊穿,雪崩是什么?如何避免?

緩存處理流程

前台請求,后台先從緩存中取數據,取到直接返回結果,取不到時從數據庫中取,數據庫取到更新緩存,並返回結果,數據庫也沒取到,那直接返回空結果。

 

 

 

一、緩存穿透(數據庫中不存在的數據)

1.什么是緩存穿透?

緩存穿透指的是:同一時刻,大量的並發請求數據庫中不存在的信息,他既不會命中緩存,也不會命中數據庫,但是他會查找數據庫。由於大量的並發請求到達數據庫,而數據庫承受不住這么高的並發,從而導致數據庫奔潰,這就是緩存穿透。 

 

緩存穿透是指緩存和數據庫中都沒有的數據,而用戶不斷發起請求,如發起為id為“-1”的數據或id為特別大不存在的數據。這時的用戶很可能是攻擊者,攻擊會導致數據庫壓力過大。

2.如何避免?

1.將空數據存入緩存

對查詢結果為空的情況也進行緩存,緩存時間設置短一點,或者該 key 對應的數據 insert 了之后清理緩存。

2.布隆過濾器

采用布隆過濾器,將所有可能存在的數據存到一個bitMap中,不存在的數據就會進行攔截。

二、緩存擊穿(緩存失效的問題)

      1.什么是緩存擊穿?

緩存擊穿是指熱點key在某個時間點過期的時候,而恰好在這個時間點對這個Key有大量的並發請求過來,從而大量的請求打到db(數據庫)

緩存擊穿是指緩存中沒有但數據庫中有的數據(一般是緩存時間到期),這時由於並發用戶特別多,同時讀緩存沒讀到數據,又同時去數據庫去取數據,引起數據庫壓力瞬間增大,造成過大壓力

熱點key:某個key訪問非常頻繁,當key失效的時候有大量線程來構建緩存,導致負載增加,系統奔潰。

 

2.如何避免?

異步更新緩存

1.自動更新

redis是支持查詢某個key剩余有效時間,所以這里我們只需要設定一個時間差,比如3分鍾,請求的時候查詢的有效時間如果小於3分鍾,那么刷新這個key的有效時間,刷新這個操作可以使用異步實現(提高性能)。

 

可能你想到了,這種方式存在缺陷,沒錯,如果再快失效的3分鍾內沒有請求,那么緩存中的key將不會被刷新,還是會存在緩存擊穿的問題,所以這種方式不是特別推薦。

2.定時刷新

      定時刷新有兩種方案

      第一種:定時任務

      查詢快要過期的key,更新內容,並刷新有效時間,這種比較消耗服務器性能,也不是特別推薦。

      第二種:延遲隊列

      如果大家了解它的話可能一下就知道我說的是什么意思了,將數據存入緩存的那一刻同時發送一個延遲隊列(安指定時間消費),時間小於緩存中key的過期時間,到了指定時間,消費者刷新key的有效時間再發送一個延遲隊列,以此循環,這種方式還是不錯的,但是實現方式相對於第一種來說就要復雜一點了,他需要依靠消息中間件來完成,如果消息中間件某個時間宕機,那就gg了,雖然這種方式雖然比較推薦,但是成本偏高,因為為了防止消息中間件宕機,我們有可能需要對消息中間件做集群處理。

3.程序加鎖

1.使用鎖,單機用synchronized,lock等,分布式用分布式鎖

我個人推薦使用這個,為什么呢?因為它不需要額外的服務器開銷,也不需要額外的資源消耗,他僅僅只是讓線程串行而已,但是這個時候你可能就會有疑問了,加鎖不是會嚴重影響程序的效率嗎?為什么你還推薦這種方式呢?

其實並不是所有的鎖都會很大的降低程序的性能,這里我們當然不能使用synchronized,原因很簡單,他的效率比較慢,不太適合這種情況,我要介紹的這種鎖名字為:讀寫鎖。

三、緩存雪崩

1.什么是緩存雪崩?

緩存雪崩是指緩存中數據大批量到過期時間,而查詢數據量巨大,引起數據庫壓力過大甚至down機。

雪崩:緩存大量失效的時候,引發大量查詢數據庫。

雪崩:當緩存服務器重啟或者大量緩存集中在某一個時間段失效,這樣在失效的時候,會給后端系統帶來很大壓力。導致系統崩潰。

2.如何避免

1.用鎖/分布式鎖或者隊列串行訪問

在緩存失效后,通過加鎖或者隊列來控制讀數據庫寫緩存的線程數量。比如對某個 key 只允許一個線程查詢數據和寫緩存,其他線程等待。

2.緩存失效時間均勻分布

緩存數據的過期時間設置隨機,防止同一時間大量數據過期現象發生。

不同的 key,設置不同的過期時間,讓緩存失效的時間點盡量均勻。在原來過期時間的基礎上生成一個隨機時間,這個隨機時間比較小,然后兩者相加即可。

如果緩存數據庫是分布式部署,將熱點數據均勻分布在不同搞得緩存數據庫中

3.設置熱點數據永遠不過期。

將一些常用的數據設置成為永久有效,注意哦,是經常使用的而不是全部,這點需要特別注意。

總結

什么是緩存穿透?

同一時刻,大量的並發請求數據庫中不存在的信息,他既不會命中緩存,也不會命中數據庫,但是他會查找數據庫。

什么是緩存擊穿?

緩存擊穿是指熱點key在某個時間點過期的時候,而恰好在這個時間點對這個Key有大量的並發請求過來,從而大量的請求打到db(數據庫)。

什么是緩存雪崩?

緩存中數據大批量到過期時間,而查詢數據量巨大,引起數據庫壓力過大甚至宕機

緩存擊穿和緩存穿透區別

緩存擊穿和緩存穿透有點像但是性質又不相同,都是緩存中沒有數據,請求命中數據庫,緩存穿透指的是數據庫中不存在的數據,緩存擊穿則是指緩存失效的問題。

緩存雪崩和緩存擊穿區別

和緩存擊穿不同的是, 緩存擊穿指並發查同一條數據,緩存雪崩是不同數據都過期了,很多數據都查不到從而查數據庫。

學習連接

https://www.cnblogs.com/wen-xin/p/11839065.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM