Memcached 内存管理(一)
2019獨角獸企業(yè)重金招聘Python工程師標(biāo)準(zhǔn)>>>
Memcached是一個高效的分布式內(nèi)存cache,了解memcached的內(nèi)存管理機制,便于我們理解memcached,讓我們可以針對我們數(shù)據(jù)特點進(jìn)行調(diào)優(yōu),讓其更好的為我所用。這里簡單談一下我對memcached的內(nèi)存管理的一些認(rèn)識,在沒有特別注明的情況下,這里談到的memcached是1.2版本,1.1和1.2版本有一些差異。
基本概念:Slab和chunk
在Memcached內(nèi)存結(jié)構(gòu)中有兩個非常重要的概念:slab 和 chunk,我們先從下圖中對這兩個概念有一個感性的認(rèn)識:
圖?1 memcached內(nèi)存結(jié)構(gòu)
Slab是一個內(nèi)存塊,它是memcached一次申請內(nèi)存的最小單位。在啟動memcached的時候一般會使用參數(shù)-m指定其可用內(nèi)存,但是并不是在啟動的那一刻所有的內(nèi)存就全部分配出去了,只有在需要的時候才會去申請,而且每次申請一定是一個slab。Slab的大小固定為1M(1048576 Byte),一個slab由若干個大小相等的chunk組成。每個chunk中都保存了一個item結(jié)構(gòu)體、一對key和value。
雖然在同一個slab中chunk的大小相等的,但是在不同的slab中chunk的大小并不一定相等,在memcached中按照chunk的大小不同,可以把slab分為很多種類(class)。在啟動memcached的時候可以通過-vv來查看slab的種類:
圖2 slab分組信息
從上圖可以看到,默認(rèn)情況下memcached把slab分為40類(class1~class40),在class 1中,chunk的大小為80字節(jié),由于一個slab的大小是固定的1048576字節(jié)(1M),因此在class1中最多可以有13107個chunk:
?????? 13107×80 + 16 = 1048576
在class1中,剩余的16字節(jié)因為不夠一個chunk的大小(80byte),因此會被浪費掉。每類chunk的大小有一定的計算公式的,假定i代表分類,class i的計算公式如下:
chunk size(class i) : ?(default_size+item_size)*f^(i-1)+?CHUNK_ALIGN_BYTES
default_size: 默認(rèn)大小為48字節(jié),也就是memcached默認(rèn)的key+value的大小為48字節(jié),可以通過-n參數(shù)來調(diào)節(jié)其大小;
item_size: item結(jié)構(gòu)體的長度,固定為32字節(jié)。default_size大小為48字節(jié),item_size為32,因此class1的chunk大小為48+32=80字節(jié);
f為factor,是chunk變化大小的因素,默認(rèn)值為1.25,調(diào)節(jié)f可以影響chunk的步進(jìn)大小,在啟動時可以使用-f來指定;
CHUNK_ALIGN_BYTES是一個修正值,用來保證chunk的大小是某個值的整數(shù)倍(在32位機器上要求chunk的大小是4的整數(shù)倍)。
從上面的分析可以看到,我們實際可以調(diào)節(jié)的參數(shù)有-f、-n,在memcached的實際運行中,我們還需要觀察我們的數(shù)據(jù)特征,合理的調(diào)節(jié)f,n的值,使我們的內(nèi)存得到充分的利用減少浪費。
?
內(nèi)存申請分配
?
Memcached內(nèi)存管理采取預(yù)分配、分組管理的方式,分組管理就是我們上面提到的slab class,按照chunk的大小slab被分為很多種類。下面解釋一下memcached的內(nèi)存預(yù)分配過程。
向memcached添加一個item時候,memcached首先會根據(jù)item的大小,來選擇最合適的slab class:例如item的大小為190字節(jié),默認(rèn)情況下class 4的chunk大小為160字節(jié)顯然不合適,class 5的chunk大小為200字節(jié),大于190字節(jié),因此該item將放在class 5中(顯然這里會有10字節(jié)的浪費是不可避免的),計算好所要放入的chunk之后,memcached會去檢查該類大小的chunk還有沒有空閑的,如果沒有,將會申請1M(1個slab)的空間并劃分為該種類chunk。例如我們第一次向memcached中放入一個190字節(jié)的item時,memcached會產(chǎn)生一個slab class 2(也叫一個page),并會用去一個chunk,剩余5241個chunk供下次有適合大小item時使用,當(dāng)我們用完這所有的5242個chunk之后,下次再有一個在160~200字節(jié)之間的item添加進(jìn)來時,memcached會再次產(chǎn)生一個class 5的slab(這樣就存在了2個pages)。查看slab的使用情況,我們可以telnet ip port,然后輸入命令 stats slabs即可:
例如:telnet 10.0.4.210 11211
stats slabs ???????? STAT 5:chunk_size 200 ???????? STAT 5:chunks_per_page 5242 ???????? STAT 5:total_pages 1 ???????? STAT 5:total_chunks 5242 ???????? STAT 5:used_chunks 5242 ???????? STAT 5:free_chunks 0 ???????? STAT 5:free_chunks_end 5241 ???????? STAT active_slabs 1 ???????? STAT total_malloced 1048400 |
圖3 stats slab
圖3顯示的是第一次放入一個190字節(jié)的item之后的統(tǒng)計結(jié)果。
轉(zhuǎn)載于:https://my.oschina.net/wuxianAbs/blog/220936
總結(jié)
以上是生活随笔為你收集整理的Memcached 内存管理(一)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 大数据时代的移动即时通讯
- 下一篇: 毕业两年返校随想