Memcache内存分配策略和性能(使用)状态检查-创新互联

一直在使用Memcache,但是对其内部的问题,如它内存是怎么样被使用的,使用一段时间后想看看一些状态怎么样?一直都不清楚,查了又忘记,现在整理出该篇文章,方便自己查阅。本文不涉及安装、操作。有兴趣的同学可以查看之前写的文章和Google。

创新互联是一家集网站建设,宁明企业网站建设,宁明品牌网站建设,网站定制,宁明网站建设报价,网络营销,网络优化,宁明网站推广为一体的创新建站企业,帮助传统企业提升企业形象加强企业竞争力。可充分满足这一群体相比中小企业更为丰富、高端、多元的互联网需求。同时我们时刻保持专业、时尚、前沿,时刻以成就客户成长自我,坚持不断学习、思考、沉淀、净化自己,让我们为更多的企业打造出实用型网站。

1:参数

Memcache 内存分配策略和性能(使用)状态检查

memcached -h  memcached 1.4.14-p       TCP端口,默认为11211,可以不设置-U       UDP端口,默认为11211,0为关闭-s       UNIX socket-a       access mask for UNIX socket, in octal (default: 0700)-l       监听的 IP 地址,本机可以不设置此参数-d         以守护程序(daemon)方式运行-u         指定用户,如果当前为 root ,需要使用此参数指定用户-m       大内存使用,单位MB。默认64MB-M         禁止LRU策略,内存耗尽时返回错误,而不是删除项-c       大同时连接数,默认是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       保存PID到指定文件-f      增长因子,默认1.25-n      初始chunk=key+suffix+value+32结构体,默认48字节-L         启用大内存页,可以降低内存浪费,改进性能-t       线程数,默认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

Memcache 内存分配策略和性能(使用)状态检查

 上面加粗的参数,需要重点关注,正常启动的例子:

Memcache 内存分配策略和性能(使用)状态检查

启动:/usr/bin/memcached -m 64 -p 11212 -u nobody -c 2048 -f 1.1 -I 1024 -d -l 10.211.55.9连接:telnet 10.211.55.9 11212Trying 10.211.55.9...
Connected to 10.211.55.9.
Escape character is '^]'.

Memcache 内存分配策略和性能(使用)状态检查

可以通过命令查看所有参数:stats settings

Memcache 内存分配策略和性能(使用)状态检查

2:理解memcached的内存存储机制

   Memcached默认情况下采用了名为Slab Allocator的机制分配、管理内存。在该机制出现以前,内存的分配是通过对所有记录简单地进行malloc和free来进行的。但是,这种方式会导致内存碎片,加重操作系统内存管理器的负担,最坏的情况下,会导致操作系统比memcached进程本身还慢。Slab Allocator就是为解决该问题而诞生的。

   Slab Allocator的基本原理是按照预先规定的大小,将分配的内存以page为单位,默认情况下一个page是1M,可以通过-I参数在启动时指定,分割成各种尺寸的块(chunk), 并把尺寸相同的块分成组(chunk的集合),如果需要申请内存时,memcached会划分出一个新的page并分配给需要的slab区域。page一旦被分配在重启前不会被回收或者重新分配,以解决内存碎片问题。

Memcache 内存分配策略和性能(使用)状态检查

Page

分配给Slab的内存空间,默认是1MB。分配给Slab之后根据slab的大小切分成chunk。

Chunk

用于缓存记录的内存空间。

Slab Class

特定大小的chunk的组。

   Memcached并不是将所有大小的数据都放在一起的,而是预先将数据空间划分为一系列slabs,每个slab只负责一定范围内的数据存储。memcached根据收到的数据的大小,选择最适合数据大小的slab。memcached中保存着slab内空闲chunk的列表,根据该列表选择chunk,然后将数据缓存于其中。

Memcache 内存分配策略和性能(使用)状态检查

   如图所示,每个slab只存储大于其上一个slab的size并小于或者等于自己大size的数据。例如:100字节大小的字符串会被存到slab2(88-112)中,每个slab负责的空间是不等的,memcached默认情况下下一个slab的大值为前一个的1.25倍,这个可以通过修改-f参数来修改增长比例。

    Slab Allocator解决了当初的内存碎片问题,但新的机制也给memcached带来了新的问题。chunk是memcached实际存放缓存数据的地方,这个大小就是管理它的slab的大存放大小。每个slab中的chunk大小是一样的,如上图所示slab1的chunk大小是88字节,slab2是112字节。由于分配的是特定长度的内存,因此无法有效利用分配的内存。例如,将100字节的数据缓存到128字节的chunk中,剩余的28字节就浪费了。这里需要注意的是chunk中不仅仅存放缓存对象的value,而且保存了缓存对象的key,expire time, flag等详细信息。所以当set 1字节的item,需要远远大于1字节的空间存放。

