Memcached那些事

#Memcached那些事 本文不是爲了介紹Memcached是什麼,而是討論在使用Memcached的時候你必須知道的一些事情。以便於方便排查和更好的使用Memcached。本文主要圍繞兩個方面來討論這個話題:Memcached的使用和監控。 ##如何更好的使用Memcached 這部分討論的是如何可以合理有效的讓Memcached爲咱們服務,經過什麼方式來調控Memcached,讓它工做的更好。下面進入這部分的內容: ###Memcached如何存儲咱們的數據? 要很好的使用Memcached,那麼必須知道咱們的數據交給Memcached,它是怎麼處理它們的。爲了說明這個,須要先了解幾個名詞:slab class,page,chunk。它們三者之間的關係以下: shell

  1. slab class :memcached會自動根據設置的chunk size以及當前分配給memcached建立一系列slab class,單個slab class中的chunk大小是同樣的,而每一個slab class中的chunk大小根據設置設置的chunk_size*growth_factor^(i-1),其中i表示第幾個slab class(這裏須要注意這裏的chunk_size不僅是item的數據大小,還包含memcached內部的一個item結構體大小,這個值通常是48byte,默認的growth_factor是1.25)。
  2. chunk:能夠理解爲memcached中存儲數據的最小單元,每一個存儲在memcached中的item都會分配一個符合它大小的chunk,chunk的數量決定了memcached存儲item的數量,默認的chunk爲48byte。
  3. page:memcached中的內存是已page爲單位分配給每一個slab class,而後每一個slab class根據它的chunk大小,計算出各自可以存儲的item的數量,默認page大小爲1M。而每一頁可以存放多少個item,這取決於chunk_size的大小。

經過上面能夠看到slab class 1中一個page可以存儲的item數量是最多的,而最後一個slab class一個page只能存儲一個item。這是因爲第一個slab class 1的chunk大小是全部slab class中最小的,那麼對於就致使了slab class 1的可以存儲的item最多了。memcached

memcached這樣作的好處什麼呢?memcached這樣作將數據存儲根據可以存儲的大小歸爲幾類,而且內存按照固定的大小來劃分。相比於隨機分配內存大小,致使內存碎片難於回收來講,這種內存方案對內存的利用率更高,並且便於管理。這就是memcached的slab allocation。fetch

對於memcached來講,若是一個item申請寫入數據,會計算當前item的大小而後加上memcached的item結構體大小,判斷具體是存儲在哪一個slab class上面。判斷的條件是item_size+item_structure_size<=某個slab class上的chunk大小。以上面的圖來講,好比我須要寫入一個54byte的數據(key+value),因爲memcached的item結構體大小是48,那麼memcached對於這個item須要寫入的總數據大小是100byte,因而就會寫入slab class2的某個chunk裏面。因而就會存在下面的狀況:優化

因爲slab class2的chunk大小是112byte,那麼寫入100byte數據,就會有12byte空間浪費。這就是下一個話題,如何可以讓memcached充分使用內存。 ###讓Memcached充分使用內存。 上面列舉的例子能夠看出如何chunk大小設置不合適會致使內存空間的浪費,如何讓memcached合理的使用內存呢?下面將介紹設置哪些參數來達到根據具體的業務合理的使用內存。線程

  1. 經過上面能夠知道,slab class 1中可以存儲的item數量是全部slab class中最多的,那麼若是可以調整slab class 1的chunk大小,就可以提升memcached存儲的數據量,而且對內存的利用率也有很大的提升。能夠經過在memcached的啓動參數-n來設置的slab class 1的chunk大小。因爲後面的slab class都是在這個基礎上遞增,那麼其實的slab class的chunk大小比較重要。好比你發現大家的業務存入memcached都是100byte的大小數據,那麼能夠將起始slab class的chunk設置爲148byte(還要加上48byte的item結構體大小),例如memcached -n 148。這樣就能夠將數據基本上都會分佈在slab class 1上面,並且在每一頁上面可以建立的chunk數量也是最大的。
  2. 上面說經過調整slab class 1的chunk大小來提供可以存儲的item數量,那麼只是對於item大小比較固定的狀況。若是對於item大小存在差別的時候呢?那麼能夠經過設置growth_factor來控制後面的slab class中chunk遞增的速度,能夠控制slab class中chunk大小變化幅度,來提升memcached的利用率。好比你如今的數據基本上在100-200byte之間,若是讓這些數據所有存儲在slab class 1那麼有些item會只是佔用chunk中的一半,這樣對內存浪費比較大。因此能夠條件growth_factor大小,來控制整個chunk大小在slab class遞增的速度。能夠經過啓動參數-f來指定growth_factor大小,好比memcached -f 1.01 -n 100 (growth_factor值必須大於1)這樣可讓memcached在chunk爲100的基礎上增加速度比較緩慢,可以有多個slab class的chunk大小分佈在100-200byte之間。具體設置什麼,能夠根據你的業務或者必定的公式來得到這個值。
  3. 除了上面幾個參數以外,能夠調節頁面的大小,以及分配給memcached的總內存大小來控制memcached分配內存的策略。經過啓動參數-m調節memcached總內存大小,以及-I調節頁面的大小。

