memcache內存管理

1、memcache啓動參數

memcached -h  
memcached 1.4.20
-p <num>           TCP端口,默認爲11211,可以不設置
-U <num>           UDP端口,默認爲11211,0爲關閉
-s <file>          UNIX socket-a <mask>          access mask for UNIX socket, in octal (default: 0700)
-l <addr>          監聽的 IP 地址,本機可以不設置此參數
-d                 以守護程序(daemon)方式運行
-u                 指定用戶,如果當前爲 root ,需要使用此參數指定用戶
-m <num>           最大內存使用,單位MB。默認64MB
-M                 禁止LRU策略,內存耗盡時返回錯誤,而不是刪除項
-c <num>           最大同時連接數,默認是1024
-v                 verbose (print errors/warnings while in event loop)
-vv                very verbose (also print client commands/reponses)
-vvv               extremely verbose (also print internal state transitions)
-h                 幫助信息
-i                 print memcached and libevent license
-P <file>          保存PID到指定文件
-f <factor>        增長因子,默認1.25
-n <bytes>         初始chunk=key+suffix+value+32結構體,默認48字節
-L                 啓用大內存頁,可以降低內存浪費,改進性能
-t <num>           線程數,默認4。由於memcached採用NIO,所以更多線程沒有太多作用
-R                 每個event連接最大併發數,默認20
-C                 禁用CAS命令(可以禁止版本計數,減少開銷)
-b                 Set the backlog queue limit (default: 1024)
-B                 Binding protocol-one of ascii, binary or auto (default)
-I                 調整分配slab頁的大小,默認1M,最小1k到128M

2、理解memcached的內存存儲機制

2.1分配機制

Memcached默認情況下采用了名爲Slab Allocator的機制分配、管理內存。在該機制出現以前,內存的分配是通過對所有記錄簡單地進行malloc和free來進行的。但是,這種方式會導致內存碎片,加重操作系統內存管理器的負擔,最壞的情況下,會導致操作系統比memcached進程本身還慢。Slab Allocator就是爲解決該問題而誕生的。

Slab Allocator的基本原理是按照預先規定的大小,將分配的內存以page爲單位,默認情況下一個page是1M,可以通過-I參數在啓動時指定,分割成各種尺寸的塊(chunk), 並把尺寸相同的塊分成組(chunk的集合),如果需要申請內存時,memcached會劃分出一個新的page並分配給需要的slab區域。page一旦被分配在重啓前不會被回收或者重新分配,以解決內存碎片問題。

在這裏插入圖片描述

Page

分配給Slab的內存空間,默認是1MB。分配給Slab之後根據slab的大小切分成chunk。

Chunk

用於緩存記錄的內存空間。

Slab Class

特定大小的chunk的組。

2.2、新數據申請具體過程如下:

在這裏插入圖片描述

每個slab只存儲大於其上一個slab中chunk的size並小於或者等於自己size的數據。memcached根據收到的數據的大小,選擇最適合數據大小的slab。每個chunk都是上一個slab的chunk的大小的1.25倍。可通過-f修改增長因子。
在這裏插入圖片描述

2.3內存浪費問題

每個slab中的chunk大小是一樣的,如上圖所示slab1的chunk大小是88字節,slab2是112字節。由於分配的是特定長度的內存,因此無法有效利用分配的內存。

例如,將100字節的數據緩存到128字節的chunk中,剩餘的28字節就浪費了。chunk中不僅存放緩存對象的value,而且保存了緩存對象的key,expire time, flag等詳細信息。

在這裏插入圖片描述

3、memcache狀態和性能查看

3.1命中率 :stats命令

stats
STAT pid 31150
STAT uptime 7096
STAT time 1577417038
STAT version 1.4.20
STAT libevent 1.4.13-stable
STAT pointer_size 64
STAT rusage_user 3.071533
STAT rusage_system 6.908949
STAT curr_connections 9
STAT total_connections 4987
STAT connection_structures 12
STAT reserved_fds 20
STAT cmd_get 2
STAT cmd_set 140102
STAT cmd_flush 0
STAT cmd_touch 0
STAT get_hits 2
STAT get_misses 0
STAT delete_misses 0
STAT delete_hits 0
STAT incr_misses 0
STAT incr_hits 0
STAT decr_misses 0
STAT decr_hits 0
STAT cas_misses 0
STAT cas_hits 0
STAT cas_badval 0
STAT touch_hits 0
STAT touch_misses 0
STAT auth_cmds 0
STAT auth_errors 0
STAT bytes_read 280231309
STAT bytes_written 3977877
STAT limit_maxbytes 10485760
STAT accepting_conns 1
STAT listen_disabled_num 0
STAT threads 4
STAT conn_yields 0
STAT hash_power_level 16
STAT hash_bytes 524288
STAT hash_is_expanding 0
STAT malloc_fails 0
STAT bytes 957022
STAT curr_items 451
STAT total_items 140102
STAT expired_unfetched 0
STAT evicted_unfetched 130699
STAT evictions 130699
STAT reclaimed 0
STAT crawler_reclaimed 0

