內存分配機制
mc內存分配機制簡介
memcached默認情況下采用了名爲Slab Allocator的機制分配、管理內存,Slab Allocator的基本原理是按照預先規定的大小,將分配的內存分割成特定長度的塊,以完全解決內存碎片問題。
先來解釋一下與Slab Allocator存儲有關的幾個術語:
Page:分配給Slab的內存空間,默認是1MB。分配給Slab之後根據slab的大小切分成chunk。Chunk:用於緩存記錄的內存空間。Slab Class:特定大小的chunk的組。
Growth Factor:增長因數,默認爲1.25(較早的版本固定爲2)
mc啓動後,會根據這個factor,計算出從1M逐步遞減的不同的slab,如factor=1.25時:
slab class 1: chunk size 88 perslab 11915
slab class 2: chunk size 112 perslab 9362
slab class 3: chunk size 144 perslab 7281
slab class 4: chunk size 184 perslab 5698
slab class 5: chunk size 232 perslab 4519
slab class 6: chunk size 296 perslab 3542
slab class 7: chunk size 376 perslab 2788
slab class 8: chunk size 472 perslab 2221
slab class 9: chunk size 592 perslab 1771
slab class 10: chunk size 744 perslab 1409
第一列數據(slab class),爲slab的編號;
第二列數據是chunk的大小,跟slab class是一一對應的關係,可以通俗的理解爲slab就是存放一組相同大小chunk的集合,只不過這個集合是固定的(1M),
第三列數據,表示每種不同slab中的page可以存放的chunk個數,實際上等於1MB/ (chunk size),例如slab1中的chunk size是88B,那麼這種slab中每個page中可以存放的chunk個數爲 1MB / 88B ,約等於11915
很顯然,slab的chunk size越大,其中的每個page包含的chunk數量就越少
如圖所示:
新入對象時,會根據自身大小來匹配slab列表,比如100KB的對象,根據最小空間損失原則,會被放入到slab2(size:112B)對應的page下,如下圖
這時,如果slab2下的page中有尚可以使用的chunk(即空閒的chunk或者過期的chunk),slab2會優先使用這些chunk,在沒有chunk可用的情況下,mc會去內存中再申請一個page,然後切分成chunk,然後使用;需要注意的是,根據 Slab Allocator算法, 該實例中的100KB對象,是永遠沒有機會存放到其他slab(如slab3,slab4等等),即便是其他slab中有大量的可用chunk,細心的朋友會發現,這種機制很有可能會導致內存浪費嚴重,mc命中率降低等問題,對,這種問題真的存在,這也正是這種機制的缺點,下面會進行詳細的分析和探討
mc數據刪除機制簡介:
首先我們知道,緩存在mc中的數據,不會主動從內存中消失,也就是說mc不會監視記錄是否過期,而是在client端執行get方法時纔去檢查時間戳是否過期(這樣做的目的就是避免在過期監視上耗費cpu資源,以提高mc的響應能力);每次有新對象加入時,mc會優先將對象置於已超時的同一規格chunk中,然而,即使如此,內存仍然會發生追加新記錄時空間不足的情況,那麼,當mc內存耗完後,又是怎樣處理新入的數據呢?mc有兩種處理策略,一種是默認的LRU(Least Recently Used),指刪除近段時間最少使用同規格chunk,再將對象塞入),另一種策略是存滿即不可再存,除非有過期的對象,否則會報錯
一致性哈希原理