Memcache 内存分配策略和性能(使用)状态检查

memcached在启动时指定 Growth Factor因子(通过-f选项), 就可以在某种程度上控制slab之间的差异。默认值为1.25。

slab的内存分配具体过程如下:

   Memcached在启动时通过-m参数指定大使用内存,但是这个不会一启动就占用完,而是逐步分配给各slab的。如果一个新的数据要被存放,首先选择一个合适的slab,然后查看该slab是否还有空闲的chunk,如果有则直接存放进去;如果没有则要进行申请,slab申请内存时以page为单位,无论大小为多少,都会有1M大小的page被分配给该slab(该page不会被回收或者重新分配,永远都属于该slab)。申请到page后,slab会将这个page的内存按chunk的大小进行切分,这样就变成了一个chunk的数组,再从这个chunk数组中选择一个用于存储数据。若没有空闲的page的时候,则会对改slab进行LRU,而不是对整个memcache进行LRU。

以上大致讲解了memcache的内存分配策略,下面来说明如何查看memcache的使用状况。

3,memcache状态和性能查看

  命中率 :stats命令

Memcache 内存分配策略和性能(使用)状态检查

按照下面的图来解读分析

Memcache 内存分配策略和性能(使用)状态检查

 get_hits表示读取cache命中的次数,get_misses是读取失败的次数,即尝试读取不存在的缓存数据。即:

命中率=get_hits / (get_hits + get_misses)

命中率越高说明cache起到的缓存作用越大。但是在实际使用中,这个命中率不是有效数据的命中率,有些时候get操作可能只是检查一个key存在不存在,这个时候miss也是正确的,这个命中率是从memcached启动开始所有的请求的综合值,不能反映一个时间段内的情况,所以要排查memcached的性能问题,还需要更详细的数值。但是高的命中率还是能够反映出memcached良好的使用情况,突然下跌的命中率能够反映大量cache丢失的发生。

② 观察各slab的items的情况:Stats items命令

Memcache 内存分配策略和性能(使用)状态检查

主要参数说明:

outofmemoryslab class为新item分配空间失败的次数。这意味着你运行时带上了-M或者移除操作失败
number存放的数据总数
age存放的数据中存放时间最久的数据已经存在的时间,以秒为单位
evicted不得不从LRU中移除未过期item的次数 
evicted_time自最后一次清除过期item起所经历的秒数,即最后被移除缓存的时间,0表示当前就有被移除,用这个来判断数据被移除的最近时间
evicted_nonzero没有设置过期时间(默认30天),但不得不从LRU中称除该未过期的item的次数

    因为memcached的内存分配策略导致一旦memcached的总内存达到了设置的大内存表示所有的slab能够使用的page都已经固定,这时如果还有数据放入,将导致memcached使用LRU策略剔除数据。而LRU策略不是针对所有的slabs,而是只针对新数据应该被放入的slab,例如有一个新的数据要被放入slab 3,则LRU只对slab 3进行,通过stats items就可以观察到这些剔除的情况。

注意evicted_time:并不是发生了LRU就代表memcached负载过载了,因为有些时候在使用cache时会设置过期时间为0,这样缓存将被存放30天,如果内存满了还持续放入数据,而这些为过期的数据很久没有被使用,则可能被剔除。把evicted_time换算成标准时间看下是否已经达到了你可以接受的时间,例如:你认为数据被缓存了2天是你可以接受的,而最后被剔除的数据已经存放了3天以上,则可以认为这个slab的压力其实可以接受的;但是如果最后被剔除的数据只被缓存了20秒,不用考虑,这个slab已经负载过重了。

通过上面的说明可以看到当前的memcache的slab1的状态:

items有305816个,有效时间最久的是21529秒,通过LRU移除未过期的items有95336839个,通过LRU移除没有设置过期时间的未过期items有95312220个,当前就有被清除的items,启动时没有带-M参数。

③ 观察各slabs的情况:stats slabs命令

从Stats items中如果发现有异常的slab,则可以通过stats slabs查看下该slab是不是内存分配的确有问题。

Memcache 内存分配策略和性能(使用)状态检查

主要参数说明:

属性名称属性说明
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数

这里需要注意total_pages 这个是当前slab总共分配大的page总数,如果没有修改page的默认大小的情况下,这个数值就是当前slab能够缓存的数据的总大小(单位为M)。如果这个slab的剔除非常严重,一定要注意这个slab的page数是不是太少了。还有一个公式:

total_chunks = used_chunks + free_chunks + free_chunks_end

另外stats slabs还有2个属性:

Memcache 内存分配策略和性能(使用)状态检查

