一直在使用Memcache,但是對(duì)其內(nèi)部的問(wèn)題,如它內(nèi)存是怎么樣被使用的,使用一段時(shí)間后想看看一些狀態(tài)怎么樣?一直都不清楚,查了又忘記,現(xiàn)在整理出該篇文章,方便自己查閱。本文不涉及安裝、操作。有興趣的同學(xué)可以查看之前寫的文章和Google。
創(chuàng)新互聯(lián)是一家集網(wǎng)站建設(shè),寧明企業(yè)網(wǎng)站建設(shè),寧明品牌網(wǎng)站建設(shè),網(wǎng)站定制,寧明網(wǎng)站建設(shè)報(bào)價(jià),網(wǎng)絡(luò)營(yíng)銷,網(wǎng)絡(luò)優(yōu)化,寧明網(wǎng)站推廣為一體的創(chuàng)新建站企業(yè),幫助傳統(tǒng)企業(yè)提升企業(yè)形象加強(qiáng)企業(yè)競(jìng)爭(zhēng)力??沙浞譂M足這一群體相比中小企業(yè)更為豐富、高端、多元的互聯(lián)網(wǎng)需求。同時(shí)我們時(shí)刻保持專業(yè)、時(shí)尚、前沿,時(shí)刻以成就客戶成長(zhǎng)自我,堅(jiān)持不斷學(xué)習(xí)、思考、沉淀、凈化自己,讓我們?yōu)楦嗟钠髽I(yè)打造出實(shí)用型網(wǎng)站。1:參數(shù)
memcached -h memcached 1.4.14-pTCP端口,默認(rèn)為11211,可以不設(shè)置-U UDP端口,默認(rèn)為11211,0為關(guān)閉-s UNIX socket-a access mask for UNIX socket, in octal (default: 0700)-l 監(jiān)聽(tīng)的 IP 地址,本機(jī)可以不設(shè)置此參數(shù)-d 以守護(hù)程序(daemon)方式運(yùn)行-u 指定用戶,如果當(dāng)前為 root ,需要使用此參數(shù)指定用戶-m 大內(nèi)存使用,單位MB。默認(rèn)64MB-M 禁止LRU策略,內(nèi)存耗盡時(shí)返回錯(cuò)誤,而不是刪除項(xiàng)-c 大同時(shí)連接數(shù),默認(rèn)是1024-v verbose (print errors/warnings while in event loop)-vv very verbose (also print client commands/reponses)-vvv extremely verbose (also print internal state transitions)-h 幫助信息-i print memcached and libevent license-P 保存PID到指定文件-f 增長(zhǎng)因子,默認(rèn)1.25-n 初始chunk=key+suffix+value+32結(jié)構(gòu)體,默認(rèn)48字節(jié)-L 啟用大內(nèi)存頁(yè),可以降低內(nèi)存浪費(fèi),改進(jìn)性能-t 線程數(shù),默認(rèn)4。由于memcached采用NIO,所以更多線程沒(méi)有太多作用-R 每個(gè)event連接大并發(fā)數(shù),默認(rèn)20-C 禁用CAS命令(可以禁止版本計(jì)數(shù),減少開(kāi)銷)-b Set the backlog queue limit (default: 1024)-B Binding protocol-one of ascii, binary or auto (default)-I 調(diào)整分配slab頁(yè)的大小,默認(rèn)1M,最小1k到128M
上面加粗的參數(shù),需要重點(diǎn)關(guān)注,正常啟動(dòng)的例子:
啟動(dòng):/usr/bin/memcached -m 64 -p 11212 -u nobody -c 2048 -f 1.1 -I 1024 -d -l 10.211.55.9連接:telnet 10.211.55.9 11212Trying 10.211.55.9...
Connected to 10.211.55.9.
Escape character is '^]'.
可以通過(guò)命令查看所有參數(shù):stats settings
2:理解memcached的內(nèi)存存儲(chǔ)機(jī)制
Memcached默認(rèn)情況下采用了名為Slab Allocator的機(jī)制分配、管理內(nèi)存。在該機(jī)制出現(xiàn)以前,內(nèi)存的分配是通過(guò)對(duì)所有記錄簡(jiǎn)單地進(jìn)行malloc和free來(lái)進(jìn)行的。但是,這種方式會(huì)導(dǎo)致內(nèi)存碎片,加重操作系統(tǒng)內(nèi)存管理器的負(fù)擔(dān),最壞的情況下,會(huì)導(dǎo)致操作系統(tǒng)比memcached進(jìn)程本身還慢。Slab Allocator就是為解決該問(wèn)題而誕生的。
Slab Allocator的基本原理是按照預(yù)先規(guī)定的大小,將分配的內(nèi)存以page為單位,默認(rèn)情況下一個(gè)page是1M,可以通過(guò)-I參數(shù)在啟動(dòng)時(shí)指定,分割成各種尺寸的塊(chunk), 并把尺寸相同的塊分成組(chunk的集合),如果需要申請(qǐng)內(nèi)存時(shí),memcached會(huì)劃分出一個(gè)新的page并分配給需要的slab區(qū)域。page一旦被分配在重啟前不會(huì)被回收或者重新分配,以解決內(nèi)存碎片問(wèn)題。
Page
分配給Slab的內(nèi)存空間,默認(rèn)是1MB。分配給Slab之后根據(jù)slab的大小切分成chunk。
Chunk
用于緩存記錄的內(nèi)存空間。
Slab Class
特定大小的chunk的組。
Memcached并不是將所有大小的數(shù)據(jù)都放在一起的,而是預(yù)先將數(shù)據(jù)空間劃分為一系列slabs,每個(gè)slab只負(fù)責(zé)一定范圍內(nèi)的數(shù)據(jù)存儲(chǔ)。memcached根據(jù)收到的數(shù)據(jù)的大小,選擇最適合數(shù)據(jù)大小的slab。memcached中保存著slab內(nèi)空閑chunk的列表,根據(jù)該列表選擇chunk,然后將數(shù)據(jù)緩存于其中。
如圖所示,每個(gè)slab只存儲(chǔ)大于其上一個(gè)slab的size并小于或者等于自己大size的數(shù)據(jù)。例如:100字節(jié)大小的字符串會(huì)被存到slab2(88-112)中,每個(gè)slab負(fù)責(zé)的空間是不等的,memcached默認(rèn)情況下下一個(gè)slab的大值為前一個(gè)的1.25倍,這個(gè)可以通過(guò)修改-f參數(shù)來(lái)修改增長(zhǎng)比例。
Slab Allocator解決了當(dāng)初的內(nèi)存碎片問(wèn)題,但新的機(jī)制也給memcached帶來(lái)了新的問(wèn)題。chunk是memcached實(shí)際存放緩存數(shù)據(jù)的地方,這個(gè)大小就是管理它的slab的大存放大小。每個(gè)slab中的chunk大小是一樣的,如上圖所示slab1的chunk大小是88字節(jié),slab2是112字節(jié)。由于分配的是特定長(zhǎng)度的內(nèi)存,因此無(wú)法有效利用分配的內(nèi)存。例如,將100字節(jié)的數(shù)據(jù)緩存到128字節(jié)的chunk中,剩余的28字節(jié)就浪費(fèi)了。這里需要注意的是chunk中不僅僅存放緩存對(duì)象的value,而且保存了緩存對(duì)象的key,expire time, flag等詳細(xì)信息。所以當(dāng)set 1字節(jié)的item,需要遠(yuǎn)遠(yuǎn)大于1字節(jié)的空間存放。
memcached在啟動(dòng)時(shí)指定 Growth Factor因子(通過(guò)-f選項(xiàng)), 就可以在某種程度上控制slab之間的差異。默認(rèn)值為1.25。
slab的內(nèi)存分配具體過(guò)程如下:
Memcached在啟動(dòng)時(shí)通過(guò)-m參數(shù)指定大使用內(nèi)存,但是這個(gè)不會(huì)一啟動(dòng)就占用完,而是逐步分配給各slab的。如果一個(gè)新的數(shù)據(jù)要被存放,首先選擇一個(gè)合適的slab,然后查看該slab是否還有空閑的chunk,如果有則直接存放進(jìn)去;如果沒(méi)有則要進(jìn)行申請(qǐng),slab申請(qǐng)內(nèi)存時(shí)以page為單位,無(wú)論大小為多少,都會(huì)有1M大小的page被分配給該slab(該page不會(huì)被回收或者重新分配,永遠(yuǎn)都屬于該slab)。申請(qǐng)到page后,slab會(huì)將這個(gè)page的內(nèi)存按chunk的大小進(jìn)行切分,這樣就變成了一個(gè)chunk的數(shù)組,再?gòu)倪@個(gè)chunk數(shù)組中選擇一個(gè)用于存儲(chǔ)數(shù)據(jù)。若沒(méi)有空閑的page的時(shí)候,則會(huì)對(duì)改slab進(jìn)行LRU,而不是對(duì)整個(gè)memcache進(jìn)行LRU。
以上大致講解了memcache的內(nèi)存分配策略,下面來(lái)說(shuō)明如何查看memcache的使用狀況。
3,memcache狀態(tài)和性能查看
① 命中率 :stats命令
按照下面的圖來(lái)解讀分析
get_hits表示讀取cache命中的次數(shù),get_misses是讀取失敗的次數(shù),即嘗試讀取不存在的緩存數(shù)據(jù)。即:
命中率=get_hits / (get_hits + get_misses)
命中率越高說(shuō)明cache起到的緩存作用越大。但是在實(shí)際使用中,這個(gè)命中率不是有效數(shù)據(jù)的命中率,有些時(shí)候get操作可能只是檢查一個(gè)key存在不存在,這個(gè)時(shí)候miss也是正確的,這個(gè)命中率是從memcached啟動(dòng)開(kāi)始所有的請(qǐng)求的綜合值,不能反映一個(gè)時(shí)間段內(nèi)的情況,所以要排查memcached的性能問(wèn)題,還需要更詳細(xì)的數(shù)值。但是高的命中率還是能夠反映出memcached良好的使用情況,突然下跌的命中率能夠反映大量cache丟失的發(fā)生。
② 觀察各slab的items的情況:Stats items命令
主要參數(shù)說(shuō)明:
outofmemory | slab class為新item分配空間失敗的次數(shù)。這意味著你運(yùn)行時(shí)帶上了-M或者移除操作失敗 |
number | 存放的數(shù)據(jù)總數(shù) |
age | 存放的數(shù)據(jù)中存放時(shí)間最久的數(shù)據(jù)已經(jīng)存在的時(shí)間,以秒為單位 |
evicted | 不得不從LRU中移除未過(guò)期item的次數(shù) |
evicted_time | 自最后一次清除過(guò)期item起所經(jīng)歷的秒數(shù),即最后被移除緩存的時(shí)間,0表示當(dāng)前就有被移除,用這個(gè)來(lái)判斷數(shù)據(jù)被移除的最近時(shí)間 |
evicted_nonzero | 沒(méi)有設(shè)置過(guò)期時(shí)間(默認(rèn)30天),但不得不從LRU中稱除該未過(guò)期的item的次數(shù) |
因?yàn)閙emcached的內(nèi)存分配策略導(dǎo)致一旦memcached的總內(nèi)存達(dá)到了設(shè)置的大內(nèi)存,表示所有的slab能夠使用的page都已經(jīng)固定,這時(shí)如果還有數(shù)據(jù)放入,將導(dǎo)致memcached使用LRU策略剔除數(shù)據(jù)。而LRU策略不是針對(duì)所有的slabs,而是只針對(duì)新數(shù)據(jù)應(yīng)該被放入的slab,例如有一個(gè)新的數(shù)據(jù)要被放入slab 3,則LRU只對(duì)slab 3進(jìn)行,通過(guò)stats items就可以觀察到這些剔除的情況。
注意evicted_time:并不是發(fā)生了LRU就代表memcached負(fù)載過(guò)載了,因?yàn)橛行r(shí)候在使用cache時(shí)會(huì)設(shè)置過(guò)期時(shí)間為0,這樣緩存將被存放30天,如果內(nèi)存滿了還持續(xù)放入數(shù)據(jù),而這些為過(guò)期的數(shù)據(jù)很久沒(méi)有被使用,則可能被剔除。把evicted_time換算成標(biāo)準(zhǔn)時(shí)間看下是否已經(jīng)達(dá)到了你可以接受的時(shí)間,例如:你認(rèn)為數(shù)據(jù)被緩存了2天是你可以接受的,而最后被剔除的數(shù)據(jù)已經(jīng)存放了3天以上,則可以認(rèn)為這個(gè)slab的壓力其實(shí)可以接受的;但是如果最后被剔除的數(shù)據(jù)只被緩存了20秒,不用考慮,這個(gè)slab已經(jīng)負(fù)載過(guò)重了。
通過(guò)上面的說(shuō)明可以看到當(dāng)前的memcache的slab1的狀態(tài):
items有305816個(gè),有效時(shí)間最久的是21529秒,通過(guò)LRU移除未過(guò)期的items有95336839個(gè),通過(guò)LRU移除沒(méi)有設(shè)置過(guò)期時(shí)間的未過(guò)期items有95312220個(gè),當(dāng)前就有被清除的items,啟動(dòng)時(shí)沒(méi)有帶-M參數(shù)。
③ 觀察各slabs的情況:stats slabs命令
從Stats items中如果發(fā)現(xiàn)有異常的slab,則可以通過(guò)stats slabs查看下該slab是不是內(nèi)存分配的確有問(wèn)題。
主要參數(shù)說(shuō)明:
屬性名稱 | 屬性說(shuō)明 |
---|---|
chunk_size | 當(dāng)前slab每個(gè)chunk的大小 |
chunk_per_page | 每個(gè)page能夠存放的chunk數(shù) |
total_pages | 分配給當(dāng)前slab的page總數(shù),默認(rèn)1個(gè)page大小1M,可以計(jì)算出該slab的大小 |
total_chunks | 當(dāng)前slab最多能夠存放的chunk數(shù),應(yīng)該等于chunck_per_page * total_page |
used_chunks | 已經(jīng)被占用的chunks總數(shù) |
free_chunks | 過(guò)期數(shù)據(jù)空出的chunk但還沒(méi)有被使用的chunk數(shù) |
free_chunks_end | 新分配的但是還沒(méi)有被使用的chunk數(shù) |
這里需要注意:total_pages 這個(gè)是當(dāng)前slab總共分配大的page總數(shù),如果沒(méi)有修改page的默認(rèn)大小的情況下,這個(gè)數(shù)值就是當(dāng)前slab能夠緩存的數(shù)據(jù)的總大?。▎挝粸镸)。如果這個(gè)slab的剔除非常嚴(yán)重,一定要注意這個(gè)slab的page數(shù)是不是太少了。還有一個(gè)公式:
total_chunks = used_chunks + free_chunks + free_chunks_end
另外stats slabs還有2個(gè)屬性:
屬性名稱 | 屬性說(shuō)明 |
active_slabs | 活動(dòng)的slab總數(shù) |
total_malloced | 實(shí)際已經(jīng)分配的總內(nèi)存數(shù),單位為byte,這個(gè)數(shù)值決定了memcached實(shí)際還能申請(qǐng)多少內(nèi)存,如果這個(gè)值已經(jīng)達(dá)到設(shè)定的上限(和stats settings中的maxbytes對(duì)比),則不會(huì)有新的page被分配。 |
④ 對(duì)象數(shù)量的統(tǒng)計(jì):stats sizes
注意:該命令會(huì)鎖定服務(wù),暫停處理請(qǐng)求。該命令展示了固定chunk大小中的items的數(shù)量。也可以看出slab1(96byte)中有多少個(gè)chunks。
⑤ 查看、導(dǎo)出key:stats cachedump
在進(jìn)入memcache中,大家都想查看cache里的key,類似redis中的keys *命令,在memcache里也可以查看,但是需要2步完成。
一是先列出items:
stats items --命令...
...
STAT items:29:number 228STAT items:29:age 34935...
END
二是通過(guò)itemid取key,上面的id是29,再加上一個(gè)參數(shù):為列出的長(zhǎng)度,0為全部列出。
stats cachedump 29 0 --命令I(lǐng)TEM 26457202 [49440 b; 1467262309 s]
...
ITEM 30017977 [45992 b; 1467425702 s]
ITEM 26634739 [48405 b; 1467437677 s]
END --總共228個(gè)keyget 26634739 取value
如何導(dǎo)出key呢?這里就需要通過(guò) echo ... nc 來(lái)完成了
echo "stats cachedump 29 0" | nc 10.211.55.9 11212 >/home/zhoujy/memcache.log
在導(dǎo)出的時(shí)候需要注意的是:cachedump命令每次返回的數(shù)據(jù)大小只有2M,這個(gè)是memcached的代碼中寫死的一個(gè)數(shù)值,除非在編譯前修改。
⑥ 另一個(gè)監(jiān)控工具:memcached-tool,一個(gè)perl寫的工具:memcache_tool.pl。
View Code
./memcached-tool 10.211.55.9:11212 --執(zhí)行
# Item_Size Max_age Pages Count Full? Evicted Evict_Time OOM
1 96B 20157s 28 305816 yes 95431913 0 0
2 120B 16049s 40 349520 yes 117041737 0 0
3 152B 17574s 39 269022 yes 92679465 0 0
4 192B 18157s 43 234823 yes 78892650 0 0
5 240B 18722s 52 227188 yes 72908841 0 0
6 304B 17971s 73 251777 yes 85556469 0 0
7 384B 17881s 81 221130 yes 75596858 0 0
8 480B 17760s 70 152880 yes 53553607 0 0
9 600B 18167s 58 101326 yes 34647962 0 0
10 752B 18518s 52 72488 yes 24813707 0 0
11 944B 18903s 52 57720 yes 16707430 0 0
12 1.2K 20475s 44 38940 yes 11592923 0 0
13 1.4K 21220s 36 25488 yes 8232326 0 0
14 1.8K 22710s 35 19740 yes 6232766 0 0
15 2.3K 22027s 33 14883 yes 4952017 0 0
16 2.8K 23139s 33 11913 yes 3822663 0 0
17 3.5K 23495s 31 8928 yes 2817520 0 0
18 4.4K 22611s 29 6670 yes 2168871 0 0
19 5.5K 23652s 29 5336 yes 1636656 0 0
20 6.9K 21245s 26 3822 yes 1334189 0 0
21 8.7K 22794s 22 2596 yes 783620 0 0
22 10.8K 22443s 19 1786 yes 514953 0 0
23 13.6K 21385s 18 1350 yes 368016 0 0
24 16.9K 23782s 16 960 yes 254782 0 0
25 21.2K 23897s 14 672 yes 183793 0 0
26 26.5K 27847s 13 494 yes 117535 0 0
27 33.1K 27497s 14 420 yes 83966 0 0
28 41.4K 28246s 14 336 yes 63703 0 0
29 51.7K 33636s 12 228 yes 24239 0 0
解釋:
列 | 含義 |
# | slab class編號(hào) |
Item_Size | chunk大小 |
Max_age | LRU內(nèi)最舊的記錄的生存時(shí)間 |
pages | 分配給Slab的頁(yè)數(shù) |
count | Slab內(nèi)的記錄數(shù)、chunks數(shù)、items數(shù)、keys數(shù) |
Full? | Slab內(nèi)是否含有空閑chunk |
Evicted | 從LRU中移除未過(guò)期item的次數(shù) |
Evict_Time | 最后被移除緩存的時(shí)間,0表示當(dāng)前就有被移除 |
OOM | -M參數(shù)? |
另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無(wú)理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國(guó)服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡(jiǎn)單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場(chǎng)景需求。