redis缓存穿透、缓存雪崩、缓存击穿、并发竞争
關注微信公眾號“蝦米聊吧”,每天更新一篇技術文章,文章內容涵蓋架構師成長必經之路應掌握的技術,一起學習,一起交流。
?
緩存穿透、緩存雪崩、緩存擊穿、并發競爭是緩存最常見的幾個問題,接下來我們簡單談談關于這他們的出現場景以及可能的解決方案都有哪些?
?
**緩存穿透**
概念:是指查詢一個不存在的數據,由于緩存無法命中,該請求將去查詢數據庫,但是數據庫也無此記錄,并且出于容錯考慮,我們沒有將這次查詢的null寫入緩存,這將導致這個不存在的數據每次請求都要到數據存儲層(比如mysql)去查詢,導致緩存失去了意義。如果在流量大的時候可能還會導致我們的數據庫服務直接掛掉,而且要是有人利用不存在的key頻繁攻擊我們的應用,那這就成了我們系統的一個漏洞。
解決:其實我們可以對空結果集也進行緩存,比如將該空結果集緩存為unknow,這樣緩存就會命中,減少db的訪問壓力,但需要把它的過期時間設置很短,最長不超過五分鐘。
?
**緩存雪崩**
概念:是指緩存中大批量數據到期,在某一時刻同時失效(可能是由于我們設置緩存時采用了相同的過期時間),而查詢量巨大,此時請求將全部轉發到DB,導致DB因無法承受如此大的瞬時壓力而雪崩。
解決:原有的失效時間基礎上增加一個隨機值,比如1-5分鐘隨機,這樣每一個緩存的過期時間的重復率就會降低,就很難引發集體失效的事件。
?
**緩存擊穿**
概念:是指對于一些設置了過期時間的key,如果這些key可能會在某些時間點被超高并發地訪問,是一種非?!盁狳c”的數據。這個時候,需要考慮一個問題:如果這個key在大量請求同時進來之前正好失效,那么所有對這個key的數據查詢都落到db,我們稱為緩存擊穿。
解決:加鎖(分布式鎖);對該熱點key進行加鎖,只允許加鎖成功的當前請求直接訪問db,等待當前請求訪問完成并且寫入redis后釋放鎖,那么后續的等待的大量請求就會直接走緩存了,這樣將大大降低db的訪問壓力。
?
緩存擊穿與緩存雪崩的區別:
1. 擊穿是一個熱點key失效
2. 雪崩是很多key集體失效
?
**redis并發競爭問題**
所謂redis的并發競爭問題是指多個客戶端同時并發寫同一個key,可能本來應該先寫的數據后寫了,產生了順序不一致從而導致數據版本錯亂了。或者是多個客戶端同時獲取同一個key,修改值后再寫回去,如果這個寫的順序錯了,那么最終獲取的數據就錯了。
比如多個客戶端同時寫一個key,初始值為A,本來需要按順序依次修改為B、C、D,最后的結果為D,但是可能在并發寫的時候順序變了比如變成了C、D、B,那么最終的結果就成了B,然鵝,這并不是我們想要的結果。
?
那么我們怎么來解決這個問題呢?常用的有如下兩種方案:1.分布式鎖+版本號(時間戳)? ?2.消息隊列MQ
?
1.分布式鎖+版本號(時間戳)
分布式鎖這里就不多做介紹了,即誰搶到了鎖誰就可以操作該key,其目的就是保證同一時刻只有一個線程來操作key。
時間戳的目的就是為了做一個標識,即每個數據都攜帶一個時間戳,
比如:A:12:00 、 B:12:01、C:12:02、D:12:03,假如B先搶到鎖,設置了key的值,并且數據時間為12.01,后面A搶到鎖,和現有key中的值一對比發現自己數據的時間早于緩存中數據時間戳(12:00<12:01),那么此時A就不做任何操作了。
?
2.消息隊列MQ的方式:
在并發量過大的情況下,可以通過消息中間件進行處理,把并行讀寫進行串行化。
即把所有操作都放在隊列中使其串行化一個一個執行這樣就可以保證執行的順序性了。
這種方式在一些高并發的場景中是一種通用的解決方案。
?
關注微信公眾號“蝦米聊吧”,獲取更多知識資料干貨~,一起交流,一起學習~,
一起打卡學習,一起交流進步吧!
微信掃描二維碼,關注我的公眾號
總結
以上是生活随笔為你收集整理的redis缓存穿透、缓存雪崩、缓存击穿、并发竞争的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: redis过期策略和淘汰机制你知道多少?
- 下一篇: 手心输入法设置怎么双拼