属性名称属性说明

active_slabs

活动的slab总数

total_malloced

实际已经分配的总内存数,单位为byte,这个数值决定了memcached实际还能申请多少内存,如果这个值已经达到设定的上限(和stats settings中的maxbytes对比),则不会有新的page被分配。

④ 对象数量的统计:stats sizes

Memcache 内存分配策略和性能(使用)状态检查

注意:该命令会锁定服务,暂停处理请求。该命令展示了固定chunk大小中的items的数量。也可以看出slab1(96byte)中有多少个chunks。

⑤ 查看、导出key:stats cachedump

在进入memcache中,大家都想查看cache里的key,类似redis中的keys *命令,在memcache里也可以查看,但是需要2步完成。

一是先列出items:

Memcache 内存分配策略和性能(使用)状态检查

stats items  --命令...
...
STAT items:29:number 228STAT items:29:age 34935...
END

Memcache 内存分配策略和性能(使用)状态检查

二是通过itemid取key,上面的id是29,再加上一个参数:为列出的长度,0为全部列出。

Memcache 内存分配策略和性能(使用)状态检查

stats cachedump 29 0  --命令ITEM 26457202 [49440 b; 1467262309 s]
...
ITEM 30017977 [45992 b; 1467425702 s]
ITEM 26634739 [48405 b; 1467437677 s]
END  --总共228个keyget 26634739  取value

Memcache 内存分配策略和性能(使用)状态检查

如何导出key呢?这里就需要通过 echo ... nc 来完成了

echo  "stats cachedump 29 0" | nc 10.211.55.9 11212 >/home/zhoujy/memcache.log

在导出的时候需要注意的是:cachedump命令每次返回的数据大小只有2M,这个是memcached的代码中写死的一个数值,除非在编译前修改。

⑥ 另一个监控工具:memcached-tool,一个perl写的工具:memcache_tool.pl

Memcache 内存分配策略和性能(使用)状态检查 View Code

Memcache 内存分配策略和性能(使用)状态检查

./memcached-tool 10.211.55.9:11212   --执行
 #  Item_Size  Max_age  Pages  Count  Full?  Evicted Evict_Time OOM
 1    96B   20157s    28  305816   yes 95431913     0   0
 2   120B   16049s    40  349520   yes 117041737     0   0
 3   152B   17574s    39  269022   yes 92679465     0   0
 4   192B   18157s    43  234823   yes 78892650     0   0
 5   240B   18722s    52  227188   yes 72908841     0   0
 6   304B   17971s    73  251777   yes 85556469     0   0
 7   384B   17881s    81  221130   yes 75596858     0   0
 8   480B   17760s    70  152880   yes 53553607     0   0
 9   600B   18167s    58  101326   yes 34647962     0   0
10   752B   18518s    52  72488   yes 24813707     0   0
11   944B   18903s    52  57720   yes 16707430     0   0
12   1.2K   20475s    44  38940   yes 11592923     0   0
13   1.4K   21220s    36  25488   yes  8232326     0   0
14   1.8K   22710s    35  19740   yes  6232766     0   0
15   2.3K   22027s    33  14883   yes  4952017     0   0
16   2.8K   23139s    33  11913   yes  3822663     0   0
17   3.5K   23495s    31   8928   yes  2817520     0   0
18   4.4K   22611s    29   6670   yes  2168871     0   0
19   5.5K   23652s    29   5336   yes  1636656     0   0
20   6.9K   21245s    26   3822   yes  1334189     0   0
21   8.7K   22794s    22   2596   yes  783620     0   0
22   10.8K   22443s    19   1786   yes  514953     0   0
23   13.6K   21385s    18   1350   yes  368016     0   0
24   16.9K   23782s    16   960   yes  254782     0   0
25   21.2K   23897s    14   672   yes  183793     0   0
26   26.5K   27847s    13   494   yes  117535     0   0
27   33.1K   27497s    14   420   yes   83966     0   0
28   41.4K   28246s    14   336   yes   63703     0   0
29   51.7K   33636s    12   228   yes   24239     0   0

Memcache 内存分配策略和性能(使用)状态检查

解释:

含义
#slab class编号
Item_Size   chunk大小
Max_ageLRU内最旧的记录的生存时间
pages分配给Slab的页数
countSlab内的记录数、chunks数、items数、keys数
Full?Slab内是否含有空闲chunk
Evicted从LRU中移除未过期item的次数
Evict_Time最后被移除缓存的时间,0表示当前就有被移除
OOM-M参数?

另外有需要云服务器可以了解下创新互联scvps.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。


文章名称:Memcache内存分配策略和性能(使用)状态检查-创新互联
标题网址:http://scyanting.com/article/ceghsd.html