redis快取擊穿,失效以及熱點key解決方案

2021-09-27 18:19:50 字數 1864 閱讀 8654

查詢乙個資料庫中不存在的資料,比如商品詳情,查詢乙個不存在的id,每次都會訪問db,如果有人惡意破壞,很可能直接對db造成過大地壓力。

解決方案:當通過某乙個key去查詢資料的時候,如果對應在資料庫中的資料都不存在,我們將此key對應的value設定為乙個預設的值,比如「null」,並設定乙個快取的失效時間,這時在快取失效之前,所有通過此key的訪問都被快取擋住了。後面如果此key對應的資料在db中存在時,更新快取中該key的資訊,通過此key再去訪問資料,就能拿到新的value了。

在高併發的環境下,如果此時key對應的快取失效,此時有多個程序就會去同時去查詢db,然後再去同時設定快取。這個時候如果這個key是系統中的熱點key或者同時失效的數量比較多時,db訪問量會瞬間增大,造成過大的壓力。

解決方案:

①:將系統中key的快取失效時間均勻地錯開,防止統一時間點有大量的key對應的快取失效;

②:當我們通過key去查詢資料時,首先查詢快取,如果此時快取中查詢不到,就通過分布式鎖進行加鎖,取得鎖的程序查db並設定快取,然後解鎖;其他程序如果發現有鎖就等待,然後等解鎖後返回快取資料或者再次查詢db。

使用互斥鎖(mutex key): 這種解決方案思路比較簡單,就是只讓乙個執行緒構建快取,其他執行緒等待構建快取的執行緒執行完,重新從快取獲取資料就可以了(如下圖)

如果是單機,可以用synchronized或者lock來處理,如果是分布式環境可以用分布式鎖就可以了(分布式鎖,可以用memcache的add, redis的setnx, zookeeper的新增節點操作)。

redis**:

string get(string key)  else   

} }

快取中的某些key(可能對應用與某個**商品)對應的value儲存在集群中一台機器,使得所有流量湧向同一機器,成為系統的瓶頸,該問題的挑戰在於它無法通過增加機器容量來解決。

解決方案:

①:客戶端熱點key快取:將熱點key對應value並快取在客戶端本地,並且設定乙個失效時間。對於每次讀請求,將首先檢查key是否存在於本地快取中,如果存在則直接返回,如果不存在再去訪問分布式快取的機器。

②:將熱點key分散為多個子key,然後儲存到快取集群的不同機器上,這些子key對應的value都和熱點key是一樣的。當通過熱點key去查詢資料時,通過某種hash演算法隨機選擇乙個子key,然後再去訪問快取機器,將熱點分散到了多個子key上。

永不過期:熱點key最好能永不過期。

這裡的「永遠不過期」包含兩層意思:

(1) 從redis上看,確實沒有設定過期時間,這就保證了,不會出現熱點key過期問題,也就是「物理」不過期。

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

為每個 value 設定乙個邏輯過期時間,當發現超過邏輯過期時間後,會使用單獨的執行緒去構建快取。

從實戰看,這種方法對於效能非常友好,唯一不足的就是構建快取時候,其餘執行緒(非構建快取的執行緒)可能訪問的是老資料,但是對於一般的網際網路功能來說這個還是可以忍受。

string get(final string key)   

} });

} return value;

}

快取擊穿 失效以及熱點key問題

快取擊穿 失效以及熱點key問題 快取擊穿 查詢乙個資料庫中不存在的資料,比如商品詳情,查詢乙個不存在的id,每次都會訪問db,如果有人惡意破壞,很可能直接對db造成過大地壓力。快取擊穿的解決方案 當通過某乙個key去查詢資料的時候,如果對應在資料庫中的資料都不存在,我們將此key對應的value設...

Redis快取擊穿,失效以及維度劃分

一 redis快取快取的使用場景基本包含如下兩種 1 開銷大的複雜計算 以mysql為例子,一些複雜的操作或者計算 例如大量聯表操作 一些分組計 算 如果不加快取,不但無法滿足高併發量,同時也會給mysql帶來巨大的負擔。2 加速請求響應 即使查詢單條後端資料足夠快 例如select from ta...

快取穿透 快取擊穿 快取雪崩 熱點資料失效

在我們專案中,多少是會使用快取知識的,因為對於很多資料沒必要每次都到資料庫中進行查詢,如果每次都到資料庫中進行查詢,當出現併發情況時,可能會導致資料庫的宕機。比如一些經常查詢但是又不經常修改的資料,我們可以直接將資料存入快取中,以減少資料庫的壓力。當然在實現快取的時候,我們也會遇見很多問題,於是彙總...