分佈式緩存系統 Memcached 整體架構

 

從這裏面轉載的:http://www.linuxidc.com/Linux/2015-01/112507.htm

別人的csdn    http://blog.csdn.net/yuyixinye/article/details/39588083

分佈式緩存出於如下考慮,首先是緩存本身的水平線性擴展問題,其次是緩存大併發下的本身的性能問題,再次避免緩存的單點故障問題(多副本和副本一致性)。分佈式緩存的核心技術包括首先是內存本身的管理問題,包括了內存的分配,管理和回收機制。其次是分佈式管理和分佈式算法,其次是緩存鍵值管理和路由。

什麼是Memcached

許多Web 應用程序都將數據保存到RDBMS中,應用服務器從中讀取數據並在瀏覽器中顯示。但隨着數據量的增大,訪問的集中,就會出現REBMS的負擔加重,數據庫響應惡化,網站顯示延遲等重大影響。Memcached是高性能的分佈式內存緩存服務器。一般的使用目的是通過緩存數據庫查詢結果,減少數據庫的訪問次數,以提高動態Web 應用的速度、提高擴展性。如圖:

分佈式緩存系統 Memcached

Memcached作爲高速運行的分佈式緩存服務器具有以下特點。

  • 協議簡單:memcached的服務器客戶端通信並不使用複雜的MXL等格式,而是使用簡單的基於文本的協議。
  • 基於libevent的事件處理:libevent是個程序庫,他將Linux 的epoll、BSD類操作系統的kqueue等時間處理功能封裝成統一的接口。memcached使用這個libevent庫,因此能在Linux、BSD、Solaris等操作系統上發揮其高性能。
  • 內置內存存儲方式:爲了提高性能,memcached中保存的數據都存儲在memcached內置的內存存儲空間中。由於數據僅存在於內存中,因此重啓memcached,重啓操作系統會導致全部數據消失。另外,內容容量達到指定的值之後memcached回自動刪除不適用的緩存。
  • Memcached不互通信的分佈式:memcached儘管是“分佈式”緩存服務器,但服務器端並沒有分佈式功能。各個memcached不會互相通信以共享信息。他的分佈式主要是通過客戶端實現的。

Memcached的內存管理

最近的memcached默認情況下采用了名爲Slab Allocatoion的機制分配,管理內存。在改機制出現以前,內存的分配是通過對所有記錄簡單地進行malloc和free來進行的。但是這中方式會導致內存碎片,加重操作系統內存管理器的負擔。

Slab Allocator的基本原理是按照預先規定的大小,將分配的內存分割成特定長度的塊,已完全解決內存碎片問題。Slab Allocation  的原理相當簡單。將分配的內存分割成各種尺寸的塊(chucnk),並把尺寸相同的塊分成組(chucnk的集合)如圖:

分佈式緩存系統 Memcached

而且slab allocator 還有重複使用已分配內存的目的。也就是說,分配到的內存不會釋放,而是重複利用。

Slab Allocation 的主要術語

  • Page :分配給Slab 的內存空間,默認是1MB。分配給Slab 之後根據slab 的大小切分成chunk.
  • Chunk : 用於緩存記錄的內存空間。
  • Slab Class:特定大小的chunk 的組。

在Slab 中緩存記錄的原理

Memcached根據收到的數據的大小,選擇最合適數據大小的Slab (圖2) memcached中保存着slab內空閒chunk的列表,根據該列表選擇chunk,然後將數據緩存於其中。

分佈式緩存系統 Memcached

Memcached在數據刪除方面有效裏利用資源

Memcached刪除數據時數據不會真正從memcached中消失。Memcached不會釋放已分配的內存。記錄超時後,客戶端就無法再看見該記錄(invisible 透明),其存儲空間即可重複使用。

Lazy Expriationmemcached內部不會監視記錄是否過期,而是在get時查看記錄的時間戳,檢查記錄是否過期。這種技術稱爲lazy expiration.因此memcached不會再過期監視上耗費CPU時間。

對於緩存存儲容量滿的情況下的刪除需要考慮多種機制,一方面是按隊列機制,一方面應該對應緩存對象本身的優先級,根據緩存對象的優先級進行對象的刪除。

LRU:從緩存中有效刪除數據的原理

