Redis缓存穿透 缓存击穿 缓存雪崩原因及其解决方案
解決緩存穿透
方法一:布隆過濾器:將所有可能存在的數據哈希到一個足夠大的bitmap中,一個一定不存在的數據會被 這個bitmap攔截掉,從而避免了對底層存儲系統的查詢壓力。
方法二:如果一個查詢返回的數據為空(不管數據不存在還是系統故障),我們仍然把這個空結果進行緩存,但它的過期時間會很短,最長不超過五分鐘。
解決緩存擊穿
key可能會在某些時間點被超高并發地訪問,是一種非常“熱點”的數據。這個時候,需要考慮一個問題:緩存被“擊穿”的問題。
使用互斥鎖(mutex key)
業界比較常用的做法,是使用mutex。簡單地來說,就是在緩存失效的時候(判斷拿出來的值為空),不是立即去load db,而是先使用緩存工具的某些帶成功操作返回值的操作(比如Redis的SETNX或者Memcache的ADD)去set一個mutex key,當操作返回成功時,再進行load db的操作并回設緩存;否則,就重試整個get緩存的方法。
SETNX,是「SET if Not eXists」的縮寫,也就是只有不存在的時候才設置,可以利用它來實現鎖的效果。
解決緩存雪崩
與緩存擊穿的區別在于這里針對很多key緩存,前者則是某一個key。
緩存正常從Redis中獲取,示意圖如下:
緩存失效瞬間示意圖如下:
緩存失效時的雪崩效應對底層系統的沖擊非常可怕!大多數系統設計者
考慮用加鎖或者
隊列的方式保證來保證不會有大量的線程對數據庫一次性進行讀寫,從而避免失效時大量的并發請求落到底層存儲系統上。
還有一個簡單方案就時講緩存失效時間分散開,比如我們可以在原有的失效時間基礎上增加一個隨機值,比如1-5分鐘隨機,這樣每一個緩存的過期時間的重復率就會降低,就很難引發集體失效的事件。
加鎖排隊只是為了減輕數據庫的壓力,并沒有提高系統吞吐量。
假設在高并發下,緩存重建期間key是鎖著的,這是過來1000個請求999個都在阻塞的。同樣會導致用戶等待超時,這是個治標不治本的方法!
加鎖排隊的解決方式分布式環境的并發問題,有可能還要解決分布式鎖的問題;線程還會被阻塞,用戶體驗很差!因此,在真正的高并發場景下很少使用!
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的Redis缓存穿透 缓存击穿 缓存雪崩原因及其解决方案的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MySQL主从同步延迟原因及解决方法
- 下一篇: 美国提出推进自由开放的印太秩序的真实目的