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进行查看分析。
来源:CSDN
作者:阿甘修行
链接:https://blog.csdn.net/happygan520/article/details/104048125