一文了解Memcache内存分配机制及stats参数

一、Memcache内存分配机制

了解memcached必须了解的三个单位:page、slabs、chunk。

1.1、Page

     Page为内存分配的最小单位,Memcached的内存分配以page为单位,默认情况下一个page是1M,可以通过-I参数在启动时指定。如果需要申请内存 时,memcached会划分出一个新的page并分配给需要的slab区域。page一旦被分配在重启前不会被回收或者重新分配

1.2、Slabs

Memcached并不是将所有大小的数据都放在一起的,而是预先将数据空间划分为一系列slabs,既按照不同的大小,每个slab只负责一定范围内的数据存储。如 下图,每个slab只存储大于其上一个slab的size并小于或者等于自己最大size的数据。例如:slab 3只存储大小介于137 到 224 bytes的数据。如果一个数据大小为230byte将被分配到slab 4中。从下图可以看出,每个slab负责的空间其实是不等的,memcached默认情况下下一个slab的最大值为前一个的1.25倍,这个可以通过修 改-f参数来修改增长比例。 

1.3、Chunk

Chunk才是存放缓存数据的单位Chunk是一系列固定的内存空间,这个大小就是管理它的slab的最大存放大小。例如:slab 1的所有chunk都是104byte,而slab 4的所有chunk都是280byte。chunk是memcached实际存放缓存数据的地方,因为chunk的大小固定为slab能够存放的最大值, 所以所有分配给当前slab的数据都可以被chunk存下。如果存储数据大小小于chunk的大小,空余的空间将会被闲置,这个是为了防止内存碎片而设 计的。例如下图,chunk size是224byte,而存储的数据只有200byte,剩下的24byte将被闲置。 

1.4、了解Slab的内存分配策略

Memcached在启动时通过-m指定最大使用内存,但是这个不会一启动就占用,是随着需要逐步分配给各slab的。如果一个新的缓存数据要被存放,memcached首先选择一个合适的slab,然后查看该slab是否还有空闲的chunk,如果有则直接存放进去;如 果没有则要进行申请。slab申请内存时以page为单位,所以在放入第一个数据,无论大小为多少,都会有1M大小的page被分配给该slab。申请到 page后,slab会将这个page的内存按chunk的大小进行切分,这样就变成了一个chunk的数组,在从这个chunk数组中选择一个用于存储 数据。如下图,slab 1和slab 2都分配了一个page,并按各自的大小切分成chunk数组。 

综合上面的介绍memcached的内存分配策略就是:按slab需求分配page,各slab按需使用chunk存储。Memcached分配出去的page不会被回收或者重新分配Memcached申请的内存不会被释放slab空闲的chunk不会借给任何其他slab使用。理解memcached的分别策略以后就可以理解为什么总内存没有被全部占用的情况下,memcached却出现了丢失缓存数据的问题了。

二、memcached命令及参数解释

2.1、stats

Name

Meaning

pid

memcached 服务器的进程 id 号

uptime

memcached 自启动至今的时长(按秒计算)

time

服务器当前的 UNIX 时间戳

version

memcached 的版本号字符串

pointer_size

默认的服务器操作系统指针尺寸(一般为 32 或 64)

rusage_user

mcached 进程用户态的累计时长(秒:毫秒)

rusage_system

memcached 进程内核态的累计时长(秒:毫秒)

curr_items

memcached 当前存储的对象数量

total_items

memcached 自启动至今存储过的对象数量

bytes

emcached 当前用来存储数据所消耗的内存量(字节)

curr_connections

memcached 当前打开的连接

total_connections

memcached 自启动至今打开过的连接数

connection_structures

memcached 分配的连接结构的数量

cmd_get

get 命令的总次数

cmd_set

set 命令的总次数

get_hits

get 命令命中的总次数

get_misses

get 命令未命中的总次数

delete_misses

delete 命令未命中的总次数

delete_hits

delete 命令命中的总次数

incr_misses

incr 命令未命中的总次数

incr_hits

incr 命令命中的总次数

decr_misses

decr 命令未命中的总次数

decr_hits

decr 命令命中的总次数

cas_misses

cas 命令未命中的总次数

cas_hits

cas 命令命中的总次数

cas_badval

cas 命令命中却更新失败的总次数

auth_cmds

memcached 接受到所有的授权命令,无论成功失败

auth_errors

memcached 接受到的所有失败的授权命令

evictions

因 LRU 机制而被主动覆盖(删除)的对象数目

reclaimed

memcached 启动至今有多少次在存储数据的时候使用了过期数据的空间

bytes_read

memcached 从网络中读取的总数据字节数

bytes_written

memcached服务器发送到网络的总的字节数

limit_maxbytes

memcached 向网络中写入的总数据字节数

threads

worker 线程数量(具体请查看 doc/threads.txt)

conn_yields

memcached 启动至今有多少次打开的连接因为内部请求数达到 -R 参数指定的限值, 一个连接的操作主动放弃让给另一个连接(不是很明白什么意思,具体可以参考 -R 参数的含义)

