memcached的内存存储机制
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的组。
Memcached并不是将所有大小的数据都放在一起的,而是预先将数据空间划分为一系列slabs,每个slab只负责一定范围内的数据存储。memcached根据收到的数据的大小,选择最适合数据大小的slab。memcached中保存着slab内空闲chunk的列表,根据该列表选择chunk,然后将数据缓存于其中。
如图所示,每个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字节的空间存放。
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。
1、stats :显示服务器信息、统计数据等
pid:守护进程的id
uptime:进程已经运行的时间,以秒为单位
time:当前的unix时间
version:服务器版本
pointer_size:操作系统默认的指针长度
rusage_user:进程累计的user time(秒:毫秒)
rusage_system:进程累计的system time(秒:毫秒)
curr_items:当前的items数量
total_items:进程启动开始存储过的items数量
bytes:当前用于存储items的byte数量
curr_connections:打开的连接数量
total_connections:进程启动开始打开过的连接数量
connection_structures:服务分配的连接结构数量
cmd_get:提取请求次数
cmd_set:存储请求次数
get_hits:get命中次数
get_misses:get未命中次数
evictions:为了添加新item而回收的合法item数量
bytes_read:服务从network读取的byte数量
bytes_written:服务写入network的byte数量
limit_maxbytes:服务可使用的用于存储数据的最大值
threads:被请求的工作线程数量
2、stats reset 清空统计数据
3、stats malloc 显示内存分配数据
4、stats maps 是把/proc/self/maps的数据显示出来。
如果远程攻击者连接到了memcached的TCP端口(默认11211)并发布了stats maps命令,Memcached就会直接将/proc/self/maps的输出管道传输给客户端。这可能导致泄漏所分配内存区域的地址。
5、stats size
6、stats slabs
chunk_size:每个chunk(块)使用的空间数量,一个item存储到一个近似大小的chunk中
chunk_per_page:每page存在的chunk数量,slabs是按页(page)分配的,一页一般为1M,每个slab(也即每页)又划分为若干chunk,这里涉及到memcached的内存管理,这里不多解释,可以参考后面的附文。
total_pages:该slabclass分配到的page数量
total_chunks:该slabclass拥有的chunk数量
used_chunks:已经分配给item的chunk数量(不一定已经装填了item)
free_chunks:尚未分配给item的chunk数量,或者由delete释放的chunk
free_chunks_end:slabclass中最后一页的自由块数量,即该slabclass尚有多少自由块可以用来装填item
active_slabs:已分配的slabclass数量
total_malloced:已分配给slab page的内存数量
7、stats items 显示各个slab中item的数目和最老item的年龄(最后一次访问距离现在的秒数)stats detail [on|off|dump]
设置或者显示详细操作记录
参数为on,打开详细操作记录
参数为off,关闭详细操作记录
参数为dump,显示详细操作记录(每一个键值get、set、hit、del的次数)
8、stats cachedump slab_id limit_num 显示某个slab中的前limit_num个key列表
显示格式如下:ITEM key_name [ value_length b; expire_time|access_time s]其中,memcached 1.2.2及以前版本显示的是 访问时间(timestamp) 1.2.4以上版本,包括1.2.4显示 过期时间(timestamp)
如果是永不过期的key,expire_time会显示为服务器启动的时间
显示各个slab的信息,包括chunk的大小、数目、使用情况等
9、stats detail dump ( stats detail [on|off|dump] )
原文:http://www.cnblogs.com/dim2046/p/6255095.html