如圖1所示尿背,當往Memcached寫入500萬的160 Bytes的數(shù)據(jù)項茴晋,內(nèi)存利用率計算:59485199(bytes)/67108864(limit_maxbytes)=89%烁涌。內(nèi)存利用率達到89%時抒钱,從evictions看到MC主動踢出很多緩存數(shù)據(jù)早芭,為什么MC達到90%的內(nèi)存利用率時開始踢出緩存數(shù)據(jù)?
要分析原因刀荒,我們首先要了解下Slab Allocation機制,可參考理解memcached的內(nèi)存存儲。
從圖2 growth factor=1.25的Slab Allocation看到拱绑,160 Bytes的數(shù)據(jù)項選擇192 Bytes的chunk,浪費32 Bytes內(nèi)存虾啦。雖然Slab Allocation解決了malloc/free固有的內(nèi)存碎片問題丁眼,卻不能有效利用分配到的內(nèi)存。
我們計算每個chunk的期望內(nèi)存利用率:
120B的chunk放置的數(shù)據(jù)項期望長度是(96+120)/2=108,期望的內(nèi)存利用率為108/120=90%;
152B的chunk放置的數(shù)據(jù)項期望長度是(120+152)/2=136,期望的內(nèi)存利用率為136/152=89%;
......
n B的chunk放置的數(shù)據(jù)項期望長度是(n/1.25+n)/2=9n/10摘盆,期望的內(nèi)存利用率為9n/10/n=90%;
所以狈邑,內(nèi)存利用率到90%就意味growth factor=1.25的MC內(nèi)存已經(jīng)放滿數(shù)據(jù)赤炒,在沒有過期數(shù)據(jù)的情況下,保存新數(shù)據(jù)只能淘汰LRU(Least Recent Used)的數(shù)據(jù)宴凉。
推廣到任意growth factor(gf)温治,n Bytes的chunk放置的數(shù)據(jù)項期望長度是(n/gf+n)/2=(1+gf)n/(2*gf)捏顺,期望的內(nèi)存利用率為(1+gf)/(2*gf)主巍,比如:
gf=1.25搞旭,期望的內(nèi)存利用率為90%;
gf=2,期望的內(nèi)存利用率為75%;
.......
極端情況具伍,gf=1啼肩,期望的內(nèi)存利用率為100%芬沉,但是growth factor必須大于1捎谨,否則會如圖3的報錯畏邢。
那是不是說growth factor接近1交煞,期望的內(nèi)存利用率就能接近100%素征?結(jié)果出人意料。
在分配64M內(nèi)存的MC中酥泛,growth factor=1.000001捶索,如圖4璃弄、圖5所示垦梆,1~199個Slab class的chunk size為96 Bytes托猩,第200個Slab class的chunk size為1MB印蓖。
當growth factor=1.000001,往64M內(nèi)存MC插入163 Bytes的數(shù)據(jù)項京腥,如圖6和圖7所示赦肃,內(nèi)存利用率:bytes(10432)/limit_maxbytes(67108864)=0.01%,趨近于0公浪。163 Bytes的數(shù)據(jù)項不能放入到96 Bytes的chunk他宛,只能放到slab class 200的64MB的chunk,幾乎浪費64M所有的空間欠气,總共寫入163 Bytes * 64=10432 Bytes的數(shù)據(jù)厅各。從這個例子看出,growth factor不能趨近與1预柒,否則內(nèi)存利用率趨近于0队塘。但是growth factor也不能太大,否則內(nèi)存利用率也會很低宜鸯。
實踐經(jīng)驗表明人灼,growth factor最好介于1.05~2之間,并且根據(jù)業(yè)務緩存數(shù)據(jù)塊大小而定顾翼。