轉:數據庫索引原理------MemCached

 
 

Memcached是高性能的分佈式內存緩存服務器。它的主要目的不是基於本地緩存的,而主要用在分佈式系統中。Memcached中保存的數據都存儲在Memcached內置的內存存儲空間中。因爲數據僅存在於內存中,所以重啓Memcached、重啓操做系統會致使所有數據消失。Memcached是記錄級的緩存,以前調研報告裏提到過與MySQL、Server等頁級緩存會緩存無效數據的,記錄級的緩存則使內存利用率更高。算法

 


 

1、Memcached的內存管理方式數組

memcached默認狀況下采用了Slab Allocator的機制分配、管理內存。在該機制出現之前,內存的分配是經過對全部記錄簡單地進行malloc和free來進行的。可是,這種方式會致使內存碎片,加劇操做系統內存管理器的負擔,Slab Allocator就是爲解決該問題而誕生的。緩存

SlabAllocator的基本原理是按照預先規定的大小,將分配的內存分割成特定長度的塊,以徹底解決內存碎片問題。下面我會介紹內存分配過程。服務器


Memcached將內存分紅多個slab,每一個slab是一次申請內存的最小單位(大小爲1M不過好像能夠設置),slab內部又分爲若干個chunk。chunk的大小分爲不少種,以80字節爲初始大小(稱爲id-0的slab),第二類大小爲第一類的f倍(f爲參數可調,稱這類爲id-1的slab),隨id遞增每一類比上一類的chunk大小大f倍。因此一個chunk最大隻可能爲1M。每一個chunk裏包含了一個item結構體(key和value),用來存放緩存數據。chunk大小相同的已分配空間的slab組成一個鏈表,全部的slab鏈表都保存在一個slabclass的數組上(至關於二維鏈表),每一種slab在初始化時默認都會建立一個。分佈式

 

 

2、Memcached緩存記錄的原理memcached

memcached接收到一條記錄時,首先會知道item的大小,而後就會在slabclass數組上去找能包含這個item的最小的chunk的slab鏈表(因爲memcached的各鏈表之間chunk大小的倍數關係,能夠快速定位到鏈表的起始位置),找到空閒的chunk緩存這條記錄。當一個slab的chunk都用完,則新申請新的slab用來存item,申請的slab的大小是倍數變化的(和std::vector同樣),鏈表大小由1變2,由2變四、八、16……若是空間已滿,不能申請更多slab,則按照LRU原則,將空間分配給新的記錄。函數

 

 

 

3、Memcached的內存浪費性能

memcached的內存主要表現有如下三處:spa

一、一個slab分配1M空間,而slab中全部chunks大小加起來可能到不了1M;操作系統

二、每類slab在初始化時默認都會建立一個,可是若是這類slab從未被使用過,則這1M就浪費了;

三、一個item的大小老是不大於chunk大小的,當小於時則發生內存冗餘。

第一類能夠經過參數調優儘可能減小這種內存冗餘,第二類應該也能夠減小,第三類看起來就不太少避免。

 

4、Memcached的分佈式算法


Memcached的服務器端主要是用來記錄緩存和讀取,而分佈式算法即選擇哪臺服務器來尋找數據/寫入內存則由客戶端程序庫實現。方法是用Consistent Hash。

ConsistentHashing以下所示:首先求出memcached服務器(節點)的哈希值(memcached用CRC計算哈希值),並將其配置到0-232的圓上。而後用一樣的方法求出存儲數據的鍵的哈希值,並映射到圓上。而後從數據映射到的位置開始順時針查找,將數據保存到找到的第一個服務器上。


從上圖的狀態中添加一臺memcached服務器。傳統的取模算法會使大量的鍵不能哈希到以前緩存的服務器上,但Consistent Hashing中,只有在增長服務器的地點逆時針方向的第一臺服務器上的鍵會受到影響(以下圖)。


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

 

(轉載本文請註明出處: http://blog.csdn.net/jiang1st2010/article/details/8121361)

相關文章
相關標籤/搜索