Memcached會優先使用已超時的記錄空間,但即使如此,也會發生追加新紀錄時空間不足的情況。此時就要使用名爲Least Recently Used (LRU)機制來分配空間。這就是刪除最少使用的記錄的機制。因此當memcached的內存空間不足時(無法從slab class)獲取到新空間時,就從最近未使用的記錄中搜索,並將空間分配給新的記錄。

Memcached分佈式

Memcached雖然稱爲“分佈式“緩存服務器,但服務器端並沒有“分佈式”的功能。Memcached的分佈式完全是有客戶端實現的。現在我們就看一下memcached是怎麼實現分佈式緩存的。

例如下面假設memcached服務器有node1~node3三臺,應用程序要保存鍵名爲“tokyo”“kanagawa”“chiba”“saitama”“gunma” 的數據。

首先向memcached中添加“tokyo”。將“tokyo”傳給客戶端程序庫後,客戶端實現的算法就會根據“鍵”來決定保存數據的memcached服務器。服務器選定後,即命令它保存“tokyo”及其值。

同樣,“kanagawa”“chiba”“saitama”“gunma”都是先選擇服務器再保存。

接下來獲取保存的數據。獲取時也要將要獲取的鍵“tokyo”傳遞給函數庫。函數庫通過與數據保存時相同的算法,根據“鍵”選擇服務器。使用的算法相同,就能選中與保存時相同的服務器,然後發送get命令。只要數據沒有因爲某些原因被刪除,就能獲得保存的值。

分佈式緩存系統 Memcached

這樣,將不同的鍵保存到不同的服務器上,就實現了memcached的分佈式。 memcached服務器增多後,鍵就會分散,即使一臺memcached服務器發生故障無法連接,也不會影響其他的緩存,系統依然能繼續運行。

Consistent Hashing的簡單說明

Consistent Hashing如下所示:首先求出memcached服務器(節點)的哈希值, 並將其配置到0~232的圓(continuum)上。 然後用同樣的方法求出存儲數據的鍵的哈希值,並映射到圓上。 然後從數據映射到的位置開始順時針查找,將數據保存到找到的第一個服務器上。 如果超過232仍然找不到服務器,就會保存到第一臺memcached服務器上。

分佈式緩存系統 Memcached

從上圖的狀態中添加一臺memcached服務器。餘數分佈式算法由於保存鍵的服務器會發生巨大變化 而影響緩存的命中率,但Consistent Hashing中,只有在continuum上增加服務器的地點逆時針方向的 第一臺服務器上的鍵會受到影響。

分佈式緩存系統 Memcached

因此,Consistent Hashing最大限度地抑制了鍵的重新分佈。 而且,有的Consistent Hashing的實現方法還採用了虛擬節點的思想。 使用一般的hash函數的話,服務器的映射地點的分佈非常不均勻。 因此,使用虛擬節點的思想,爲每個物理節點(服務器) 在continuum上分配100~200個點。這樣就能抑制分佈不均勻, 最大限度地減小服務器增減時的緩存重新分佈。

Memcached 安裝及啓動腳本 http://www.linuxidc.com/Linux/2013-07/87641.htm

PHP中使用Memcached的性能問題 http://www.linuxidc.com/Linux/2013-06/85883.htm

Ubuntu下安裝Memcached及命令解釋 http://www.linuxidc.com/Linux/2013-06/85832.htm

Memcached的安裝和應用 http://www.linuxidc.com/Linux/2013-08/89165.htm

使用Nginx+Memcached的小圖片存儲方案 http://www.linuxidc.com/Linux/2013-11/92390.htm

Memcached使用入門 http://www.linuxidc.com/Linux/2011-12/49516p2.htm

緩存多副本

緩存多副本主要是用於在緩存數據存放時存儲緩存數據的多個副本,以防止緩存失效。緩存失效發生在以下幾種情況:

1.    緩存超時被移除(正常失效)

2.    緩存由於存儲空間限制被移除(異常失效)

3.    由於緩存節點變化而導致的緩存失效(異常失效)

在緩存多副本的情況下,需要重新考慮緩存的分佈式分佈策略。其次緩存的多個副本實際本身是可能的多個讀的節點,可以做爲分佈式的並行讀,這是另外一個可以考慮的問題。

緩存數據的一致性問題

緩存數據儘量只讀,因此緩存本身是不適合大量寫和更新操作的數據場景的。對於讀的情況下,如果存在數據變化,一種是同時更新緩存和數據庫。一種是直接對緩存數據進行失效處理。

 

相關書籍:memcached全面分析 長野雅廣、前阪徹著

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章