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

2021-08-10 15:14:07 字數 2404 閱讀 2635

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

本案例結合平台開發過程中遇到的問題,簡要總結了快取中常見的問題並提供一些解決方案。

在專案開發中,我們常會遇到以下三種情形:

圖一、查詢快取

圖二、刪除快取

圖三、更新快取

在專案中使用快取通常都是先檢查快取中是否存在,如果存在直接返回快取內容,如果不存在就查詢資料庫,然後再快取查詢結果返回。這個時候如果我們查詢的某乙個資料在快取中一直不存在,就會造成每一次請求都查詢db,這樣快取就失去了意義,在流量很大時就會對db造成一定的壓力。這就是快取穿透。如果有人利用不存在的key頻繁攻擊我們的應用,很可能直接對db造成影響,這是在**設計時需要考慮的問題。

有乙個比較巧妙的做法是,將這個不存在的key預先設定乙個值及過期時間,比如」key」-「null」等。當返回null值的時候,我們就認為這是乙個不存在的key,然後決定是否繼續等待訪問取值,或者放棄操作。如果繼續等待訪問,過乙個時間輪詢點後再次請求這個key,如果取到的值不是」null」,則認為這時key有值了,從而避免了透傳到資料庫,把大量的類似請求擋在了快取之中。

在我們搭建的平台中,有些地方需要特別注意防範快取穿透問題,比如使用者登入操作、找回密碼操作等。我們可以分兩步處理,在使用者發起請求的時候,首先對請求內容的格式做校驗,將非法內容的請求直接阻擋在前端或者服務層面;其次,在快取中對頻繁查詢的字段做校驗。比如最常用到的手機號,首先過濾非法手機號,然後再查詢資料庫,如果手機號不存在,則將該手機號放入快取中,下次請求可直接從快取中讀取結果,減少資料庫的壓力。如果後續將手機號新增到了平台,同步更新對應的key即可。

有時候如果平台併發訪問高,乙個快取失效了,可能出現多個程序同時查詢db,造成db壓力過大,還有快取頻繁更新的問題。

處理方案是對快取查詢加鎖,如果key不存在則加鎖,查詢db放入快取,然後解鎖;其他程序如果發現有鎖就等待,等解鎖後查詢資料或者進入db查詢。這種情況和剛才說的預先設定值問題有些類似,不過利用鎖的方式,會造成部分請求等待。

引起這個問題的主要原因也是高併發,平時我們可能將快取設定乙個過期時間(比如1分鐘或5分鐘),當併發很高時可能在某乙個時間點同時生成很多快取key,並且過期時間都一樣,這個時候就可能引發在過期時間點到達時,快取同時失效,請求全部**到db,db就會有很大的壓力,造成快取雪崩。

關於此問題,方案之一就是將快取失效時間均勻的分散開,防止同一時間點大量的快取key失效。比如我們可以在原有的失效時間基礎上增加乙個隨機值,比如1-5分鐘隨機,這樣每乙個快取的過期時間的重複率就會降低,就很難引發集體失效的事件。

快取中的某些key(比如某個**商品或熱點事件),對應value儲存在集群中的一台機器,使得所有流量湧向同一機器,這樣就形成系統的乙個瓶頸。該問題的挑戰在於它無法通過增加機器容量來解決。

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

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

如上圖二、圖三是對更新資料的兩種不同操作,一種刪除快取(資料只寫入資料庫,不寫入快取)、一種更新快取(資料不僅寫入資料庫,還要寫入快取),應該選用哪種更新方案呢,這裡需要討論下db和快取不一致的問題。

由於操作快取與運算元據庫不是原子的,中間某一過程非常有可能執行失敗。假設先寫資料庫,再淘汰快取:第一步寫資料庫操作成功,第二步淘汰快取失敗,則會出現db中是新資料,cache中是舊資料,兩方資料不一致。

圖四、db中是新資料,cache中是舊資料

假設先淘汰快取,再寫資料庫:第一步淘汰快取成功,第二步寫資料庫失敗,則只會引發一次cache miss,但是不存髒資料及快取不一致的現象。

圖五、cache中無資料,db中是舊資料

所以我們應該選用:先淘汰快取,再寫資料庫

多級快取也會存在一致性問題,如果我們需要強一致性的話,快取與資料庫同步是會存在時間差的,所以在具體開發的過程中,要根據場景來具體分析,二級快取需要解決是快取穿透與程式的健壯性,保證當集中式快取出現問題的時候,我們的平台能繼續執行。

注:快取併發是針對同乙個快取來講,快取失效是針對很多快取而言。

乙個好的專案不僅需要實現客戶提出的功能需求,還需在效能、穩定性等方面花大量功夫進行測試,才能保證專案在現場環境較少的出現問題,也減少以後維護專案的成本。本案例總結了在使用快取技術時經常遇到的幾個問題,並提供了相應的解決方案,可供其它用到類似技術的同事學習借鑑。

常見快取問題及解決方案

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

快取常見問題及解決方案

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

fc中常見問題及解決方案

我的fc6安裝過程 先簡單介紹一下我的基本情況 fc5,乙個lvm掛載到 乙個ext3格式的 home分割槽。1.備份 把 usr local下的軟體和一些配置檔案拷貝到home中用來備份。如 etc x11 xorg.conf,etc profile.d 下自己新增的script等等 mount上...