在這裏插入圖片描述

命中率=get_hits / (get_hits + get_misses)

3.2觀察各slab的items的情況:Stats items命令

stats items
STAT items:15:number 451
STAT items:15:age 4133
STAT items:15:evicted 129549
STAT items:15:evicted_nonzero 129549
STAT items:15:evicted_time 1
STAT items:15:outofmemory 0
STAT items:15:tailrepairs 0
STAT items:15:reclaimed 0
STAT items:15:expired_unfetched 0
STAT items:15:evicted_unfetched 129549
STAT items:15:crawler_reclaimed 0
主要參數說明:
outofmemory slab class爲新item分配空間失敗的次數。這意味着你運行時帶上了-M或者移除操作失敗
number 存放的數據總數
age 存放的數據中存放時間最久的數據已經存在的時間,以秒爲單位
evicted 不得不從LRU中移除未過期item的次數
evicted_time 自最後一次清除過期item起所經歷的秒數,即最後被移除緩存的時間,0表示當前就有被移除,用這個來判斷數據被移除的最近時間
evicted_nonzero 沒有設置過期時間(默認30天),但不得不從LRU中移除該未過期的item的次數

LRU策略不是針對所有的slabs,而是隻針對新數據應該被放入的slab。

3.3 觀察各slabs的情況:stats slabs命令

從Stats items中如果發現有異常的slab,則可以通過stats slabs查看下該slab是不是內存分配的確有問題。

stats slabs
STAT 12:chunk_size 1184
STAT 12:chunks_per_page 885
STAT 12:total_pages 10
STAT 12:total_chunks 8850
STAT 12:used_chunks 0
STAT 12:free_chunks 8850
STAT 12:free_chunks_end 0
STAT 12:mem_requested 0
STAT 12:get_hits 2
STAT 12:cmd_set 10102
STAT 12:delete_hits 0
STAT 12:incr_hits 0
STAT 12:decr_hits 0
STAT 12:cas_hits 0
STAT 12:cas_badval 0
STAT 12:touch_hits 0
STAT 15:chunk_size 2320
STAT 15:chunks_per_page 451
STAT 15:total_pages 1
STAT 15:total_chunks 451
STAT 15:used_chunks 451
STAT 15:free_chunks 0
STAT 15:free_chunks_end 0
STAT 15:mem_requested 957022
STAT 15:get_hits 0
STAT 15:cmd_set 130000
STAT 15:delete_hits 0
STAT 15:incr_hits 0
STAT 15:decr_hits 0
STAT 15:cas_hits 0
STAT 15:cas_badval 0
STAT 15:touch_hits 0
STAT active_slabs 2
STAT total_malloced 11524720
主要參數說明:
屬性名稱 屬性說明
chunk_size 當前slab每個chunk的大小
chunk_per_page 每個page能夠存放的chunk數
total_pages 分配給當前slab的page總數,默認1個page大小1M,可以計算出該slab的大小
total_chunks 當前slab最多能夠存放的chunk數,應該等於chunck_per_page * total_page
used_chunks 已經被佔用的chunks總數
free_chunks 過期數據空出的chunk但還沒有被使用的chunk數
free_chunks_end 新分配的但是還沒有被使用的chunk數
active_slabs 活動的slab總數
total_malloced 實際已經分配的總內存數,單位爲byte,這個數值決定了memcached實際還能申請多少內存,如果這個值已經達到設定的上限(和stats settings中的maxbytes對比),則不會有新的page被分配。

total_chunks = used_chunks + free_chunks + free_chunks_end

3.4對象數量的統計:

stats sizes
STAT 2144 451

注意:該命令會鎖定服務,暫停處理請求。該信息返回兩列,第一列是 item 的大小,第二列是 item 的個數。

3.5查看、導出key:stats cachedump

3.5.1先列出items:
stats items
STAT items:15:number 451
STAT items:15:age 4647
STAT items:15:evicted 129549
STAT items:15:evicted_nonzero 129549
STAT items:15:evicted_time 1
STAT items:15:outofmemory 0
STAT items:15:tailrepairs 0
STAT items:15:reclaimed 0
STAT items:15:expired_unfetched 0
STAT items:15:evicted_unfetched 129549
STAT items:15:crawler_reclaimed 0
END
3.5.2通過itemid取key,上面的id是29,再加上一個參數:爲列出的長度,0爲全部列出。
stats cachedump 15 5
ITEM k99999 [2048 b; 1577416690 s]
ITEM k99998 [2048 b; 1577416690 s]
ITEM k99997 [2048 b; 1577416690 s]
ITEM k99996 [2048 b; 1577416690 s]
ITEM k99995 [2048 b; 1577416690 s]
END

導出爲文件命令

echo  "stats cachedump 15 0" | nc 192.168.180.35 11211 >/home/dev/memcache.log

4、案例分析

若通過stats查看bytes並不大,但是item被驅逐嚴重,則是因爲memcache中已經被某大小的chunk佔用,無法申請到所需的chunk。可通過stats slabs和stats items進行查看分析。
在這裏插入圖片描述
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章