##監控Memcached 如何監控memcached內存使用狀況,以及每一個slab classs當前狀態這個對優化memcached也是一種重要的手段。memcached自身提供了對它監控的手段,也很簡單。能夠經過telnet連接到memcached便可查看當前的memcached。下面是在我本機上經過telnet觀察memcached的一個實例,下面主要是對返回的幾個參數進行說明。code

<!--lang:shell-->
dev@codinglife:~$ telnet localhost 11211
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
stats items
STAT items:1:number 64708
STAT items:1:age 32067
STAT items:1:evicted 0
STAT items:1:evicted_nonzero 0
STAT items:1:evicted_time 0
STAT items:1:outofmemory 0
STAT items:1:tailrepairs 0
STAT items:1:reclaimed 32828
STAT items:1:expired_unfetched 29979
STAT items:1:evicted_unfetched 0
END
stats slabs
STAT 1:chunk_size 688
STAT 1:chunks_per_page 1524
STAT 1:total_pages 43
STAT 1:total_chunks 65532
STAT 1:used_chunks 64708
STAT 1:free_chunks 824
STAT 1:free_chunks_end 0
STAT 1:mem_requested 5888428
STAT 1:get_hits 0
STAT 1:cmd_set 101909
STAT 1:delete_hits 0
STAT 1:incr_hits 0
STAT 1:decr_hits 0
STAT 1:cas_hits 0
STAT 1:cas_badval 0
STAT 1:touch_hits 0
STAT active_slabs 1
STAT total_malloced 45086016
END

上面主要執行了兩個命令,一個是stats items和stats slabs。stats items是對當前memcached當前存儲的item進行一個統計,能夠看到item的數量,一些item的一些狀態,好比是否有item被移除,是否有超時等,注意上面更在STAT items後面的數字表示是在第幾個slab class上,上面表示數據都是在slab class 1上面。而stats slabs是觀察各個slab class的狀況,好比某個slab class使用了多少page,當前slab class的chunk_size,以及使用了多少個chunk,剩餘多少chunk,以及內存的使用狀況,同時能夠看到整個memcached但錢有多少個slab class處於使用激活狀態,以及總共使用了多少內存,重要的是能夠看到某個slab class對數據的操做歷史累計統計(好比get_hits,cmd_set,delete_hits等等),從而能夠看到哪一個slab class存儲的數據是熱點數據,從而能夠更具上面的方法調整memcached參數,來提升memcached對內存的使用狀況。內存

上面主要是對memcached使用內存方面調優的參數以及對memcached運行狀態的監控進行了討論,這二者實際上是一個相互反饋的過程。經過調整好了memcached相關參數,監控一下memcached運行狀況,是否達到預期的效果,從而再對memcached進行調整,再進行監控。只有反覆進行調整才能將memcached對內存方面的使用達到最佳的效果。固然能夠經過其餘參數對memcached進行其餘方面的調整,否則可以支持的最大鏈接數量,處理請求的線程數量等,來提升memcached的總體處理能力。因爲不是本文討論的主題,因此這裏就不作過多的描述,具體有哪些參數能夠經過memcached -h來獲取全部參數列表。get

相關文章
相關標籤/搜索