1. 程式人生 > >Redis 熱Key、 穿透、雪崩

Redis 熱Key、 穿透、雪崩

高併發的情況會給系統帶來很高的訪問流量,這就給儲存這些熱點資訊的Redis資料造成了一些壓力。

熱key問題及解決方案
產生原因
使用者消費的資料遠大於生產的資料 (熱賣商品、熱點新聞、熱點評論、明星直播)等。

在日常工作生活中一些突發的的事件,例如某明星突然宣佈戀情,導致某新聞點選量瞬間變大,請求遠超過對資料的寫入。就會造成熱資料問題。

我們 一般採用快取 + 過期時間的策略來幫助我們加速介面的訪問速度,減少了後端負載,同時保證功能的更新,一般情況下這種模式已經基本滿足要求了。

但是有兩個問題如果同時出現,可能就會對系統造成致命的危害:

訪問的資料是一個熱點key
構建快取需要時間
以上兩個問題如果同時出現,就可能會造成快取失效問題,有大量執行緒來構建快取,造成後端負載過大,嚴重還會導致系統崩潰。

在這裡插入圖片描述

上圖簡單描述了訪問熱點key及構建快取的一個過程。

解決方案
解決熱點key問題,可以有以下幾種方案,

1、互斥鎖

在上圖查詢資料庫的過程,只讓一個執行緒獨佔,這個執行緒構建快取的過程,其他執行緒都要等待,直到第一個執行緒構建完成可以從中讀取資料。

2、提前使用互斥鎖

提前使用互斥鎖,和互斥鎖差不多,都是讓一個執行緒獨佔構建快取,不一樣的是,在構建快取的時候。

在value內部設定一個超時值timeout1,這個過期時間比實際的快取過期時間短。

當從快取中讀到timeout1已經過期的時候,就認為資料也快過期了,直接執行查詢資料庫,進行構建快取的過程。

這樣在所有快過期的資料前,就重新構建了快取。

3、永遠不過期

永遠不過期有兩點

a、從redis上看,確實沒有設定過期時間,這就保證了,不會出現熱點key過期問題,也就是“物理”不過期。

b、從功能上看,如果不過期,那不就成靜態的了嗎?所以我們把過期時間存在key對應的value裡,如果發現要過期了,通過一個後臺的非同步執行緒進行快取的構建,也就是“邏輯”過期

可能會出現的問題,就是會出現老資料,怎麼說?

有1、2、3、4個執行緒,在第2個執行緒時,發現value中資料已經過期,通過非同步更新重新構建快取,前面有說過,執行緒構建快取會需要一定時間,如果在第4個執行緒執行時才完成構建,那麼第2、3個執行緒輸出的就是老資料。不過對於一般的業務需求是可以接受的。

穿透和雪崩
快取穿透
什麼是快取穿透?

在客戶端和資料庫中間增加一個快取層,如果這個快取層中儲存的都是資料庫命中資料,如果服務層並沒有返回資料儲存到快取中,而客戶端一直在訪問這個資料,則每次都要直接訪問資料庫,在流量小時沒有問題,如果流量非常大或有惡意攻擊,就會利用這個漏洞,使服務端的壓力增大,嚴重會導致系統崩潰。

解決方案

1、把查詢結果為空的結果也放到快取中,設定很短的快取過期時間,不超過5分鐘;

2、增加一個bloomfilter,任務某個key不存在,則不訪問資料庫;

快取雪崩
什麼是快取雪崩?

雪崩是設定快取失效的時間相同,造成大量的資料在短時間內同時失效,這樣訪問資料庫的壓力也會陡增。壓力這麼大,就像是發生了雪崩一樣。

解決方案

1、採用加鎖或訊息佇列,採用單執行緒的方式,防止失效時大量執行緒請求資料庫。

2、在同樣的快取失效時間上,增加一個隨機值,這樣每個快取的過期時間的重複率就會降低很多。

3、保證快取的高可用。例如Redis Sentinel 和 Redis Cluster

淘汰機制
儲存在記憶體中的快取資料如果過期或失效,為了更合理利用記憶體空間,提高記憶體使用效率。

什麼是淘汰機制

在記憶體中儲存的Key被清除掉,

(1)定時去清理過期的快取;

(2)當有使用者請求過來時,再判斷這個請求所用到的快取是否過期,過期的話就去底層系統得到新資料並更新快取。

可以通過redis.conf設定# maxmemory 這個值來開啟記憶體淘汰功能

redis資料淘汰策略
volatile-lru 從已設定過期時間的資料集中挑選最近最少使用的資料淘汰
volatile-ttl 從已設定過期時間的資料集中挑選將要過期的資料淘汰
volatile-random 從已設定過期時間的資料集中任意選擇資料淘汰
allkeys-lru 從所有資料集中挑選最近最少使用的資料淘汰
allkeys-random 從所有資料集中任意選擇資料進行淘汰
noeviction 禁止驅逐資料

原文:https://blog.csdn.net/mayfla/article/details/80112241