4種常見的快取問題及解決方案詳解

2021-09-28 21:25:08 字數 1467 閱讀 9000

使用快取可以緩解大流量壓力,顯著提高程式的效能。我們在使用快取系統時,尤其是大併發情況下,經常會遇到一些「疑難雜症」。本文總結了一些使用快取時常見的問題及解決方案,以後在遇到這類問題時可以作為參考,在設計快取系統的時候也應該考慮這些常見的情況。

為了表述方便,本文以資料庫查詢快取為例,使用快取可以減小對資料庫的壓力。

我們在使用快取時,往往先嘗試去快取中取值,如果沒有,再去資料庫取值,如果資料庫也沒有值,則根據業務需求,返回空或者拋異常。

如果使用者一直訪問乙個資料庫不存在的資料,比如id為-1的資料,就會導致每次請求都會先去快取查一次,然後再去資料庫查一次,造成嚴重的效能問題。這種情況就叫快取穿透。

以下幾種解決方案:

快取擊穿指的是,乙個key的訪問量非常大,比如某秒殺活動,有1w/s的併發量。這個key在某一時刻過期,那這些大量的請求就會一瞬間到資料庫,資料庫可能會直接崩潰。

快取擊穿的解決方案也有幾種,可以配合使用:

快取雪崩指的是,在某一時刻,多個key失效。這樣就會有大量的請求從快取中獲取不到值,全部到資料庫。還有另一種情況,就是快取伺服器宕機,也算做快取雪崩。

針對上述兩種情況,快取雪崩有兩種解決方案:

雙寫不一致

在使用資料庫快取的時候,讀和寫的流程往往是這樣的:

所謂雙寫不一致,就是在發生寫操作(更新)的時候或寫操作之後,可能會存在資料庫裡面的值和快取中的值不同的情況。

為什麼更新的時候要先刪除快取,再更新資料庫?因為如果先更新資料庫,然後在刪除快取的時候失敗了,就會造成快取裡面的值和資料庫的值不一致。

然而這樣並不能完全避免雙寫不一致問題。假設在大併發情景下,乙個執行緒先刪除快取,然後取更新資料庫,這個時候另乙個執行緒去取快取,發現沒有值,於是去讀資料庫,然後把資料庫舊的值設定進快取。等第乙個執行緒更新完資料庫後,資料庫裡面就是新的值,而快取裡面是舊的值,所以就存在了資料不一致的問題。

乙個比較簡單的解決辦法是把過期時間設定得比較低,這樣就只有在快取沒過期之前存在資料不一致問題,在一些業務場景下也還能接受。

另一種解決方案是使用佇列輔助。先更新資料庫,再刪除快取。如果刪除失敗,就放進佇列。然後另乙個任務從佇列中取出訊息,不斷去重試刪除相應的key。

還有一種解決方案是使用對乙個資料使用乙個佇列,使讀寫操作序列化。比如對id為n的資料建立乙個佇列。對這條資料的寫操作,刪除快取後,放進乙個佇列;然後另乙個執行緒過來了,發現沒有快取,則把這個讀操作也放進這個佇列裡面。

不過這樣會增加程式的複雜性,序列化也會降低程式的吞吐量,可能得不償失。一般主流的解決方案還是先刪除快取,再更新資料庫。可以滿足絕大部分需求。

常見快取問題及解決方案

概念 增加節點機器,效能沒有提公升反而下降了。以使用者為例 user 133 age,user 133 name,user 133 height n個ke,當伺服器增多的時候,133號使用者的資訊,也被更散落在更多的節點上,所以,同樣是訪問個人主頁,得到相同的個人資訊,節點越多,要連線的節點也越多,...

快取常見問題及解決方案

使用快取可以緩解大流量壓力,顯著提高程式的效能。我們在使用快取系統時,尤其是大併發情況下,經常會遇到一些 疑難雜症 本文總結了一些使用快取時常見的問題及解決方案,以後在遇到這類問題時可以作為參考,在設計快取系統的時候也應該考慮這些常見的情況。為了表述方便,本文以資料庫查詢快取為例,使用快取可以減小對...

快取中常見的問題及解決方案

快取技術是 服務端經常用到的一種技術,在讀多寫少的業務場景中,通過使用快取可以有效地提高 的效能,支撐高併發的訪問量,對資料庫做到很好的保護。我們在使用快取的時候,如redis memcached,基本上都遇到以下幾個問題 快取穿透 快取併發 快取失效 快取雪崩 熱點key db快取一致性。本案例結...