Memcached的Slab Allocation机制管理内存
#Memcached那些事 本文不是为了介绍Memcached是什么,而是讨论在使用Memcached的时候你必须知道的一些事情。以便于方便排查和更好的使用Memcached。本文主要围绕两个方面来讨论这个话题:Memcached的使用和监控。 ##如何更好的使用Memcached 这部分讨论的是如何能够合理有效的让Memcached为我们服务,通过什么方式来调控Memcached,让它工作的更好。下面进入这部分的内容: ###Memcached如何存储我们的数据? 要很好的使用Memcached,那么必须知道我们的数据交给Memcached,它是怎么处理它们的。为了说明这个,需要先了解几个名词:slab class,page,chunk。它们三者之间的关系如下:
- slab class :memcached会自动根据设置的chunk size以及当前分配给memcached创建一系列slab class,单个slab class中的chunk大小是一样的,而每个slab class中的chunk大小根据设置设置的chunk_size*growth_factor^(i-1),其中i表示第几个slab class(这里需要注意这里的chunk_size不只是item的数据大小,还包含memcached内部的一个item结构体大小,这个值一般是48byte,默认的growth_factor是1.25)。
- chunk:可以理解为memcached中存储数据的最小单元,每个存储在memcached中的item都会分配一个符合它大小的chunk,chunk的数量决定了memcached存储item的数量,默认的chunk为48byte。
- page:memcached中的内存是已page为单位分配给每个slab class,然后每个slab class根据它的chunk大小,计算出各自能够存储的item的数量,默认page大小为1M。而每一页能够存放多少个item,这取决于chunk_size的大小。
通过上面可以看到slab class 1中一个page能够存储的item数量是最多的,而最后一个slab class一个page只能存储一个item。这是由于第一个slab class 1的chunk大小是所有slab class中最小的,那么对于就导致了slab class 1的能够存储的item最多了。
memcached这样做的好处什么呢?memcached这样做将数据存储根据能够存储的大小归为几类,并且内存按照固定的大小来划分。相比于随机分配内存大小,导致内存碎片难于回收来说,这种内存方案对内存的利用率更高,而且便于管理。这就是memcached的slab allocation。
对于memcached来说,如果一个item申请写入数据,会计算当前item的大小然后加上memcached的item结构体大小,判断具体是存储在哪个slab class上面。判断的条件是item_size+item_structure_size<=某个slab class上的chunk大小。以上面的图来说,比如我需要写入一个54byte的数据(key+value),由于memcached的item结构体大小是48,那么memcached对于这个item需要写入的总数据大小是100byte,于是就会写入slab class2的某个chunk里面。于是就会存在下面的情况:
由于slab class2的chunk大小是112byte,那么写入100byte数据,就会有12byte空间浪费。这就是下一个话题,如何能够让memcached充分使用内存。 ###让Memcached充分使用内存。 上面列举的例子可以看出如何chunk大小设置不合适会导致内存空间的浪费,如何让memcached合理的使用内存呢?下面将介绍设置哪些参数来达到根据具体的业务合理的使用内存。
- 通过上面可以知道,slab class 1中能够存储的item数量是所有slab class中最多的,那么如果能够调整slab class 1的chunk大小,就能够提高memcached存储的数据量,并且对内存的利用率也有很大的提高。可以通过在memcached的启动参数-n来设置的slab class 1的chunk大小。由于后面的slab class都是在这个基础上递增,那么其实的slab class的chunk大小比较重要。比如你发现你们的业务存入memcached都是100byte的大小数据,那么可以将起始slab class的chunk设置为148byte(还要加上48byte的item结构体大小),例如memcached -n 148。这样就可以将数据基本上都会分布在slab class 1上面,而且在每一页上面能够创建的chunk数量也是最大的。
- 上面说通过调整slab class 1的chunk大小来提供能够存储的item数量,那么只是对于item大小比较固定的情况。如果对于item大小存在差异的时候呢?那么可以通过设置growth_factor来控制后面的slab class中chunk递增的速度,可以控制slab class中chunk大小变化幅度,来提高memcached的利用率。比如你现在的数据基本上在100-200byte之间,如果让这些数据全部存储在slab class 1那么有些item会只是占用chunk中的一半,这样对内存浪费比较大。所以可以条件growth_factor大小,来控制整个chunk大小在slab class递增的速度。可以通过启动参数-f来指定growth_factor大小,比如memcached -f 1.01 -n 100 (growth_factor值必须大于1)这样可以让memcached在chunk为100的基础上增长速度比较缓慢,能够有多个slab class的chunk大小分布在100-200byte之间。具体设置什么,可以根据你的业务或者一定的公式来获得这个值。
- 除了上面几个参数之外,可以调节页面的大小,以及分配给memcached的总内存大小来控制memcached分配内存的策略。通过启动参数-m调节memcached总内存大小,以及-I调节页面的大小。
##监控Memcached 如何监控memcached内存使用情况,以及每个slab classs当前状态这个对优化memcached也是一种重要的手段。memcached自身提供了对它监控的手段,也很简单。可以通过telnet链接到memcached即可查看当前的memcached。下面是在我本机上通过telnet观察memcached的一个实例,下面主要是对返回的几个参数进行说明。
<!--lang:shell-->
aaa@qq.com:~$ telnet localhost 11211
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
stats items
STAT items:1:number 64708
STAT items:1:age 32067
STAT items:1:evicted 0
STAT items:1:evicted_nonzero 0
STAT items:1:evicted_time 0
STAT items:1:outofmemory 0
STAT items:1:tailrepairs 0
STAT items:1:reclaimed 32828
STAT items:1:expired_unfetched 29979
STAT items:1:evicted_unfetched 0
END
stats slabs
STAT 1:chunk_size 688
STAT 1:chunks_per_page 1524
STAT 1:total_pages 43
STAT 1:total_chunks 65532
STAT 1:used_chunks 64708
STAT 1:free_chunks 824
STAT 1:free_chunks_end 0
STAT 1:mem_requested 5888428
STAT 1:get_hits 0
STAT 1:cmd_set 101909
STAT 1:delete_hits 0
STAT 1:incr_hits 0
STAT 1:decr_hits 0
STAT 1:cas_hits 0
STAT 1:cas_badval 0
STAT 1:touch_hits 0
STAT active_slabs 1
STAT total_malloced 45086016
END
上面主要执行了两个命令,一个是stats items和stats slabs。stats items是对当前memcached当前存储的item进行一个统计,可以看到item的数量,一些item的一些状态,比如是否有item被移除,是否有超时等,注意上面更在STAT items后面的数字表示是在第几个slab class上,上面表示数据都是在slab class 1上面。而stats slabs是观察各个slab class的情况,比如某个slab class使用了多少page,当前slab class的chunk_size,以及使用了多少个chunk,剩余多少chunk,以及内存的使用情况,同时可以看到整个memcached但钱有多少个slab class处于使用**状态,以及总共使用了多少内存,重要的是可以看到某个slab class对数据的操作历史累计统计(比如get_hits,cmd_set,delete_hits等等),从而可以看到哪个slab class存储的数据是热点数据,从而可以更具上面的方法调整memcached参数,来提高memcached对内存的使用情况。
上面主要是对memcached使用内存方面调优的参数以及对memcached运行状态的监控进行了讨论,这两者其实是一个相互反馈的过程。通过调整好了memcached相关参数,监控一下memcached运行情况,是否达到预期的效果,从而再对memcached进行调整,再进行监控。只有反复进行调整才能将memcached对内存方面的使用达到最佳的效果。当然可以通过其他参数对memcached进行其他方面的调整,不然能够支持的最大连接数量,处理请求的线程数量等,来提高memcached的整体处理能力。由于不是本文讨论的主题,所以这里就不做过多的描述,具体有哪些参数可以通过memcached -h来获取所有参数列表。
/usr/local/memcached/bin/memcached -u nobody -vvv -f 1.25
写在前面:前不久在工作中被问到关于MC一致哈希的问题,由于时隔太久几乎忘记,特前来恶补一下MC,以下是前几年在工作中学习MC时的一些资料,来历不明,特整理一下,希望对大家的学习也能有所帮助。
关于memcache的安装,有兴趣的朋友请参考这篇文章:http://blog.csdn.net/xifeijian/article/details/22000173
1、memcached 介绍
1.1 memcached 是什么?
memcached 是以LiveJournal旗下Danga Interactive 公司的Brad Fitzpatric 为首开发的一款软件。现在已成为mixi、hatena、Facebook、Vox、LiveJournal 等众多服务中提高Web
应用扩展性的重要因素。许多Web 应用都将数据保存到RDBMS 中,应用服务器从中读取数据并在浏览器中显示。但随着数据量的增大、访问的集中,就会出现RDBMS 的负担加重、数据库响应恶化、网站显示延迟等重大影响。这时就该memcached 大显身手了。memcached 是高性能的分布式内存缓存服务器。一般的使用目的是,通过缓存数据库查询结果,减少数据库访问次数,以提高动态Web 应用的速度、提高可扩展性。
内置内存存储方式
为了提高性能,memcached 中保存的数据都存储在memcached 内置的内存存储空间中。由于数据仅存在于内存中,因此重启memcached、重启操作系统会导致全部数据消失。另外,内容容量达到指定值之后,就基于LRU(Least Recently Used)算法自动删除不使用的缓存。memcached 本身是为缓存而设计的服务器,因此并没有过多考虑数据的永久性问题
memcached 不互相通信的分布式
memcached 尽管是“分布式”缓存服务器,但服务器端并没有分布式功能。各个memcached 不会互相通信以共享信息。那么,怎样进行分布式呢?这完全取决于客户端的实现。
2.2 memcached 启动
memcached 启动的命令在安装目录的bin 二级目录下,如/home/test/app/memcahced-1.4.2/bin/memcached -p 11222 -m 128–d
常用的一些启动选项介绍选项说明
-p 侦听的端口,默认为11211
-m 使用内存大小,默认的64m
-d 作为daemon 在后台启动
-vv 用very vrebose 模式启动,调试信息和错误输出到控制台
-l 侦听的地址,默认为所有可以访问的地址
-M 用于在内存溢出的时候,返回一个错误,禁止自动的移出数
据,替代的是返回一个error
-P Pid 文件存在的路径,仅限加上-d 参数是用
-c 最大同时的连接数,默认为1024
其它的一些选项,可以通过–h 命令来进行查看
2.3命令行访问memcached
下面假设memcached 启动时的-p 参数为11311,命令操作在启动memcached
本机首先telnet 连接到memcached 服务器
telnet 127.0.0.1 11311
telnet 成功之后,大概会显示下面的信息
Trying 127.0.0.1...
Connected to localhost.localdomain (127.0.0.1).
Escape character is '^]'.
各种状态(stats)
STAT <name> <value>\r\n
如:stats命令,则返回以下信息:
stats
STAT pid 26804
STAT uptime 182783
STAT time 1404973716
STAT version 1.4.13
STAT libevent 2.0.11-stable
STAT pointer_size 64
STAT rusage_user 2.320647
STAT rusage_system 5.411177
STAT curr_connections 34
STAT total_connections 558
STAT connection_structures 37
STAT reserved_fds 20
STAT cmd_get 127292
STAT cmd_set 60056
STAT cmd_flush 145
STAT cmd_touch 0
STAT get_hits 83811
STAT get_misses 43481
STAT delete_misses 15970
STAT delete_hits 11992
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 14300156
STAT bytes_written 11507140
STAT limit_maxbytes 134217728 # 分配给memcache的内存大小(字节)
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 expired_unfetched 16884
STAT evicted_unfetched 0
STAT bytes 609350 # 当前服务器存储items占用的字节数
STAT curr_items 4668 # 服务器当前存储的items数量
STAT total_items 60056
STAT evictions 0 # 分配给memcache的空间用满后需要删除旧的items数,踢出。
STAT reclaimed 27160 #回收再利用,已过期的数据条目来存储新数据。
END
存储命令(set ,add ,replace)
客户端会发送一行像这样的命令:
<command name> <key> <flags> <exptime> <bytes>\r\n
如:
set key1 0 600 5\r\nvalue\r\n
add key2 0 500 2\r\n
replace key1 0 600 6\r\nvalue1\r\n
详细的命令说明,可以见附录的memcached 中英文协议内容
读取命令(get)
命令如下:get <key>*\r\n
- <key>* 表示一个或多个键值,由空格隔开的字串
如:
get key1
VALUE key1 0 7
value12
删除命令(delete)
命令如:delete <key> <time>\r\n
<key> 是客户端希望服务器删除的内容的键名
- <time> 是一个单位为秒的时间(或代表直到某一刻的Unix时间),在该时间内服务器会拒绝对于此键名的“add”和“replace”命令。此时内容被放入delete队列,无法再通过“get”得到该内容,也无法是用“add”和“replace”命令(但是“set”命令可用)。直到指定时间,这些内容被最终从服务器的内存中彻底清除
<time>参数是可选的,缺省为0(表示内容会立刻清除,并且随后的存储命令均可用
如:delete key1
退出命令(quit)
如:quit
4、理解memcached 的内存存储
4.1Slab Allocation 机制:整理内存以便重复使用
最近的memcached 默认情况下采用了名为Slab Allocator 的机制分配、管理内存。在该机制出现以前,内存的分配是通过对所有记录简单地进行malloc和free 来进行的。但是,这种方式会导致内存碎片,加重操作系统内存管理器的负担,最坏的情况下,会导致操作系统比memcached 进程本身还慢。Slab Allocator 就是为解决该问题而诞生的
Slab Allocation 的原理相当简单。将分配的内存分割成各种尺寸的块
(chunk),并把尺寸相同的块分成组(chunk 的集合)
而且,slab allocator 还有重复使用已分配的内存的目的。也就是说,分配到的内存不会释放,而是重复利用。
Slab Allocation 的主要术语
Page
分配给Slab 的内存空间,默认是1MB。分配给Slab 之后根据slab 的大小切分成chunk。
Chunk
用于缓存记录的内存空间。
Slab Class
特定大小的chunk 的组
4.2 在Slab中缓存记录的原理
memcached 根据收到的数据的大小,选择最适合数据大小的slab,memcached 中保存着slab 内空闲chunk 的列表,根据该列表选择chunk,然
后将数据缓存于其中
4.3 Slab Allocator 的缺点
由于分配的是特定长度的内存,因此无法有效利用分配的内存。例如,将100 字节的数据缓存到128 字节的chunk 中,剩余的28字节就浪费了
对于该问题目前还没有完美的解决方案,但在文档中记载了比较有效的解决方案。就是说,如果预先知道客户端发送的数据的公用大小,或者仅缓存大小相同的数据的情况下,只要使用适合数据大小的组的列表,就可以减少浪费。但是很遗憾,现在还不能进行任何调优,只能期待以后的版本了。但是,我们可以调节slab class 的大小的差别。接下来说明growth factor 选项。
4.4 使用Growth Factor进行调优
memcached 在启动时指定Growth Factor 因子(通过f 选项),就可以在某种程度上控制slab 之间的差异。默认值为1.25。但是,在该选项出现之前,这个因子曾经固定为2,称为“powers of 2”策略。
下面是启动后的verbose 输出:
slab class 1: chunk size 128 perslab 8192
slab class 2: chunk size 256 perslab 4096
slab class 3: chunk size 512 perslab 2048
slab class 4: chunk size 1024 perslab 1024
slab class 5: chunk size 2048 perslab 512
slab class 6: chunk size 4096 perslab 256
slab class 7: chunk size 8192 perslab 128
slab class 8: chunk size 16384 perslab 64
slab class 9: chunk size 32768 perslab 32
slab class 10: chunk size 65536 perslab 16
slab class 11: chunk size 131072 perslab 8
slab class 12: chunk size 262144 perslab 4
slab class 13: chunk size 524288 perslab 2
可见,从128 字节的组开始,组的大小依次增大为原来的2 倍。这样设置的问题是,slab 之间的差别比较大,有些情况下就相当浪费内存。因此,为尽量减少内存浪费,两年前追加了growth factor 这个选项来看看现在的默认设置(f=1.25)时的输出(篇幅所限,这里只写到第10 组):
slab class 1: chunk size 88 perslab 11915
slab class 2: chunk size 112 perslab 9362
slab class 3: chunk size 144 perslab 7281
slab class 4: chunk size 184 perslab 5698
slab class 5: chunk size 232 perslab 4519
slab class 6: chunk size 296 perslab 3542
slab class 7: chunk size 376 perslab 2788
slab class 8: chunk size 472 perslab 2221
slab class 9: chunk size 592 perslab 1771
slab class 10: chunk size 744 perslab 1409
/usr/local/memcached/bin/memcached -u nobody -vvv -f 1.25 改变chunk size
可见,组间差距比因子为2 时小得多,更适合缓存几百字节的记录。从上面的输出结果来看,可能会觉得有些计算误差,这些误差是为了保持字节数的对齐而故意设置的。将memcached 引入产品,或是直接使用默认值进行部署时,最好是重新计算一下数据的预期平均长度,调整growth factor,以获得最恰当的设置。内存是珍贵的资源,浪费就太可惜了。
5、memcached 删除机制
memcached 是缓存,不需要永久的保存到服务器上,本章介绍memcache 的删除机制
5.1 memcached 在数据删除方面有效的利用资源
Memcached 不会释放已经分配的内存,记录过期之后,客户端无法再看到这一条记录,其存储空间就可以利用。
Lazy Expiration
memcached 内部不会监视记录是否过期,而是在get 时查看记录的时间戳,检查记录是否过期。这种技术被称为lazy(惰性)expiration。因此,memcached不会在过期监视上耗费CPU 时间
5.2 LRU:从缓存中有效删除数据的原理
memcached 会优先使用已超时的记录的空间,但即使如此,也会发生追加新记录时空间不足的情况,此时就要使用名为Least Recently Used(LRU)机制来分配空间。顾名思义,这是删除“最近最少使用”的记录的机制。因此,当memcached 的内存空间不足时(无法从slab class 获取到新的空间时),就从最近未被使用的记录中搜索,并将其空间分配给新的记录。从缓存的实用角度来看,该模型十分理想。不过,有些情况下LRU 机制反倒会造成麻烦。memcached 启动时通过“M”参数可以禁止LRU,如下所示:
$ memcached -M –m 1024
启动时必须注意的是,小写的“m”选项是用来指定最大内存大小的。不指定具体数值则使用默认值64MB。
指定“M”参数启动后,内存用尽时memcached 会返回错误。话说回来,memcached 毕竟不是存储器,而是缓存,所以推荐使用LRU
6、memcached 的分布式算法
6.1memcached 的分布式
memcached 虽然称为“分布式”缓存服务器,但服务器端并没有“分布式”功能。memcached 的分布式,则是完全由客户端程序库实现的。这种分布式是memcached 的最大特点
memcached 的分布式是什么意思?
下面假设memcached 服务器有node1~node3 三台,应用程序要保存键名为“tokyo”、“kanagawa”、“chiba”、“saitama”、“gunma”的数据
首先向memcached 中添加“tokyo”。将“tokyo”传给客户端程序库后,客户端实现的算法就会根据“键”来决定保存数据的memcached 服务器。服务器选定后,即命令它保存“tokyo”及其值
同样,“kanagawa”、“chiba”、“saitama”、“gunma”都是先选择服务器再保接下来获取保存的数据。获取时也要将要获取的键“tokyo”传递给函数库。函数库通过与数据保存时相同的算法,根据“键”选择服务器。使用的算法相同,就能选中与保存时相同的服务器,然后发送get 命令。只要数据没有因为某些原因被删除,就能获得保存的值。
这样,将不同的键保存到不同的服务器上,就实现了memcached 的分布式。memcached 服务器增多后,键就会分散,即使一台memcached 服务器发生故障无法连接,也不会影响其他的缓存,系统依然能继续运行。
6.2 余数分布式算法
就是“根据服务器台数的余数进行分散”。求得键的整数哈希值,再除以服务器台数,根据其余数来选择服务器
余数算法的缺点
余数计算的方法简单,数据的分散性也相当优秀,但也有其缺点。那就是当添加或移除服务器时,缓存重组的代价相当巨大。添加服务器后,余数就会产生巨变,这样就无法获取与保存时相同的服务器,从而影响缓存的命中。
6.3Consistent Hashing(一致哈希)
知识补充:哈希算法,即散列函数。将任意长度的二进制值映射为较短的固定长度的二进制值,这个小的二进制值称为哈希值。哈希值是一段数据唯一且极其紧凑的数值表示形式。如果散列一段明文而且哪怕只更改该段落的一个字母,随后的哈希都将产生不同的值。要找到散列为同一个值的两个不同的输入,在计算上是不可能的,所以数据的哈希值可以检验数据的完整性。一般用于快速查找和加密算法。(常见的有MD5,SHA-1)
Consistent Hashing 的简单说明
Consistent Hashing 如下所示:首先求出memcached 服务器(节点)的哈希值(一般的方法可以使用 cache 机器的 IP 地址或者机器名作为 hash 输入。),并将其配置到0~232 的圆(continuum)上。然后用同样的方法求出存储数据的键的哈希值,并映射到圆上。然后从数据映射到的位置开始顺时针查找,将数据保存到找到的第一个服务器上。如果超过232仍然找不到服务器,就会保存到第一台memcached 服务器上。
从上图的状态中添加一台memcached 服务器。余数分布式算法由于保存键的服务器会发生巨大变化,而影响缓存的命中率,但Consistent Hashing中,只有在continuum 上增加服务器的地点逆时针方向的第一台服务器上的键会受到影响
Consistent hashing 的基本思想就是将对象和 cache 都映射到同一个 hash 数值空间中,并且使用相同的 hash 算法。
现在 cache 和对象都已经通过同一个 hash 算法映射到 hash 数值空间中了,接下来要考虑的就是如何将对象映射到 cache 上面了。
在这个环形空间中,如果沿着顺时针方向从对象的 key 值出发,直到遇见一个 cache ,那么就将该对象存储在这个 cache 上,因为对象和 cache 的 hash 值是固定的,因此这个 cache 必然是唯一和确定的。这样不就找到了对象和 cache 的映射方法了吗?
Consistent Hashing:添加服务器
因此,Consistent Hashing 最大限度地抑制了键的重新分布。而且,有的Consistent Hashing 的实现方法还采用了虚拟节点的思想。使用一般的hash函数的话,服务器的映射地点的分布非常不均匀。因此,使用虚拟节点的思想,为每个物理节点(服务器)在continuum上分配100~200 个点。这样就能抑制分布不均匀,最大限度地减小服务器增减时的缓存重新分布。
存储命令
<command name> <key> <flags> <exptime> <bytes>\r\n
- <command name> 是set, add,或者repalce
- <key> 是接下来的客户端所要求储存的数据的键值
- <flags> 是在取回内容时,与数据和发送块一同保存服务器上的任意16位无符号整形(用十进制来书写)。客户端可以用它作为“位域”来存储一些特定的信息;它对服务器是不透明的。
- <exptime> 是终止时间。如果为0,该项永不过期(虽然它可能被删除,以便为其他缓存项目腾出位置)。如果非0(Unix 时间戳或当前时刻的秒偏移),到达终止时间后,客户端无法再获得这项内容。
- <bytes> 是随后的数据区块的字节长度,不包括用于分野的“\r\n”。它可以是0(这时后面跟随一个空的数据区块)。
- <data block> 是大段的8位数据,其长度由前面的命令行中的<bytes>指定。
• set 意思是“储存此数据”
• add 意思是“储存此数据,只在服务器*未*保留此键值的数据时”
• replace 意思是“储存此数据,只在服务器*曾*保留此键值的数据时”
发送命令行和数据区块以后,客户端等待回复,可能的回复如下:
- "STORED\r\n"表明成功.
- "NOT_STORED\r\n"表明数据没有被存储,但不是因为发生错误。这通常意味着add或replace 命令的条件不成立,或者,项目已经位列删除队列(参考后文的“delete”命令)。
取回命令
get <key>*\r\n
- <key>* 表示一个或多个键值,由空格隔开的字串这行命令以后,客户端的等待0个或多个项目,每项都会收到一行文本,然后跟着数据区块。所有项目传送完毕后,服务器发送以下字串:"END\r\n"来指示回应完毕,服务器用以下形式发送每项内容:
VALUE <key> <flags> <bytes>\r\n
<data block>\r\n
- <key> 是所发送的键名
- <flags> 是存储命令所设置的记号
- <bytes> 是随后数据块的长度,*不包括* 它的界定符“\r\n”
- <data block> 是发送的数据
如果在取回请求中发送了一些键名,而服务器没有送回项目列表,这意味着服务器没这些键名(可能因为它们从未被存储,或者为给其他内容腾出空间而被删除,或者到期,或者被已客户端删除)。
删除
delete <key> <time>\r\n
- <key> 是客户端希望服务器删除的内容的键名
- <time> 是一个单位为秒的时间(或代表直到某一刻的Unix时间),在该时间内服务器会拒绝对于此键名的“add”和“replace”命令。此时内容被放入delete队列,无法再通过“get”得到该内容,也无法是用“add”和“replace”命令(但是“set”命令可用)。直到指定时间,这些内容被最终从服务器的内存中彻底清除。<time>参数是可选的,缺省为0(表示内容会立刻清除,并且随后的存储命令均可用)。
此命令有一行回应:- "DELETED\r\n"表示执行成功
- "NOT_FOUND\r\n"表示没有找到这项内容
增加/减少
命令“incr”和“decr”被用来修改数据,当一些内容需要替换、增加或减少时。这些数据必须是十进制的32位无符号整新。如果不是,则当作0 来处理。修改的内容必须存在,当使用“incr”/“decr”命令修改不存在的内容时,不会被当作0处理,而是操作失败。
客户端发送命令行:
incr <key> <value>\r\n或decr <key> <value>\r\n
- <key> 是客户端希望修改的内容的建名
- <value> 是客户端要增加/减少的总数。
回复为以下集中情形:
- "NOT_FOUND\r\n"指示该项内容的值,不存在。
- <value>\r\n ,<value>是增加/减少。
注意"decr"命令发生下溢:如果客户端尝试减少的结果小于0 时,结果会是0。"incr" 命令不会发生溢出。
状态
命令"stats" 被用于查询服务器的运行状态和其他内部数据。有两种格式。不带参数的:
stats\r\n
这会在随后输出各项状态、设定值和文档。另一种格式带有一些参数:
stats <args>\r\n
通过<args>,服务器传回各种内部数据。因为随时可能发生变动,本文不提供参数的种类及其传回数据。
各种状态
受到无参数的"stats"命令后,服务器发送多行内容,如下:
STAT <name> <value>\r\n
服务器用以下一行来终止这个清单:END\r\n,在每行状态中,<name> 是状态的名字,<value>使状态的数据。以下清单,是所有的状态名称,数据类型,和数据代表的含义。
在“类型”一列中,"32u"表示32 位无符号整型,"64u"表示64 位无符号整型,"32u:32u"表示用冒号隔开的两个32 位无符号整型。
名称 |
类型 |
含义 |
pid |
32u |
服务器进程ID |
uptime |
32u |
服务器运行时间,单位秒 |
time |
32u |
服务器当前的UNIX时间 |
version |
string |
服务器的版本号 |
rusage_user |
32u |
该进程累计的用户时间(秒:微妙) |
rusage_system |
32u |
该进程累计的系统时间(秒:微妙) |
curr_items |
32u |
服务器当前存储的内容数量 |
total_items |
32u |
服务器启动以来存储过的内容总数 |
bytes |
64u |
服务器当前存储内容所占用的字节数 |
curr_connections |
32u |
连接数 |
total_connections |
32u |
服务器运行以来接受的连接总数 |
connection_structures |
32u |
服务器分配的连接结构的数量 |
cmd_get |
32u |
取回请求总数 |
cmd_set |
32u |
存储请求总数 |
get_hits |
32u |
请求成功的总次数 |
get_misses |
32u |
请求失败的总次数 |
bytes_read |
64u |
服务器从网络读取到的总字节数 |
bytes_written |
64u |
服务器向网络发送的总字节数 |
limit_maxbytes |
32u |
服务器在存储时被允许使用的字节总数 |
如果不想每次通过输入stats来查看memcache状态,可以通过echo "stats" |nc ip port 来查看,例如:echo "stats" | nc 127.0.0.1 9023。
转自https://blog.csdn.net/xifeijian/article/details/21994941
转自https://my.oschina.net/bieber/blog/505458