幾個重要概念 Slab memcached通過slab機制進行記憶體的分配和回收,slab是一個記憶體塊,它是memcached一次申請記憶體的最小單位,。在啟動memcached的時候一般會使用參數-m指定其可用記憶體,但是並不是在啟動的那一刻所有的記憶體就全部分配出去了,只有在需要的時候才會去申請,而且每 ...
幾個重要概念
Slab
memcached通過slab機制進行記憶體的分配和回收,slab是一個記憶體塊,它是memcached一次申請記憶體的最小單位,。在啟動memcached的時候一般會使用參數-m指定其可用記憶體,但是並不是在啟動的那一刻所有的記憶體就全部分配出去了,只有在需要的時候才會去申請,而且每次申請一定是一個slab。Slab的大小固定為1MB(1MB=1024KB=1024×1024B=1048576B,1048576位元組),一個slab由若幹個大小相等的chunk組成。
Slab的分類
根據chunk的大小而將Slab分為不同的類,chunk大小的增幅由增長因數factor決定。根據memcached版本的不同而分類也各有不同,-vv查詢分類。
Chunk
chunk是Slab的組成單位,每個Slab都被分割成大小相等的chunk,分割Slab時,不夠一個chunk大小的記憶體空間將被不可以避免的浪費(記憶體碎片化)。每個chunk中都保存了一個item結構體,item結構體由屬性域和數據域組成,數據域中有一個變長數據data,是真正存儲緩存記錄key和value的地方。
圖memcached Slab 分類示意圖
源碼
typedef struct _stritem {
//屬性域
struct _stritem *next;
struct _stritem *prev;
......
//數據域
union {
uint64_t cas;
char end;
} data[];
} item;
Chunk的計算
對於Slab 分類 i,求Slab 分類 i中的chunk的大小:
chunkSize = (default_size + item_size)*f^(i-1) + CHUNK_ALIGN_BYTES
各參數含義:
l i,分類
l default_size,預設大小為48位元組,也就是item結構體中數據域的大小為48位元組,可以通過-n參數來調節其大小
l item_size, item結構體的長度,固定為32位元組
l f,factor,增長因數,是chunk變化大小的因素,預設值為1.25,調節f可以改變chunk的增幅,在啟動時可以使用-f來指定
l CHUNK_ALIGH_BYTES 是一個長常量值,用來保證chunk的大小是這個常量值的整數倍,防止越界。CHUNK_ALIGH_BYTES 大小為sizeof(void *)
例如:void *的長度在不同系統上不一樣,在32位機器上,sizeof(void *)值為4
所以,在32為的系統中,Slab 分類1中chunk的大小為:
chunkSize1 = (48 + 32)* 1.25^(1-1) + 4 = 84(有待驗證)
從chunkSize的計算公式可以看出,可以通過調節-n,-f參數來調整chunk的大小,這也是實際中mecahced調優的關鍵,合理的調節-n,-f參數以充分利用記憶體資源,儘可能的減少記憶體碎片化。
記憶體分配
當我們通過add命令向memcached中添加一條記錄的時候,memcached會根據數據的大小選擇合適的slab,memcached維護著slab中空閑的chunk列表,並從中選擇一塊分配給要添加的記錄。
如要存的item大小為100byte,chunk大小為80byte的slab將存不下,而chunk大小為120byte的slab又有剩餘,此時memcached會將數據存到chunk大小為120byte的slab中。而剩餘的20byte空間將不可避免的浪費。
需要註意的是,當chunk大小為120byte的slab已經滿時,memcached並不會尋找更大chunk的slab,如chunk大小為140byte的slab來存儲,而是把chunk大小為120byte的slab中的舊數據踢掉。
增長因數調優
memcached 在啟動時可以通過f 選項指定增長因數,預設為1.25。增長因數的不同,chunk大小也不同,應根據實際情況,指定合理的增長因數避免過多的記憶體空間浪費。
過期數據惰性刪除
Memcached中,當某個chunk 中的數據過期後,並不會馬上從記憶體中刪除,因此,使用stats 統計時,curr_item 中仍然有其信息,直到新的數據占用該chunk ;當試圖去get改數據時,先判斷是否過期,如果過期則返回空並清空chunk,curr_item減1。過期數據不會馬上刪除,這種機制稱為lazy expiration,即惰性失效,好處是不需要另外去檢查數據是否失效,節省了CUP的檢測成本。
LRU刪除機制
和操作系統記憶體管理類似,memcached數據刪除機制使用的是“最近最少使用”機制(Least Recently Used)進行數據剔除,memcached通過維護一個計數器,來判斷最近誰最少被使用,當有新的數據進來時,最近最少用的數據將被剔除。
memcached使用三十二位元的迴圈冗餘校驗(CRC-32)計算鍵值後,將數據分散在不同的機器上。當chunk滿了以後,接下來新增的數據會以LRU機制替換掉。
即使某個key被設置永久有效期,也一樣會被踢出來,即永久數據被踢現象。
參考文檔:
http://kenby.iteye.com/blog/1423989
http://www.dexcoder.com/selfly/article/2248
http://www.dexcoder.com/selfly/series/63
http://www.cnblogs.com/luluping/archive/2009/01/14/1375456.html