memcache内存管理

做~自己de王妃 提交于 2020-01-20 16:57:30

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进行查看分析。
在这里插入图片描述
在这里插入图片描述

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!