2.2、stats settings

Name

Meaning

maxbytes

memcached 可分配的最大缓存内存字节数

maxconns

memcached 允许的连接数最大数值

tcpport

TCP 监听端口

udpport

UDP 监听端口

inter

监听的 host 地址

verbosity

memcached 运行信息输出级别:0 = none, 1 = some, 2 = lots

oldest

memcached 当前存储的对象中最长的存活时长

evictions

当设成 off 的时候,LRU 机制将不会启用

domain_socket

Unix socket 的文件路径(如果存在的话)

umask

创建 Unix socket 的 umask

growth_factor

Chunk 尺寸增长因子数值

chunk_size

最小的 chunk 尺寸(key+value+flags)

num_threads

线程数量(包括 dispatch 的)

stat_key_prefix

Stats 命令分隔符

detail_enabled

如果 yes 的话,stats 的详细信息将被开启

reqs_per_event

一个事件(event)中允许的最大 IO 操作数

cas_enabled

如果 no 的话,CAS 不会被启用

tcp_backlog

CP 监听队列(backlog)等待长度的最大值

auth_enabled_sasl

是否启用 SASL 授权请求

2.3、stats items

Name

Meaning

number

当前 slab 中存储的对象数量,过期的对象不会主动被排除出去

age

LRU 中存活时间最长的对象的存活时长

evicted

根据 LRU 原则不得不在过期之前就被删除的对象的个数

evicted_nonzero

根据 LRU 原则不得不在过期之间就被删除,且有被设过过期时间的对象个数

evicted_time

根据 LRU 原则不得不在过期之间就被删除,且有被设过过期时间的对象个数,用这个来做 LRU 的频率监控

outofmemory

该 slab 无法为新对象分配内存空间的次数,出现这个数值意味着memcached 在运行的时候带上了-M参数或者存在 LRU 删除失败

tailrepairs

这个数值表示了我们自己解决的 slab 引用泄露的次数,如果这个数值增长很多,请联系开发人员

reclaimed

memcached 使用一个过期数据的空间来存储数据的次数

2.4、stats sizes


    这个stats命令将会返回存储在缓存内所有对象的尺寸和个数信息。 
    警告:这个命令将会锁死你的缓存!它会遍历缓存内存储的每个对象,并获取他们的尺寸。虽然这个命令速度很快,但是如果你的缓存里存储了很多对象的话,这个命令还是有可能会使你的缓存在几秒钟内无法进行任何缓存服务。 
    命令返回的格式为: STAT <size> <count> 
    这个命令会显示出,对于所有存储在你缓存中的对象,是否每32个字节就存在一个slab。你可以通过这个命令来查看,是否调整slab增长因子会节约你的内存开销。 
举例来说:如果你大部分的存储对象的尺寸是小于200字节的话,创建更多小尺寸的slab会使得存储对象找到更适合它们尺寸的slab。 

2.5、stats slabs

Name

Meaning

chunk_size

每个 chunk 占用的内存空间,一个存储对象将会寻找适合它尺寸的 chunk 来存储

chunks_per_page

当前数字说明了每个 page 可以划分成多少个 chunk,一个 page 默认大小小于等于1M,Slabs 申请的内存是按 page 分配的,接着按大小划分为 chunk

total_pages

当前 slab 所分配到的 page 总数

total_chunks

当前 slab 所分配到的 chunk 总数

get_hits

当前 slab 中命中的 get 请求数

cmd_set

当前 slab 接受的所有 set 命令请求数

delete_hits

当前 slab 中命中的 delete 请求数

incr_hits

当前 slab 中命中的 incr 请求数

decr_hits

当前 slab 中命中的 decr 请求数

cas_hits

当前 slab 中命中的 cas 请求数

cas_badval

当前 slab 中命中但是更新失败的 cas 请求数

used_chunks

已经被分配给存储对象的 chunk 数

free_chunks

还未被分配给存储对象,或通过 delete 操作释放出来的 chunk

free_chunks_end

最近分配的 Page 尾部空闲 chunk 数

mem_requested

当前 slab 中被请求用来存储对象数据的内存空间字节总数(注 1

active_slabs

memcached 分配的 slab 的总数

total_malloced

emcached 分配给所有 slab 的 pages 的内存总量


1:存储对象是被存储在尺寸等于或者大于对象尺寸的slab里的。mem_requested显示了当前slab里所有存储对象总占用的内存空间。 
(total_chunks * chunk_size) – mem_requested 的结果显示了有多少内存在这个slab里是被闲置的。如果你看到闲置的内存量很大, 考虑使用slab增长因子来调节slab大小,其中(used_chunks + free_chunks) * chunk_size就是用掉的chunks被分配到的内存空间,mem_requested是实际被占用掉的内存空间,两者的差值就是没有用掉的(闲置的)内存。

  • 25
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值