快取三大問題及解決方案

2022-09-15 23:30:20 字數 1523 閱讀 5031

隨著網際網路系統發展的逐步完善,提高系統的qps,目前的絕大部分系統都增加了快取機制從而避免請求過多的直接與資料庫操作從而造成系統瓶頸,極大的提公升了使用者體驗和系統穩定性。

雖然使用快取給系統帶來了一定的質的提公升,但同時也帶來了一些需要注意的問題。

快取穿透是指查詢乙個一定不存在的資料,因為快取中也無該資料的資訊,則會直接去資料庫層進行查詢,從系統層面來看像是穿透了快取層直接達到db,從而稱為快取穿透,沒有了快取層的保護,這種查詢一定不存在的資料對系統來說可能是一種危險,如果有人惡意用這種一定不存在的資料來頻繁請求系統,不,準確的說是攻擊系統,請求都會到達資料庫層導致db癱瘓從而引起系統故障。

快取穿透業內的解決方案已經比較成熟,主要常用的有以下幾種:

在普通的快取系統中一般例如redis、memcache等中,我們會給快取設定乙個失效時間,但是如果所有的快取的失效時間相同,那麼在同一時間失效時,所有系統的請求都會傳送到資料庫層,db可能無法承受如此大的壓力導致系統崩潰。

快取擊穿實際上是快取雪崩的乙個特例,大家使用過微博的應該都知道,微博有乙個熱門話題的功能,使用者對於熱門話題的搜尋量往往在一些時刻會大大的高於其他話題,這種我們成為系統的「熱點「,由於系統中對這些熱點的資料快取也存在失效時間,在熱點的快取到達失效時間時,此時可能依然會有大量的請求到達系統,沒有了快取層的保護,這些請求同樣的會到達db從而可能引起故障。擊穿與雪崩的區別即在於擊穿是對於特定的熱點資料來說,而雪崩是全部資料。

1.使用互斥鎖(mutex key)

業界比較常用的做法,是使用mutex。簡單地來說,就是在快取失效的時候(判斷拿出來的值為空),不是立即去load db,而是先使用快取工具的某些帶成功操作返回值的操作(比如redis的setnx或者memcache的add)去set乙個mutex key,當操作返回成功時,再進行load db的操作並回設快取;否則,就重試整個get快取的方法。

setnx,是「set if not exists」的縮寫,也就是只有不存在的時候才設定,可以利用它來實現鎖的效果。在redis2.6.1之前版本未實現setnx的過期時間,所以這裡給出兩種版本**參考:

前單機版本鎖

string get(string key) else

} }

最新版本**:

public string get(key) else

} else

}2:"永遠不過期":  

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

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

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

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

string get(final string key)

} });

} return value;

}

快取三大問題及解決方案

隨著網際網路系統發展的逐步完善,提高系統的qps,目前的絕大部分系統都增加了快取機制從而避免請求過多的直接與資料庫操作從而造成系統瓶頸,極大的提公升了使用者體驗和系統穩定性。雖然使用快取給系統帶來了一定的質的提公升,但同時也帶來了一些需要注意的問題。快取穿透是指查詢乙個一定不存在的資料,因為快取中也...

快取的三大問題以及解決方案

redis經常用於系統中的快取,這樣可以解決目前io裝置無法滿足網際網路應用海量的讀寫請求的問題。快取穿透是指快取和資料庫中都沒有的資料,而使用者不斷發起請求,如發起id為 1的資料或者特別大的不存在的資料。有可能是黑客利用漏洞攻擊從而去壓垮應用的資料庫。對於快取穿透問題,常見的解決方案有以下三種 ...

快取世界中的三大問題及解決方案

試想一下,如果有黑客會對你的系統進行攻擊,拿乙個不存在的id 去查詢資料,會產生大量的請求到資料庫去查詢。可能會導致你的資料庫由於壓力過大而宕掉。2.3.1 快取空值 之所以會發生穿透,就是因為快取中沒有儲存這些空資料的key。從而導致每次查詢都到資料庫去了。那麼我們就可以為這些key對應的值設定為...