十分鐘徹底掌握快取擊穿、快取穿透、快取雪崩

三分惡發表於2021-09-10

大家好,我是老三,刷題刷煩了……

寫篇文章緩一下,分享一下老八股:快取擊穿快取穿透快取雪崩

在瞭解這三大問題之前,我們要理解,常用的分散式快取Redis單機併發量能達到萬級,常用的關係型資料庫MySQL一般併發量是千級,他們支援的併發量可能差十倍,所以要儘可能把流量攔截在快取層。

為什麼呢?就像是大湖裡多排點水,就可能把小河道沖垮,不知道你聽過沒——長江之水天上來,白洋澱裡把不住。

快取擊穿

什麼是快取擊穿

先從快取擊穿開始。

快取擊穿: 一個併發訪問量比較大的key在某個時間過期,導致所有的請求直接打在DB上。

快取擊穿

快取擊穿會增大資料庫的負載,我們看看怎麼緩解。

快取擊穿如何解決

加鎖更新

查詢快取,發現快取中不存在,加鎖,讓其它執行緒等待,只讓一個執行緒去更新快取。

加鎖更新

非同步更新

還有一個可行的方案是把快取設定永不過期。那快取怎麼更新呢?通過非同步的方式去更新快取。

比如後臺設定一個守護執行緒定時更新快取,但這種定時比較難以把握。

非同步更新機制實際上更適合用於快取預熱。

快取穿透

什麼是快取穿透

快取穿透:快取穿透指的查詢快取和資料庫中都不存在的資料,這樣每次請求直接打到資料庫,就好像快取不存在一樣。

快取穿透

快取穿透將導致不存在的資料每次請求都要到儲存層去查詢,失去了快取保護後端儲存的意義。

快取穿透可能會使後端儲存負載加大,如果發現大量儲存層空命中,可能就是出現了快取穿透問題。

快取穿透可能有兩種原因:

  1. 自身業務程式碼問題
  2. 惡意攻擊,爬蟲造成空命中

我們來看看如何解決。

快取穿透如何解決

快取空值/預設值

一種方式是在資料庫不命中之後,把一個空物件或者預設值儲存到快取,之後再訪問這個資料,就會從快取中獲取,這樣就保護了資料庫。

快取空值

快取空值有兩大問題:

  1. 空值做了快取,意味著快取層中存了更多的鍵,需要更多的記憶體空間(如果是攻擊,問題更嚴重),比較有效的

    方法是針對這類資料設定一個較短的過期時間,讓其自動剔除。

  2. 快取層和儲存層的資料會有一段時間視窗的不一致,可能會對業務有一定影響。

    例如過期時間設定為5分鐘,如果此時儲存層新增了這個資料,那此段時間就會出現快取層和儲存層資料的不一致。

    這時候可以利用訊息佇列或者其它非同步方式清理快取中的空物件。

布隆過濾器

除了快取空物件,我們還可以在儲存和快取之前,加一個布隆過濾器,做一層過濾。

布隆過濾器裡會儲存資料是否存在,如果判斷資料不不能再,就不會訪問儲存。

布隆過濾器過濾

那布隆過濾器是什麼玩意兒?查詢它會不會很慢?

布隆過濾器是什麼?

不知道你對雜湊表瞭解多少,布隆過濾器是一個類似的東西。

它是一個連續的資料結構,每個儲存位儲存都是一個bit,即0或者1, 來標識資料是否存在。

儲存資料的時時候,使用K個不同的雜湊函式將這個變數對映為bit列表的的K個點,把它們置為1。

布隆過濾器結構

我們判斷快取key是否存在,同樣,K個雜湊函式,對映到bit列表上的K個點,判斷是不是1:

  • 如果全不是1,那麼key不存在;
  • 如果都是1,也只是表示key可能存在。

至於為什麼?因為雜湊函式是存在碰撞的可能的。

關於快取穿透的兩種主要解決方案,我們簡單對比一下:

快取空物件核布隆過濾器方案對比

快取雪崩

接下來我們看最嚴重的一種情況,快取雪崩。

什麼是快取雪崩

快取雪崩: 當某⼀時刻發⽣⼤規模的快取失效的情況,例如快取服務當機、大量key在同一時間過期,這樣的後果就是⼤量的請求進來直接打到DB上,可能導致整個系統的崩潰,稱為雪崩。

快取雪崩

快取雪崩如何解決

快取雪崩是三大快取問題裡最嚴重的一種,我們來看看怎麼預防和處理。

提高快取可用性

  • 叢集部署:通過叢集來提升快取的可用性,可以利用Redis本身的Redis Cluster或者第三方叢集方案如Codis等。
  • 多級快取:設定多級快取,第一級快取失效的基礎上,訪問二級快取,每一級快取的失效時間都不同。

過期時間

  • 均勻過期:為了避免大量的快取在同一時間過期,可以把不同的 key 過期時間隨機生成,避免過期時間太過集中。
  • 熱點資料永不過期。

熔斷降級

  • 服務熔斷:當快取伺服器當機或超時響應時,為了防止整個系統出現雪崩,暫時停止業務服務訪問快取系統。
  • 服務降級:當出現大量快取失效,而且處在高併發高負荷的情況下,在業務系統內部暫時捨棄對一些非核心的介面和資料的請求,而直接返回一個提前準備好的 fallback(退路)錯誤處理資訊。

總結

一張圖總結:

面渣逆襲-第 3 頁



參考:

[1]. 《Redis開發與運維》

[2]. 《極客時間 高併發系統設計四十問》

[4]. 快取穿透、快取擊穿、快取雪崩,看這篇就夠了

[5]. 布隆過濾器,沒那麼難

相關文章