[Memcached] Slab鈣化問(wèn)題

引子

Memcached采用LRU(Least Recent Used)淘汰算法,在內(nèi)存容量滿(mǎn)時(shí)踢出過(guò)期失效和LRU數(shù)據(jù),為新數(shù)據(jù)騰出內(nèi)存空間。不過(guò)該淘汰算法在內(nèi)存空間不足以分配新的Slab情況下,這時(shí)只會(huì)在同一類(lèi)Slab內(nèi)部踢出數(shù)據(jù)。即當(dāng)某個(gè)Slab容量滿(mǎn),且不能在內(nèi)存足夠分配新的Slab,只會(huì)在相同Slab內(nèi)部踢出數(shù)據(jù),而不會(huì)挪用或者踢出其他Slab的數(shù)據(jù)。這種局部剔除數(shù)據(jù)的淘汰算法帶來(lái)一個(gè)問(wèn)題:Slab鈣化。

實(shí)踐

1 搭建一個(gè)64M、growth factor=1.25的MC節(jié)點(diǎn)。

2 用item數(shù)據(jù)寫(xiě)滿(mǎn)MC 192B的chunk,因?yàn)橐呀?jīng)有evicted數(shù)量,所以192B chunk肯定已經(jīng)寫(xiě)滿(mǎn),如圖1所示。

圖1 memcached-tool結(jié)果

3 計(jì)算內(nèi)存利用率:bytes(59066176)/limit_maxbytes(67108864)=88%,已經(jīng)達(dá)到growth factor=1.25的期望內(nèi)存利用率,MC期望內(nèi)存利用率計(jì)算方法請(qǐng)參考拙作《期望內(nèi)存利用率計(jì)算方法》,所以?xún)?nèi)存已滿(mǎn),如圖2所示。

圖2 stats結(jié)果

4 flush_all刪除所有數(shù)據(jù),從圖3看item仍占用192B的chunk size,MC刪除機(jī)制是數(shù)據(jù)不會(huì)真正從內(nèi)存中消失,只要被其他數(shù)據(jù)覆蓋,MC不會(huì)主動(dòng)刪除Slab chunk已存在的數(shù)據(jù)。

圖3 memcached-tool結(jié)果

5 再用5萬(wàn)個(gè)96B的item寫(xiě)入MC,一共寫(xiě)50000*96B/1024/1024=4M數(shù)據(jù),遠(yuǎn)遠(yuǎn)小于64M,但是只能寫(xiě)入96B*10922=1MB,即只能寫(xiě)一個(gè)Page,還是有很多96B的item被Evicted,如圖4所示。

即使192B的chunk數(shù)據(jù)已經(jīng)被清除,MC淘汰策略是淘汰相同的Slab class數(shù)據(jù),96B的item也不會(huì)重新使用192B的chunk size,只會(huì)使用原有啟動(dòng)Memcached時(shí)分配的1MB Slab class(Chunk size 96B),這就是所謂的Slab鈣化問(wèn)題。

圖4 memcached-tool結(jié)果

Slab鈣化可以解釋這個(gè)問(wèn)題:為什么我寫(xiě)入比較新的數(shù)據(jù),但被淘汰了

假設(shè)Slab有各種規(guī)格(64~ 1M字節(jié)),比如應(yīng)用存入的大部分?jǐn)?shù)據(jù)大小在 64 ~ 128 字節(jié)范圍內(nèi),那么這些數(shù)據(jù)會(huì)存儲(chǔ)在128個(gè)字節(jié)大小的Slab chunk中,這些Slab chunk以鏈表的方式連接在一起。當(dāng)已經(jīng)沒(méi)有空余的內(nèi)存分配新的Slab,如果這時(shí)候?qū)懭?0K新數(shù)據(jù),且之前并沒(méi)有這么大的數(shù)據(jù)寫(xiě)入時(shí),那么這條新數(shù)據(jù)可以寫(xiě)入成功。但是當(dāng)下次再寫(xiě)入10K數(shù)據(jù)時(shí),第一次寫(xiě)入的10K數(shù)據(jù)就會(huì)被逐出。當(dāng)下一次寫(xiě)入的新數(shù)據(jù)在64 ~ 128字節(jié)時(shí),128字節(jié)大小的Slab鏈表上的數(shù)據(jù)會(huì)以L(fǎng)RU方式淘汰,所以L(fǎng)RU只會(huì)淘汰同一級(jí)別的Slab數(shù)據(jù)。

Slab鈣化降低內(nèi)存使用率,如果發(fā)生Slab鈣化,有三種解決方案:

1) 重啟Memcached實(shí)例,簡(jiǎn)單粗暴,啟動(dòng)后重新分配Slab class,但是如果是單點(diǎn)可能造成大量請(qǐng)求訪(fǎng)問(wèn)數(shù)據(jù)庫(kù),出現(xiàn)雪崩現(xiàn)象,沖跨數(shù)據(jù)庫(kù)。

2) 隨機(jī)過(guò)期:過(guò)期淘汰策略也支持淘汰其他slab class的數(shù)據(jù),twitter工程師采用隨機(jī)選擇一個(gè)Slab,釋放該Slab的所有緩存數(shù)據(jù),然后重新建立一個(gè)合適的Slab。

3) 通過(guò)slab_reassign、slab_authmove參數(shù)控制。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容