Memcached那些事

jopen 9年前發布 | 12K 次閱讀 緩存服務器 memcached

Memcached那些事

本文不是為了介紹Memcached是什么,而是討論在使用Memcached的時候你必須知道的一些事情。以便于方便排查和更好的使用Memcached。本文主要圍繞兩個方面來討論這個話題:Memcached的使用和監控。

如何更好的使用Memcached

這部分討論的是如何能夠合理有效的讓Memcached為我們服務,通過什么方式來調控Memcached,讓它工作的更好。下面進入這部分的內容:

Memcached如何存儲我們的數據?

要很好的使用Memcached,那么必須知道我們的數據交給Memcached,它是怎么處理它們的。為了說明這個,需要先了解幾個名詞:slab class,page,chunk。它們三者之間的關系如下: Memcached那些事

  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的大小。
  4. </ol>

    通過上面可以看到slab class 1中一個page能夠存儲的item數量是最多的,而最后一個slab class一個page只能存儲一個item。這是由于第一個slab class 1的chunk大小是所有slab class中最小的,那么對于就導致了slab class 1的能夠存儲的item最多了。

    memcached這樣做的好處什么呢?memcached這樣做將數據存儲根據能夠存儲的大小歸為幾類,并且內存按照固定的大小來劃分。相比于隨 機分配內存大小,導致內存碎片難于回收來說,這種內存方案對內存的利用率更高,而且便于管理。這就是memcached的slab allocation。

    對于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里面。于是就會存在下面的情況:

    Memcached那些事

    由于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調節頁面的大小。
    4. </ol>

      監控Memcached

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

      <!--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來獲取所有參數列表。

      來自:http://my.oschina.net/bieber/blog/505458

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!