快取擊穿,快取失效造成問題的解決方案

2021-07-17 03:18:09 字數 2623 閱讀 8329

我們在用快取的時候,不管是redis或者memcached,基本上會通用遇到以下三個問題:

一、快取穿透

注:

上面三個圖會有什麼問題呢?

我們在專案中使用快取通常都是先檢查快取中是否存在,如果存在直接返回快取內容,如果不存在就直接查詢資料庫然後再快取查詢結果返回。這個時候如果我們查詢的某乙個資料在快取中一直不存在,就會造成每一次請求都查詢db,這樣快取就失去了意義,在流量大時,可能db就掛掉了。

那這種問題有什麼好辦法解決呢?

要是有人利用不存在的key頻繁攻擊我們的應用,這就是漏洞。

有乙個比較巧妙的作法是,可以將這個不存在的key預先設定乙個值。

比如,"key" , 「&&」。

在返回這個&&值的時候,我們的應用就可以認為這是不存在的key,那我們的應用就可以決定是否繼續等待繼續訪問,還是放棄掉這次操作。如果繼續等待訪問,過乙個時間輪詢點後,再次請求這個key,如果取到的值不再是&&,則可以認為這時候key有值了,從而避免了透傳到資料庫,從而把大量的類似請求擋在了快取之中。

二、快取併發

有時候如果**併發訪問高,乙個快取如果失效,可能出現多個程序同時查詢db,同時設定快取的情況,如果併發確實很大,這也可能造成db壓力過大,還有快取頻繁更新的問題。

我現在的想法是對快取查詢加鎖,如果key不存在,就加鎖,然後查db入快取,然後解鎖;其他程序如果發現有鎖就等待,然後等解鎖後返回資料或者進入db查詢。

這種情況和剛才說的預先設定值問題有些類似,只不過利用鎖的方式,會造成部分請求等待。

三、快取失效

引起這個問題的主要原因還是高併發的時候,平時我們設定乙個快取的過期時間時,可能有一些會設定1分鐘啊,5分鐘這些,併發很高時可能會出在某乙個時間同時生成了很多的快取,並且過期時間都一樣,這個時候就可能引發一當過期時間到後,這些快取同時失效,請求全部**到db,db可能會壓力過重。

那如何解決這些問題呢?

其中的乙個簡單方案就時講快取失效時間分散開,比如我們可以在原有的失效時間基礎上增加乙個隨機值,比如1-5分鐘隨機,這樣每乙個快取的過期時間的重複率就會降低,就很難引發集體失效的事件。

我們討論的第二個問題時針對同乙個快取,第三個問題時針對很多快取。

總結來看:

2、快取失效:如果快取集中在一段時間內失效,db的壓力凸顯。這個沒有完美解決辦法,但可以分析使用者行為,盡量讓失效時間點均勻分布。

當發生大量的快取穿透,例如對某個失效的快取的大併發訪問就造成了快取雪崩。

四、大家提問彙總

1、問題1:如何解決db和快取一致性問題?

答:當修改了資料庫後,有沒有及時修改快取。這種問題,以前有過實踐,修改資料庫成功,而修改快取失敗的情況,最主要就是快取伺服器掛了。而因為網路問題引起的沒有及時更新,可以通過重試機制來解決。而快取伺服器掛了,請求首先自然也就無法到達,從而直接訪問到資料庫。那麼我們在修改資料庫後,無法修改快取,這時候可以將這條資料放到資料庫中,同時啟動乙個非同步任務定時去檢測快取伺服器是否連線成功,一旦連線成功則從資料庫中按順序取出修改資料,依次進行快取最新值的修改。

2、問題2:

問下快取穿透那塊!例如,乙個使用者查詢文章,通過id查詢,按照之前說的,是將快取的key預先設定乙個值,,如果通過id插過來,發現是預先設定的乙個值,比如說是「&&」,那之後的繼續等待訪問是什麼意思,這個id什麼時候會真正被附上使用者所需要的值呢?

答:我剛說的主要是咱們常用的後面配置,前台獲取的場景。前台無法獲取相應的key,則等待,或者放棄。當在後台配置介面上配置了相關key和value之後,那麼以前的key &&也自然會被替換掉。你說的那種情況,自然也應該會有乙個程序會在某乙個時刻,在快取中設定這個id,再有新的請求到達的時候,就會獲取到最新的id和value。

3、問題3:4、問題4:

多級快取是什麼概念呢?

答:多級快取就像我今天之前給大家發的文章裡面提到了,將ehcache與redis做二級快取,就像我之前寫的文章 提到過的。但同樣會存在一致性問題,如果我們需要強一致性的話,快取與資料庫同步是會存在時間差的,所以我們在具體開發的過程中,一定要根據場景來具體分析,二級快取更多的解決是,快取穿透與程式的健壯性,當集中式快取出現問題的時候,我們的應用能夠繼續執行。

快取擊穿 快取併發和快取失效

1 快取穿透 專案中使用快取通常都是先檢查快取中是否存在,如果存在直接返回快取內容,如果不存在就直接查詢資料庫然後再快取查詢結果返回。遇到問題 如果我們查詢的某乙個資料在快取中一直不存在,就會造成每一次請求都查詢db,這樣快取就失去了意義,在流量大時,可能db就掛掉了。要是有人利用不存在的key頻繁...

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

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

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

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