文章目錄
第1章 memcached 的內存管理與刪除機制
1.1 內存碎片化
如果用 c 語言直接 malloc,free 來向操作系統申請和釋放內存時,在不斷的申請和釋放過程中,形成了一些很小的內存片斷,無法再利用.這種空閒,但無法利用內存的現象,—稱爲內存的碎片化.
1.2 slab allocator 緩解內存碎片化
memcached 用 slab allocator 機制來管理內存.
slab allocator 原理: 預告把內存劃分成數個 slab class 倉庫.(每個 slab class 大小 1M)各倉庫,切分成不同尺寸的小塊(chunk). (圖 3.2)
需要存內容時,判斷內容的大小,爲其選取合理的倉庫.
1.3 系統如何選擇合適的 chunk?
memcached 根據收到的數據的大小, 選擇最適合數據大小的 chunk 組(slab class)memcached 中保存着 slab class 內空閒 chunk 的列表, 根據該列表選擇空的 chunk, 然後將數據緩存於其中。
警示:如果有 100byte 的內容要存,但 122 大小的倉庫中的 chunk 滿了
並不會尋找更大的,如 144 的倉庫來存儲,
而是把 122 倉庫的舊數據踢掉! 詳見過期與刪除機制
1.4 固定大小 chunk 帶來的內存浪費
由於 slab allocator 機制中, 分配的 chunk 的大小是”固定”的, 因此, 對於特定的 item,可能造成內存空間的浪費.
比如, 將 100 字節的數據緩存到 122 字節的 chunk 中, 剩餘的 22 字節就浪費了
對於 chunk 空間的浪費問題,無法徹底解決,只能緩解該問題.開發者可以對網站中緩存中的 item 的長度進行統計,並制定合理的 slab class 中的 chunk 的大小.
可惜的是,我們目前還不能自定義 chunk 的大小,但可以通過參數來調整各 slab class 中 chunk大小的增長速度. 即增長因子, grow factor!
1.5 grow factor調優
memcached 在啓動時可以通過f 選項指定 Growth Factor 因子, 並在某種程度上控制 slab 之間的差異. 默認值爲 1.25. 但是,在該選項出現之前,這個因子曾經固定爲 2,稱爲”powers of 2” 策略。我們:
#分別用 grow factor 爲 2 和 1.25 來看一看效果
memcached -f 2 -vvv
...
memcached -f 2.5 -vvv
...
#對比可知, 當 f=2 時, 各 slab 中的 chunk size 增長很快,有些情況下就相當浪費內存.因此,我們應細心統計緩存的大小,制定合理的增長因子.
(注意:當 f=1.25 時,從輸出結果來看,某些相鄰的 slab class 的大小比值並非爲 1.25,可能會覺得有些計算誤差,這些誤差是爲了保持字節數的對齊而故意設置的.)
1.6 memcached 的惰性刪除機制
當某個值過期後,並沒有從內存刪除, 因此,stats 統計時, curr_item 有其信息
當某個新值去佔用他的位置時,當成空 chunk 來佔用.
當 get 值時,判斷是否過期,如果過期,返回空,並且清空, curr_item 就減少了.
即–這個過期,只是讓用戶看不到這個數據而已,並沒有在過期的瞬間立即從內存刪除.這個稱爲 lazy expiration, 惰性失效.好處— 節省了 cpu 時間和檢測的成本
1.7 memcached 的lru 刪除機制
如果以 122byte 大小的 chunk 舉例, 122 的 chunk 都滿了, 又有新的值(長度爲 120)要加入, 要 擠掉誰?memcached 此處用的 lru 刪除機制.(操作系統的內存管理,常用 fifo,lru 刪除)
lru: least recently used 最近最少使用 fifo: first in ,first out 原理: 當某個單元被請求時,維護一個計數器,通過計數器來判斷最近誰最少被使用. 就把誰t出.
(注:即使某個 key 是設置的永久有效期,也一樣會被踢出來!
即–永久數據被踢現象)
1.8 memcached 中的一些參數限制
key 的長度: 250 字節, (二進制協議支持 65536 個字節)
value 的限制: 1m, 一般都是存儲一些文本,如新聞列表等等,這個值足夠了.
內存的限制: 32 位下最大設置到 2g.
如果有 30g 數據要緩存,一般也不會單實例裝 30g, (不要把雞蛋裝在一個籃子裏),一般建議 開啓多個實例(可以在不同的機器,或同臺機器上的不同端口)