memcache簡介

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

原文:http://wenku.baidu.com/view/8686d46c7e21af45b307a8c3.html

什麼是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默認情況下采用了名爲SlabAllocatoion的機制分配,管理內存。在改機制出現以前,內存的分配是通過對所有記錄簡單地進行malloc和free來進行的。但是這中方式會導致內存碎片,加重操作系統內存管理器的負擔。

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

分佈式緩存-Memcached

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

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

在Slab 中緩存記錄的原理

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

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

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

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

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

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服務器發生故障無法連接,也不會影響其他的緩存,系統依然能繼續運行。

Memcached的緩存分佈策略:http://blog.csdn.net/bintime/article/details/6259133

ConsistentHashing的簡單說明

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

分佈式緩存-Memcached

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

分佈式緩存-Memcached

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

緩存多副本

緩存多副本主要是用於在緩存數據存放時存儲緩存數據的多個副本,以防止緩存失效。緩存失效發生在以下幾種情況:
  • 1.   緩存超時被移除(正常失效)
  • 2.   緩存由於存儲空間限制被移除(異常失效)
  • 3.   由於緩存節點變化而導致的緩存失效(異常失效)

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

緩存數據的一致性問題

緩存數據儘量只讀,因此緩存本身是不適合大量寫和更新操作的數據場景的。對於讀的情況下,如果存在數據變化,一種是同時更新緩存和數據庫。一種是直接對緩存數據進行失效處理。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章