@phper
2016-09-03T13:20:14.000000Z
字数 16699
阅读 7842
memcache
memcached 是一个高效支持多线程的内存存储系统。接下来会从安装、使用、内存分配一步步来分析memcached。
[root@web3 vagrant]# wget http://downloads.sourceforge.net/levent/libevent-2.0.22-stable.tar.gz
[root@web3 vagrant]# tar zxvf libevent-2.0.22-stable.tar.gz
[root@web3 vagrant]# cd libevent-2.0.22-stable
[root@web3 vagrant]# ./configure --prefix=/usr/local/libevent-2.0.22
[root@web3 vagrant]# make
[root@web3 vagrant]# make install
[root@web3 vagrant]# wget http://memcached.org/files/memcached-1.4.29.tar.gz
[root@web3 vagrant]# tar zxvf memcached-1.4.29.tar.gz
[root@web3 vagrant]# cd memcached-1.4.29
[root@web3 memcached-1.4.29]# ./configure --prefix=/usr/local/memcached-1.4.25 --with-libevent=/usr/local/libevent-2.0.22
[root@web3 memcached-1.4.29]# make
[root@web3 memcached-1.4.29]# make install
[root@web3 memcached-1.4.29]# cd /usr/local/memcached-1.4.25/
[root@web3 memcached-1.4.25]# ls
bin include share
[root@web3 memcached-1.4.25]# cd bin/
[root@web3 bin]# ls
memcached
[root@web3 bin]# cp memcached /usr/bin/memcached
[root@web3 bin]#
[root@web3 bin]# memcached -h
memcached 1.4.29
[root@web3 bin]# memcached -p 11211 -m 64 -u root -vv
slab class 1: chunk size 96 perslab 10922
slab class 2: chunk size 120 perslab 8738
slab class 3: chunk size 152 perslab 6898
slab class 4: chunk size 192 perslab 5461
slab class 5: chunk size 240 perslab 4369
slab class 6: chunk size 304 perslab 3449
slab class 7: chunk size 384 perslab 2730
slab class 8: chunk size 480 perslab 2184
slab class 9: chunk size 600 perslab 1747
slab class 10: chunk size 752 perslab 1394
slab class 11: chunk size 944 perslab 1110
slab class 12: chunk size 1184 perslab 885
slab class 13: chunk size 1480 perslab 708
slab class 14: chunk size 1856 perslab 564
slab class 15: chunk size 2320 perslab 451
slab class 16: chunk size 2904 perslab 361
slab class 17: chunk size 3632 perslab 288
slab class 18: chunk size 4544 perslab 230
slab class 19: chunk size 5680 perslab 184
slab class 20: chunk size 7104 perslab 147
slab class 21: chunk size 8880 perslab 118
slab class 22: chunk size 11104 perslab 94
slab class 23: chunk size 13880 perslab 75
slab class 24: chunk size 17352 perslab 60
slab class 25: chunk size 21696 perslab 48
slab class 26: chunk size 27120 perslab 38
slab class 27: chunk size 33904 perslab 30
slab class 28: chunk size 42384 perslab 24
slab class 29: chunk size 52984 perslab 19
slab class 30: chunk size 66232 perslab 15
slab class 31: chunk size 82792 perslab 12
slab class 32: chunk size 103496 perslab 10
slab class 33: chunk size 129376 perslab 8
slab class 34: chunk size 161720 perslab 6
slab class 35: chunk size 202152 perslab 5
slab class 36: chunk size 252696 perslab 4
slab class 37: chunk size 315872 perslab 3
slab class 38: chunk size 394840 perslab 2
slab class 39: chunk size 493552 perslab 2
slab class 40: chunk size 616944 perslab 1
slab class 41: chunk size 771184 perslab 1
slab class 42: chunk size 1048576 perslab 1
<26 server listening (auto-negotiate)
<27 server listening (auto-negotiate)
<28 send buffer was 124928, now 268435456
<32 send buffer was 124928, now 268435456
<30 server listening (udp)
<34 server listening (udp)
<31 server listening (udp)
<35 server listening (udp)
<29 server listening (udp)
<33 server listening (udp)
<28 server listening (udp)
<32 server listening (udp)
启动时候,常用的命令:
[root@web3 bin]# memcached -h #可以看所有的命令
由于命令很多,看几个常见的命令:
-p
<num>
指定服务TCP端口,默认为11211,默认会监听tcp和udp端口。
比如:memcached -p 11200 表示监听11200端口
-m
<num>
分配给memcached用作缓存的内存大小,单位为MB,默认64M
比如:memcached -m 1024 表示分配1g的内存给memcached
-u 是运行Memcache的用户,如果当前为 root 的话,则必须使用此参数指定用户,不然会报错:can't run as root without the -u switch
比如:memcached -u yangyi 表示用yangyi 这个帐户运行memcached
-l
<ip>
,小写的字母l, 监听的 IP 地址。本机的话不用设置。-f chunk size的增长因子(合理范围1.05~2,默认:1.25)。
-t
<num>
Memcached启动的工作线程数
,默认为4,建议不要超过系统 CPU的个数。-c 最大同时连接数,默认是1024。
-I
<num>
大写的字母 i ,改变slab page的容量大小,以调整ITEM容量的最大值,默认为1MB。最大可以支持128M-vv 输出详细的信息。
-d 启动一个守护进程,后台运行。
-P 指定pid的路径
比如:memcached -P /tmp/memcached.pid
-h 打印版本和帮助信息,然后退出。
memcached的命令分为以下5个大类。
set/add/replace/append/prepend/cas
存储命令的格式:
<command> <key> <flags> <exptime> <bytes> [<version>]
<datablock>
<status>
详细看下面的表格:
参数 | 说明 |
---|---|
command | set无论如何都进行存储,add只有数据不存在时进行添加 |
key | 存储的key的名字,长度最多为250个字符,不包含空格和控制字符 |
flags | 是一个16位的无符号的整数(以十进制的方式表示)。该标志将和需要存储的数据一起存储,并在客户端get数据时返回 |
exptime | 过期时间,单位为秒,0为永远,表示用不过期,<30天60*60*24*30为秒数,>30天为unixtime时间戳 |
bytes | byte字节数,不包含\r\n,根据长度截取存/取的字符串,可以是0,即存空串 |
version | 版本号,可选的,可不写,这个字断主要是给cas命令用 |
datablock | 储存的内容value,以\r\n结尾,当然可以包含\r或\n |
status | STORED/NOT_STORED/EXISTS/NOT_FOUND/ERROR/CLIENT_ERROR/SERVER_ERROR服务端返回的状态标志 |
用telnet连接一下,来实际操作下。
链接:
telnet 192.168.33.13 11211
Trying 192.168.33.13...
Connected to 192.168.33.13.
Escape character is '^]'.
# 1. set key flag exptime bytes
# flag 是一个16位的无符号的整数标记,这里我们随便设置成一个数字16吧。
set name 16 10 5 #设置name 为 5个字符,过期时间为10秒
12345
STORED #成功
get name #读取name的值
VALUE name 16 5
12345
END
set name 16 10 5
1234
CLIENT_ERROR bad data chunk
ERROR #字符长度不符合,报错。
get name
END #过期了,没取到值
set name 16 0 5
123456
CLIENT_ERROR bad data chunk
ERROR #字符长度不符合,报错。
set name 16 0 5 #设置为不过期
12345
STORED
get name
VALUE name 16 5
12345
END #正确返回值
set name2 16 2592000 3 #设置为刚好30天过期
123
STORED #成功
get name2
VALUE name2 16 3
123
END # 成功取出数据
set name2 16 2592001 3 #30天多一秒
123
STORED #成功了
get name2
END #但是取不到数据了!!!
set name3 16 1476961243 5 #所以如果设置超过30天的过期时间时,就要用时间戳作为过期时间
12345
STORED
get name3
VALUE name3 16 5
12345
END #成功。
# 2.add只能添加不存在的Key
add name 16 1476961243 5 #使用add命令,会判断这个key是否存在
12345
NOT_STORED #报错,没有存储成功,因为已经存在了。
add name4 16 0 4
1234
STORED #添加一个不存在的key就成功了。
get name4
VALUE name4 16 4
1234 #成功取到
END
# 3. replace 替换一个key的值,必须要已存在的。而且过期时间也会替换掉之前的。
replace name4 17 100 5 #替换 name4的flag,expiretime,bytes
12345
STORED #成功了。
get name4
VALUE name4 17 5
12345 #成功取出
END
replace name4 16 3 2 #替换expiretime为3秒
12
STORED
get name4 #已过期。
END
replace name5 16 0 4 # 替换一个不存在的key name5
1234
NOT_STORED #报错没有存储成功
# 4. append 在一个key 的 value 后面追加字符。
# 注意:追加不会破坏原先的过期时间。
set name 16 0 4
1234
STORED
append name 16 3 2 #在后面追加2个字符12,并改变flag和expiretime
12
STORED 成功了。
get name
VALUE name 16 6
123412 # 成功取出,而且过期时间不受影响。
END
# 5. prepend 在一个 key 的 value 前面追加字符。
# 注意:追加不会破坏原先的过期时间。
set name 16 0 5
12345
STORED
prepend name 16 0 2 #在前面追加
67
STORED #成功
get name
VALUE name 16 7
6712345 #成功
END
prepend name 16 3 1 #改变过期时间为3秒。
8
STORED #成功
get name #3秒之后访问,仍让还在。
VALUE name 16 8
86712345
END
# 6. cas即check and set,只有版本号相匹配时才能存储,否则返回EXISTS。
版本号的概念 在讲 gets 命令时,一起说。
get/gets
读取命令的格式为:
get/gets key1 key2 ...keyn
返回值为:
get/gets key1... keyn
VALUE <key1> <flags> <bytes> [<version>]
<value1>
…
VALUE <keyn> <flags> <bytes> [<version>]
<valuen>
END
gets较get命令,会多返回一个版本号 version, 用于标识名称/值对, 每次set 新的 value后,verison都会变化。
看栗子吧:
#1. get 同时get2个key的值
get name name4
VALUE name 16 1 #返回了key的名字、flag、以及bytes
2
VALUE name4 16 3
123
END
#2. gets 会多返回一个version
gets name name4
VALUE name 16 1 31 #version为31
2
VALUE name4 16 3 32 #version 为32
123
END
set name4 16 0 3
456
STORED #改变name4的值
gets name4
VALUE name4 16 3 33 #version 改变了
456
END
gets命令会多返回一个version值。那么就可以说上面没说完的cas
命令了:
cas <key> <flag> <verion> <bytes> <version>
cas
(check 和 set),给一个已经存在的key设置新的value,但是它会先检查 version和它gets的version是否一致,如果是一致的,则会生效,否则会报错 EXISTS。
看下栗子:
gets name4
VALUE name4 16 3 33 #version 为33
456
END
cas name4 16 0 2 30 #我们输入version为30
12
EXISTS #失败,说已经存在。
cas name4 16 0 2 33 #输入一样的version
12
STORED #成功
gets name4
VALUE name4 16 2 34 #并且生成新的version
12
END
delete
删除命令最简单了,删除一个key,只能一个一个的删,不能批量
delete key1
直接上栗子:
delete name4
DELETED #成功
get name4
END
delete name name3
CLIENT_ERROR bad command line format. Usage: delete <key> [noreply] #报错,不能批量删除
incr/decr
计数命令,用来对value为int数字型的key进行加n或者减n操作。
用法为:
incr key number
value + number
decr key number
value - number
直接看栗子:
# 1. incr 增加
set name 16 0 2
12
STORED
incr name 1 #成功,并返回加1的value
13
# 2. decr 减少
decr name 10 #减去10,返回了3
3
decr name 10 #继续减10,就直接返回0了
0
decr name 10 #返回0
0
#设置为字符串
get name5
VALUE name5 16 3 #字符串
qwe
END
incr name5 1 #报错,说不能增加或者减少非数字型
CLIENT_ERROR cannot increment or decrement non-numeric value
stats/settings/items/sizes/slabs
统计命令,主要是来维护和统计memcached的一些命令,属于管理命令来。
stats 命令用来统计memcached的运行状态:
运行看一下:
stats
STAT pid 9752 #memcached运行的进程pid
STAT uptime 50034 #memcached的运行时间(秒)
STAT time 1469232745 #当前的UNIX时间戳
STAT version 1.4.29 #memcached的版本号
STAT libevent 2.0.22-stable #memcached使用的libevent的版本号
STAT pointer_size 64 #操作系统的位数,32或64。我这里是64位
STAT rusage_user 8.855653 #该进程累计的用户时间(秒)
STAT rusage_system 26.481974 #该进程累计的系统时间(秒)
STAT curr_connections 10 #当前连接数
STAT total_connections 12 #服务器运行以来接受的连接总数
STAT connection_structures 12 #Memcached分配的连接结构的数量
STAT reserved_fds 20 #misc fds使用数
STAT cmd_get 81 #get命令执行的次数
STAT cmd_set 47 #set命令执行的次数
STAT cmd_flush 0 #flush_all命令执行的次数
STAT cmd_touch 0 #执行touch的次数,touch可以刷新过期时间
STAT get_hits 59 #命中的次数,获取数据成功的次数
STAT get_misses 22 #没有命中的次数,获取数据失败的次数
STAT get_expired 7 #
STAT get_flushed 0
STAT delete_misses 0 #delete未命中次数
STAT delete_hits 1 #delete命中次数
STAT incr_misses 0 #incr命中次数
STAT incr_hits 3 #incr未命中次数
STAT decr_misses 0 #decr未命中次数
STAT decr_hits 3 #decr命中次数
STAT cas_misses 0 #cas未命中次数
STAT cas_hits 3 #cas命中次数
STAT cas_badval 2 #使用擦拭次数
STAT touch_hits 0 #touch命中次数
STAT touch_misses 0 #touch未命中次数
STAT auth_cmds 0 #authentication 执行的次数
STAT auth_errors 0 #authentication 执行失败的次数
STAT bytes_read 2724 #memcached服务器从网络读取的总的字节数
STAT bytes_written 8610 #memcached服务器发送到网络的总的字节数。
STAT limit_maxbytes 67108864 #memcached服务缓存允许使用的最大字节数。这里为67108864字节,也就是是64M.与我们启动memcached服务设置的大小一致。
STAT accepting_conns 1 #正在接受的连接数
STAT listen_disabled_num 0 #拒绝连接尝试的次数,因为memcached的达到其配置的连接限制("-C"参数)。
STAT time_in_listen_disabled_us 0
STAT threads 4 #当前Memcached服务器使用的线程数。("-t" 参数指定)
STAT conn_yields 0 #memcached 启动至今有多少次打开的连接因为内部请求数达到 -R 参数指定的限值而被动放弃
STAT hash_power_level 16 #hashpower的level,可以在启动的时候设置($ memcached -o hashpower=20)
STAT hash_bytes 524288 #内存使用总量单位为byte
STAT hash_is_expanding 0 #是否正在扩大hash表
STAT malloc_fails 0
STAT log_worker_dropped 0
STAT log_worker_written 0
STAT log_watcher_skipped 0
STAT log_watcher_sent 0
STAT bytes 146 #当前memcached服务器上保存数据的字节数
STAT curr_items 2 #当前在memcached服务器上存储的数据项的个数
STAT total_items 38 #在服务器上曾经保存过的数据项的总数
STAT expired_unfetched 0
STAT evicted_unfetched 0
STAT evictions 0 #因超时而被替换出内存的数据项的个数
STAT reclaimed 2 # memcached 启动至今有多少次在存储数据的时候使用了过期数据的空间
STAT crawler_reclaimed 0
STAT crawler_items_checked 0
STAT lrutail_reflocked 0
END
stats 还有几个子命令集合,这些等我们说完memcached的存储和结构后再来看。
前面基本上把memcache的安装和使用说的差不多了,基本可以正常友好的使用memcached了。现在我们来看下memcached的内存分配和管理机制。
在熟悉memcached的内存管理之前,我们先拿小学生的格子作业本
来举例子,把格子本比作memcached的内存分配。每个作业本(memcached的内存空间),它都有很页(slab),每一页里面有很多方格子(trunk),每个格子里面可以写字(item)。
在脑海中有这样一个印象之后,我们开始讲上面提到的几个名词:
上面说到的格子本的一页纸,就一个是slab
, 是memcached分配的一块内存空间,默认大小为1M。memcached会将内存空间分配成一个一个的slab,还会把一个slab分割成一个一个的格子,也就是一个一个chunk,比如说1M的slab分成两个0.5M的chunk,slab和chunk其实都是代表实质的内存空间,chunk是slab分割后的更小的单元。所以:slab就相当于作业本中的“一页纸”,而chunk则是把这一页纸中的一个个的“格子”。
item是我们要保存的数据,也就是我们需要在“格子”中写入的“字”。
比如,在PHP中我们这样设置一个缓存:
$memcached->set(“name”,”abc”,30);
这行代码代表我们把一个key为name,value为abc的键值对保存在内存中30秒,那么上述中的”name”、 “abc”、“30”这些数据实质都是我们要memcached保存下来的数据, memcached会把这些数据打包成一个item,把打包好的item填充到chunk中,一个item保存在一个chunk。chunk是实质的内存空间,item是要保存的东西,所以关系是:item是往chunk中塞的。
还是拿作业本来比喻,item就是相当于我们要写的“字”,把它写到作业本某一“页(slab)”中的“格子(chunk)”里。
通过上面我们知道,slab(都假设为1M)会割成一个个chunk,而item往chunk中塞。
那么问题来了:
我们要把这个1M的slab割成多少个chunk?就是一页纸,要画多少个格子?
我们往chunk中塞item的时候,item总不可能会与chunk的大小完全匹配吧,chunk太小塞不下或者chunk太大浪费了怎么办?就是我们写字的时候,格子太小,字出界了,或者我们的字很小写在一个大格子里面好浪费。
所以memcached的设计是,我们会准备“几种不同格子的slab”,也就是说根据“slab分割的chunk的大小不一样”来分成“不同的种类的slab”,而 slabclass就是“slab的种类”的意思了。
继续拿作业本来比喻:假设我们现在有很多张A4纸,有些我们画成100个格子,有些我们画成200个格子,有些300,我们把画了相同个格子(也相同大小)的纸钉在一起,成为一本本“作业本”,每本“作业本”的格子大小都是一样的,不同的“作业本”也代表着“画了不同的大小格子的A4纸的集合”,而这个作业本就是slabclass啦!
所以当你要写字(item)的时候,你估一下你的字有多“大”,然后挑一本作业本(slabclass),在某一页(slab)空白的格子(chunk)上写。
每个slabclass在memcached中都表现为一个结构体,里面会有个指针,指向它的那一堆slab。
slab是一个内存块,它是memcached一次申请内存的最小单位。在启动memcached的时候一般会使用参数-m
指定其可用的最大内存,在启动的时候memcached并不会把有的内存就全部分配出去了,只有在需要的时候才会去申请,而且每次申请一定是一个slab。Slab的大小固定为1M(1048576Byte),一个slab由若干个大小相等的chunk组成。每个chunk中都保存了一个item结构体。
虽然在同一个slab中chunk的大小相等的,但是在不同的slab中chunk的大小并不一定相等,在memcached中按照chunk的大小不同,可以把slab分为很多种类(slab class)。一个 slabclass 中包含若干相同 trunk 大小的slab list。
所以总结下,看下这张图:
可以在启动memcached的时候可以通过-vv来查看slab的种类:
[root@web3 bin]# memcached -p 11211 -m 64 -u root -vv
slab class 1: chunk size 96 perslab 10922
slab class 2: chunk size 120 perslab 8738
slab class 3: chunk size 152 perslab 6898
slab class 4: chunk size 192 perslab 5461
slab class 5: chunk size 240 perslab 4369
slab class 6: chunk size 304 perslab 3449
slab class 7: chunk size 384 perslab 2730
slab class 8: chunk size 480 perslab 2184
slab class 9: chunk size 600 perslab 1747
slab class 10: chunk size 752 perslab 1394
slab class 11: chunk size 944 perslab 1110
slab class 12: chunk size 1184 perslab 885
slab class 13: chunk size 1480 perslab 708
slab class 14: chunk size 1856 perslab 564
slab class 15: chunk size 2320 perslab 451
slab class 16: chunk size 2904 perslab 361
slab class 17: chunk size 3632 perslab 288
slab class 18: chunk size 4544 perslab 230
slab class 19: chunk size 5680 perslab 184
slab class 20: chunk size 7104 perslab 147
slab class 21: chunk size 8880 perslab 118
slab class 22: chunk size 11104 perslab 94
slab class 23: chunk size 13880 perslab 75
slab class 24: chunk size 17352 perslab 60
slab class 25: chunk size 21696 perslab 48
slab class 26: chunk size 27120 perslab 38
slab class 27: chunk size 33904 perslab 30
slab class 28: chunk size 42384 perslab 24
slab class 29: chunk size 52984 perslab 19
slab class 30: chunk size 66232 perslab 15
slab class 31: chunk size 82792 perslab 12
slab class 32: chunk size 103496 perslab 10
slab class 33: chunk size 129376 perslab 8
slab class 34: chunk size 161720 perslab 6
slab class 35: chunk size 202152 perslab 5
slab class 36: chunk size 252696 perslab 4
slab class 37: chunk size 315872 perslab 3
slab class 38: chunk size 394840 perslab 2
slab class 39: chunk size 493552 perslab 2
slab class 40: chunk size 616944 perslab 1
slab class 41: chunk size 771184 perslab 1
slab class 42: chunk size 1048576 perslab 1
<26 server listening (auto-negotiate)
<27 server listening (auto-negotiate)
<28 send buffer was 124928, now 268435456
<32 send buffer was 124928, now 268435456
<30 server listening (udp)
<34 server listening (udp)
<31 server listening (udp)
<35 server listening (udp)
<29 server listening (udp)
<33 server listening (udp)
<28 server listening (udp)
<32 server listening (udp)
memcached把slab分为40类(class1~class40),在class 1中,chunk的大小为96字节,由于一个slab的大小是固定的1048576字节(1M),因此在class1中最多可以有perslab = 10922个chunk:
10922×80 + 64 = 1048576
在class1中,剩余的64字节因为不够一个chunk的大小(96byte),因此会被浪费掉。
每类chunk的大小有一定的计算公式的,假定i代表分类,class i的计算公式如下:
chunk size(class i) = (default_size+item_size)*f^(i-1) + CHUNK_ALIGN_BYTES
所以,我们可以根据自己的业务需求,通过-f
和 -n
参数,来合理划分trunk的大小。
我们,来修改下-f
和 -n
来重新启动下memcached:
[root@web3 ~]# memcached -u root -m 64 -p 11211 -n 80 -vv
slab class 1: chunk size 128 perslab 8192
slab class 2: chunk size 160 perslab 6553
slab class 3: chunk size 200 perslab 5242
slab class 4: chunk size 256 perslab 4096
slab class 5: chunk size 320 perslab 3276
slab class 6: chunk size 400 perslab 2621
slab class 7: chunk size 504 perslab 2080
slab class 8: chunk size 632 perslab 1659
slab class 9: chunk size 792 perslab 1323
slab class 10: chunk size 992 perslab 1057
slab class 11: chunk size 1240 perslab 845
slab class 12: chunk size 1552 perslab 675
slab class 13: chunk size 1944 perslab 539
slab class 14: chunk size 2432 perslab 431
slab class 15: chunk size 3040 perslab 344
slab class 16: chunk size 3800 perslab 275
slab class 17: chunk size 4752 perslab 220
slab class 18: chunk size 5944 perslab 176
slab class 19: chunk size 7432 perslab 141
slab class 20: chunk size 9296 perslab 112
slab class 21: chunk size 11624 perslab 90
slab class 22: chunk size 14536 perslab 72
slab class 23: chunk size 18176 perslab 57
slab class 24: chunk size 22720 perslab 46
slab class 25: chunk size 28400 perslab 36
slab class 26: chunk size 35504 perslab 29
slab class 27: chunk size 44384 perslab 23
slab class 28: chunk size 55480 perslab 18
slab class 29: chunk size 69352 perslab 15
slab class 30: chunk size 86696 perslab 12
slab class 31: chunk size 108376 perslab 9
slab class 32: chunk size 135472 perslab 7
slab class 33: chunk size 169344 perslab 6
slab class 34: chunk size 211680 perslab 4
slab class 35: chunk size 264600 perslab 3
slab class 36: chunk size 330752 perslab 3
slab class 37: chunk size 413440 perslab 2
slab class 38: chunk size 516800 perslab 2
slab class 39: chunk size 646000 perslab 1
slab class 40: chunk size 807504 perslab 1
slab class 41: chunk size 1048576 perslab 1
<26 server listening (auto-negotiate)
<27 server listening (auto-negotiate)
<28 send buffer was 124928, now 268435456
<32 send buffer was 124928, now 268435456
<30 server listening (udp)
<34 server listening (udp)
<31 server listening (udp)
<35 server listening (udp)
<29 server listening (udp)
<33 server listening (udp)
<28 server listening (udp)
<32 server listening (udp)
可以看见class1的chunk大小为:80+48字节,根据具体的业务预估缓存数据的最小值以便设置memcache的chunk初始值,避免内存浪费。
memcache默认的slab大小是1M,所以不能存入大小超过1M的数据,但一旦需要存入大数据时可以使用-I
参数来设置slab的值,但是不推荐将slab值设置为超过1M。
向memcached添加一个item时候,memcached首先会根据item的大小,来选择最合适的slabclass。例如item的大小为190字节。
slab class 3: chunk size 152 perslab 6898
slab class 4: chunk size 192 perslab 5461
默认情况下slb class 4的chunk大小为192字节,因此是可以放到在class4中(显然这里会有2字节的浪费是不可避免的),计算好所要放入的chunk之后,memcached会去检查该类大小的chunk还有没有空闲的,如果没有,将会申请1M(1个slab)的slab class4 空间并划分为该种类chunk。
例如我们第一次向memcached中放入一个190字节的item时,memcached会使用slab class4,并会用去一个chunk,剩余5460个chunk供下次有适合大小item时使用,当我们用完这所有的5460个chunk之后,下次再有一个在152~192字节之间的item添加进来时,memcached会再申请空间生成一个class4的slab(这样就存在了2个slab class4)。
memcached是懒检测机制,当存储在内存中的对象过期甚至是flush_all时,它并不会做检查或删除操作,只有在get时才检查数据对象是否应该删除。删除数据时,Memcached同样是懒删除机制,只在对应的数据对象上做删除标识并不回收内存,在下次分配时直接覆盖使用。
所以,当memcached过期或者删除的时候,它所占用的内存并不会释放,除非重新启动。
参考:
http://www.cnblogs.com/moqiang02/p/4061151.html
http://blog.csdn.net/clh604/article/details/39401249
http://blog.wpjam.com/m/php-memcached-persistent-mode/
http://blog.csdn.net/wangsg2014/article/details/17451273
http://www.dexcoder.com/selfly/article/2248
http://www.dexcoder.com/selfly/article/2388
http://blog.csdn.net/lgh1117/article/details/11742023
http://calixwu.com/2014/11/memcached-yuanmafenxi-neicunguanli.html