博客 / 詳情

返回

分佈式系統架構8:分佈式緩存

這是小卷對分佈式系統架構學習的第11篇文章,今天瞭解分佈式緩存的理論知識以及Redis集羣。

分佈式緩存也是面試常見的問題,通常面試官會問為什麼要用緩存,以及用的Redis是哪種模式,用的過程中遇到哪些問題這些

1. AP還是CP

Redis 集羣就是典型的 AP 式,它具有高性能、高可用等特點,但它卻並不保證強一致性。

而能夠保證強一致性的 ZooKeeper、Doozerd、Etcd 等框架,吞吐量比不過Redis,通常不會用作“緩存框架”,而是作為通知、協調、隊列、分佈式鎖等使用

2.透明多級緩存TMC

實際開發中,同時搭配進程內緩存和分佈式緩存,來構成透明多級緩存(Transparent Multilevel Cache,TMC)

多級緩存的查詢過程如下圖:

缺點:代碼侵入性大,由開發人員維護管理

一、二級緩存數據不一致問題解決:

  • 設計原則:變更以分佈式緩存中的數據為準,查詢以進程內緩存數據優先

3.實現方案

3.1 memcached緩存

在服務端,memcached集羣環境實際就是一個個memcached服務器的堆積

cache的分佈式主要是在客户端實現,通過客户端的路由處理來達到分佈式解決方案的目的。客户端做路由的原理,是在每次存取某key的value時,通過一致性哈希算法把key映射到某台memcached服務器node上。

如下是memcached客户端路由過程:

3.2 Redis緩存

與memcached客户端支持分佈式方案不同,Redis更傾向於在服務端構建分佈式存儲

  • 以Redis集羣模式為例,它沒有中心節點,具有線性可伸縮的功能。
  • 節點與節點之間通過二進制協議進行通信,節點與客户端之間通過ascii協議進行通信
  • 在數據的放置策略上,Redis Cluster將整個key的數值域分成2的14次方16384個hash槽,每個節點上可以存儲一個或多個hash槽,也就是説當前Redis Cluster支持的最大節點數就是16384
  • 總結下:數據hash分佈在不同redis節點實例,主/從切換採用Sentinel
  • 寫:只會寫master Instance,從sentinel獲取當前的master instance;
  • 讀:從redis node中基於權重選取一個實例讀取,失敗/超時則輪詢其他實例;

要想詳細瞭解redis的面試過程中的問題,可以參考下面的思維導圖自行整理:

4. 緩存風險

4.1 緩存穿透

緩存風險問題也是面試常考的八股文題目,這裏還是簡單説明下

緩存穿透:查詢的數據在數據庫里根本不存在,緩存裏也不會有,這樣的請求每次都不會命中緩存,會請求到末端數據庫。這種查詢不存在數據的現象就是緩存穿透

解決辦法:

  • 對業務邏輯本身不能避免的緩存穿透:對返回為空的Key值進行緩存,如果數據庫中對該key插入新記錄,就需要主動清理緩存的key值。
  • 惡意攻擊導致的緩存穿透:緩存之前設置一個布隆過濾器來解決,思路就是判斷請求的數據是否存在,布隆過濾器可以判斷某個元素是否在集合中

4.2 緩存擊穿

概念:單個熱點key失效,在失效的那一刻,同時有大量請求打到DB上,造成數據庫壓力劇增的情況

解決辦法:

  • 設置熱點key不過期定時任務更新緩存或者設置互斥鎖,當請求過來時,發現緩存不存在數據時,就給當前請求加鎖,後面的請求等待或者返回,當從數據庫中拿出來放到緩存中時,就可以釋放鎖資源。

4.3 緩存雪崩

概念:多個熱點key緩存失效,大量的key設置了相同的過期時間、導致緩存在同一時間全部失效,造成瞬時DB請求量大、壓力劇增。

解決辦法:

  • 存數據的過期時間設置隨機,防止同一時間大量數據過期現象發生
  • 啓用透明多級緩存,多個服務節點因為加載一級緩存的時間不一樣,也能分散過期時間

4.4 緩存污染

概念:緩存中的數據與真實數據源中的數據不一致的現象

解決辦法:

使用更新緩存時遵循的設計模式,如:Cache Aside,Read/Write Through,Write Behind Caching這些

Cache Aside模式的工作方式:

  • 讀數據時,先讀緩存,如緩存中沒有,則讀數據庫,再將數據寫入緩存中;
  • 寫數據時,先寫數據庫,然後失效緩存(刪除緩存數據);

面試可能遇到的兩個關於Cache Aside的問題:

1.更新先後順序,為什麼先更新數據庫再刪除緩存?

  • 假設先刪除緩存再更新數據庫,會有一段時間是緩存已刪除,數據庫未更新的情況。這時如果有請求進來,緩存中沒查到,就會查數據庫中舊的數據,再放到緩存裏。造成問題就是:數據庫已經是最新數據,緩存中還是舊的,不一致的問題;

2.為什麼是刪除緩存,而不是更新緩存?

  • 和上面一樣,更新過程中,如果有其他更新請求進來更新數據庫,緩存就會面臨多次修改賦值的複雜時序問題。所以直接刪除緩存就行。

總結:本文只寫了一些關於分佈式緩存的簡單理論內容,實際面試時大多圍繞redis進行提問,下次再寫關於redis的相關內容

user avatar markerhub 頭像 xiaoweiyu 頭像 fulng 頭像 edagarli 頭像 13917911249 頭像 yaoyaolx_wiki 頭像 knifeblade 頭像 saoming_zhang 頭像 gozhuyinglong 頭像 shadowck 頭像 yexiaobai_616e2b70869ae 頭像 ixuea 頭像
21 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.