大型分散式系統中的緩存架構
本文主要介紹大型分散式系統中緩存的相關理論,常見的緩存組件以及應用場景。
緩存概述
緩存概述
緩存的分類
緩存主要分為四類,如下圖:
緩存的分類
CDN 緩存
CDN(Content Delivery Network 內容分發網路)的基本原理是廣泛採用各種緩存伺服器,將這些緩存伺服器分布到用戶訪問相對集中的地區或網路中。
在用戶訪問網站時,利用全局負載技術將用戶的訪問指向距離最近的工作正常的緩存伺服器上,由緩存伺服器直接響應用戶請求。
應用場景:主要緩存靜態資源,例如圖片,視頻。
CDN 緩存應用如下圖:
未使用 CDN 緩存
使用 CDN 緩存
CDN 緩存優點如下圖:
優點
反向代理緩存
反向代理位於應用伺服器機房,處理所有對 Web 伺服器的請求。
如果用戶請求的頁面在代理伺服器上有緩衝的話,代理伺服器直接將緩衝內容發送給用戶。
如果沒有緩衝則先向 Web 伺服器發出請求,取回數據,本地緩存後再發送給用戶。通過降低向 Web 伺服器的請求數,從而降低了 Web 伺服器的負載。
應用場景:一般只緩存體積較小靜態文件資源,如 css、js、圖片。
反向代理緩存應用如下圖:
反向代理緩存應用圖
開源實現如下圖:
開源實現
本地應用緩存
指的是在應用中的緩存組件,其最大的優點是應用和 Cache 是在同一個進程內部,請求緩存非常快速,沒有過多的網路開銷等。
在單應用不需要集群支持或者集群情況下各節點無需互相通知的場景下使用本地緩存較合適。
同時,它的缺點也是應為緩存跟應用程序耦合,多個應用程序無法直接的共享緩存,各應用或集群的各節點都需要維護自己的單獨緩存,對內存是一種浪費。
應用場景:緩存字典等常用數據。
緩存介質如下圖所示:
緩存介質
編程直接實現如下圖:
編程直接實現
Ehcache
基本介紹:Ehcache 是一種基於標準的開源緩存,可提高性能,卸載資料庫並簡化可伸縮性。
它是使用最廣泛的基於 Java 的緩存,因為它功能強大,經過驗證,功能齊全,並與其他流行的庫和框架集成。
Ehcache 可以從進程內緩存擴展到使用 TB 級緩存的混合進程內/進程外部署。
Ehcache 應用場景如下圖:
Ehcache 應用場景
Ehcache 的架構如下圖:
Ehcache 架構圖
Ehcache 的主要特徵如下圖:
Ehcache 主要特徵
Ehcache 緩存數據過期策略如下圖:
緩存數據過期策略
Ehcache 過期數據淘汰機制:即懶淘汰機制,每次往緩存放入數據的時候,都會存一個時間,在讀取的時候要和設置的時間做 TTL 比較來判斷是否過期。
Guava Cache
基本介紹:Guava Cache 是 Google 開源的 Java 重用工具集庫 Guava 里的一款緩存工具。
Guava Cache 特點與功能如下圖:
Guava Cache 特點與功能
Guava Cache 的應用場景如下圖:
Guava Cache 應用場景
Guava Cache 的數據結構如下圖:
Guava Cache 數據結構圖
Guava Cache 結構特點
Guava Cache 的緩存更新策略如下圖:
Guava Cache 緩存更新策略
Guava Cache 的緩存回收策略如下圖:
Guava Cache 緩存回收策略
分散式緩存
指的是與應用分離的緩存組件或服務,其最大的優點是自身就是一個獨立的應用,與本地應用隔離,多個應用可直接的共享緩存。
分散式緩存的主要應用場景如下圖:
分散式緩存應用場景
分散式緩存的主要接入方式如下圖:
分散式緩存接入方式
下面介紹分散式緩存常見的 2 大開源實現 Memcached 和 Redis。
Memcached
Memcached 是一個高性能,分散式內存對象緩存系統,通過在內存里維護一個統一的巨大的 Hash 表,它能夠用來存儲各種格式的數據,包括圖像、視頻、文件以及資料庫檢索的結果等。
簡單的說就是將數據調用到內存中,然後從內存中讀取,從而大大提高讀取速度。
Memcached 的特點如下圖:
Memcached 特點
Memcached 的基本架構如下圖:
Memcached 基本架構
緩存數據過期策略:LRU(最近最少使用)到期失效策略,在 Memcached 內存儲數據項時,可以指定它在緩存的失效時間,默認為永久。
當 Memcached 伺服器用完分配的內存時,失效的數據被首先替換,然後是最近未使用的數據。
數據淘汰內部實現:懶淘汰機製為每次往緩存放入數據的時候,都會存一個時間,在讀取的時候要和設置的時間做 TTL 比較來判斷是否過期。
分散式集群實現:服務端並沒有 「 分散式 」 功能。每個伺服器都是完全獨立和隔離的服務。 Memcached 的分散式,是由客戶端程序實現的。
數據讀寫流程圖
Memcached 分散式集群實現
Redis
Redis 是一個遠程內存資料庫(非關係型資料庫),性能強勁,具有複製特性以及解決問題而生的獨一無二的數據模型。
它可以存儲鍵值對與 5 種不同類型的值之間的映射,可以將存儲在內存的鍵值對數據持久化到硬碟,可以使用複製特性來擴展讀性能。
Redis 還可以使用客戶端分片來擴展寫性能,內置了 複製(replication),LUA 腳本(Lua scripting),LRU 驅動事件(LRU eviction),事務(transactions) 和不同級別的磁碟持久化(persistence)。
並通過 Redis 哨兵(Sentinel)和自動分區(Cluster)提供高可用性(High Availability)。
Redis 的數據模型如下圖:
Redis 數據模型
Redis 的數據淘汰策略如下圖:
Redis 數據淘汰策略
Redis 的數據淘汰內部實現如下圖:
Redis 數據淘汰內部實現
Redis 的持久化方式如下圖:
Redis 持久化方式
Redis 底層實現部分解析如下圖:
啟動的部分過程圖解
Server 端持久化的部分操作圖解
底層哈希表實現(漸進式Rehash)如下圖:
初始化字典
新增字典元素圖解
Rehash 執行流程
Redis 的緩存設計原則如下圖所示:
Redis 緩存設計原則
Redis 與 Memcached 的比較如下圖:
Redis 與 Memcached 比較
下面主要介紹緩存架構設計常見問題以及解決方案,業界案例。
分層緩存架構設計
緩存帶來的複雜度問題
常見的問題主要包括如下幾點:
數據一致性
緩存穿透
緩存雪崩
緩存高可用
緩存熱點
下面逐一介紹分析這些問題以及相應的解決方案。
數據一致性
因為緩存屬於持久化數據的一個副本,因此不可避免的會出現數據不一致問題,導致臟讀或讀不到數據的情況。
數據不一致,一般是因為網路不穩定或節點故障導致問題出現的常見 3 個場景以及解決方案:
緩存穿透
緩存一般是 Key-Value 方式存在,當某一個 Key 不存在時會查詢資料庫,假如這個 Key,一直不存在,則會頻繁的請求資料庫,對資料庫造成訪問壓力。
主要解決方案:
對結果為空的數據也進行緩存,當此 Key 有數據後,清理緩存。
一定不存在的 Key,採用布隆過濾器,建立一個大的 Bitmap 中,查詢時通過該 Bitmap 過濾。
緩存雪崩
緩存高可用
緩存是否高可用,需要根據實際的場景而定,並不是所有業務都要求緩存高可用,需要結合具體業務,具體情況進行方案設計,例如臨界點是否對後端的資料庫造成影響。
主要解決方案:
分布式:實現數據的海量緩存。
複製:實現緩存數據節點的高可用。
緩存熱點
一些特別熱點的數據,高並發訪問同一份緩存數據,導致緩存伺服器壓力過大。
解決:複製多份緩存副本,把請求分散到多個緩存伺服器上,減輕緩存熱點導致的單台緩存伺服器壓力
業界案例
※詳談微服務與容器技術發展史
※Flash快閃記憶體顆粒和工藝知識深度解析
TAG:架構師技術聯盟 |