memcached工作原理
基本概念:slab,page,chunk。
slab,是一个逻辑概念。它是在启动memcached实例的时候预处理好的,每个slab对应一个chunk size,也就是说不同slab有不同的chunk size。具体分配多少个slab由参数 -f (增长因子)和 -n (chunk最小尺寸)决定的。
page,可以理解为内存页。大小固定为1m。slab会在存储请求时向系统申请page,并将page按chunk size进行切割。
chunk,是保存用户数据的最小单位。用户数据item(包括key,value)最终会保存到chunk内。chunk规格是固定的,如果用户数据放进来后还有剩余则这剩余部分不能做其他用途。
memcached工作流程
memcahed实例启动,根据 -f 和 -n 进行预分配slab。以 -n 为最小值开始,以 -f 为比值生成等比数列,直到1m为止(每个slab的chunk size都要按8的倍数进行补全,比如:如果按比值算是556的话,会再加4到560成为8的整倍数)。然后每个slab分配一个page。当用户发来存储请求时(key,value),memcached会计算key+value的大小,看看属于哪个slab。确定slab后看里面的是否有空闲chunk放key+value,如果不够就再向系统申请一个page(如果此时已经达到 -m 参数设置的内存使用上限,则看是否设置了 -M 。如果设置了 -M 则返回错误提示,否则按LRU算法删除数据)。申请后将该page按本slab的chunk size 进行切割,然后分配一个来存放用户数据。
注意:
1)chunk是在page里面划分的,而page固定为1m,所以chunk最大不能超过1m。
2)chunk实际占用内存要加48B,因为chunk数据结构本身需要占用48B。
3)如果用户数据大于1m,则memcached会将其切割,放到多个chunk内。
4)已分配出去的page不能回收。
优化建议
1)-n 参数的设置,注意将此参数设置为1024可以整除的数(还要考虑48B的差值),否则余下来的部分就浪费了。
2)不要存储超过1m的数据。因为要拆成多个chunk,计算和时间成本都成倍增加。
3)善用stats命令查看memcached状态。
4)消灭eviction(被删除的数据)。
造成eviction是因为内存不够,有三个思路:
(1)在CPU有余力的情况下开启压缩(PHP扩展);
(2)增加内存;
(3)调整-f参数,减少内存浪费。
5)调整业务代码,提高命中率。
6)缓存小数据。省带宽,省网络I/O时间,省内存。
7)根据业务特点,为数据尺寸区间小的业务分配专用的memcached实例。这样可以调小 -f 参数,使数据集中存在少数几个slab上,内存浪费较少。
启动时最重要的参数:
-m 整个memcached最大内存
-f chunk大小增长因子
-n chunk最小分配空间
-C 禁用CAS
-vvv 打印详细信息
我们通过计算可以看出,每个slab的chunk size大小都是上一个大小的1.25倍,1.25就是memcached启动时制定的-f的值,所以,要根据不同的业务场景调整,既要尽可能少的减少内存浪费,又要存得下我们业务中的数据,再举个例子,加入我们的业务很BT,大小都是200kb,我们该怎么做?那当然是要保证我们申请的chunk大小都是200kb了,虽然memcached并不支持这么做。假如创建了38个slabs,最后数据全都落到了第20-25个slab中,那0-19和26-38的内存就被浪费了,这只是能评估出来的,还有一种情况,加入我们的chunk大小是500kb,数据才200kb,因为每个chunk都只能存储一个,所以一个chunk就会有500kb-200kb的空间浪费,如果有一千万个chunk要存,那将会浪费多少空间?所以,在使用memcached之前,先要评估你的数据,根据它去调整-f因子。
memcached参数使用介绍(Win7用户要以管理员身份启动命令窗口哦!) -p 监听的端口 -l 连接的IP地址, 默认是本机 -d start 启动memcached服务 -d restart 重起memcached服务 -d stop|shutdown 关闭正在运行的memcached服务 -d install 安装memcached服务 -d uninstall 卸载memcached服务 -u 以的身份运行 (仅在以root运行的时候有效) -m 最大内存使用,单位MB。默认64MB -M 内存耗尽时返回错误,而不是删除项 -c 最大同时连接数,默认是1024 -f 块大小增长因子,默认是1.25 -n 最小分配空间,key+value+flags默认是48 -h 显示帮助
清空memcache缓存的方法
默认memcache会监听11221端口,如果想清空服务器上memecache的缓存:
1)第一种方法:
# telnet localhost 11221
进入后,执行flush_all
2)第二种方法:
# echo “flush_all”|nc localhost 11221
————————php的memcache和memcached扩展区别————————
memcache文档:http://pecl.php.net/package/memcache
memcached文档:http://pecl.php.net/package/memcached
1)首先看下开发时间:
memcache最早是在2004年2月开发的,最后更新是在2013年4月;
memcached最早是在2009年1月开发的,最后更新是在2014年1月更新的。
所以memcache的历史比memcached早。
2)memcache是一个原生版本,完全在php框架内开发的。与之对应的带d的memcached是建立在libmemcached的基础上,所以相对来说,memcached版本的功能更全一些。
在安装memcache扩展的时候并不要求安装其他东西,但是在安装memcached的时候会要求安装libmemcached;
libmemcached是memcache的C客户端,它具有的优点是低内存,线程安全等特点。
比如新浪微博之前就全面将php的memcache替换成php的memcached,在高并发下,稳定性果断提高。
3)memcache的方法特别少,比如getMulti,setMulti都是没有的,基本就剩下最简单的get和set了。
所以说memcached比memcache支持更多的memcache协议。
memcache方法列表:http://cn2.php.net/memcache
memcached方法列表:http://www.php.net/manual/zh/book.memcached.php
4)Memcache是原生实现的,支持OO和非OO两套接口并存。而memcached是使用libmemcached,只支持OO接口。
5)memcached直接配置了session支持,只要稍微修改下配置文件就可以把session存储在memcache中了。
6)memcached还有个非常称赞的地方,就是flag不是在操作的时候设置了,而是有了一个统一的setOption()。Memcached实现了更多的memcached协议。
7)memcached支持Binary Protocol,而memcache不支持。这意味着memcached会有更高的性能。不过memcached目前还不支持长连接。
—————————————————————————-
连接到memcache后,使用stats命令查看缓存状态
[root@bastion-IDC ~]# telnet 192.168.1.5 11211 Trying 192.168.1.5... Connected to 192.168.1.5. Escape character is '^]'. stats STAT pid 20439 ----> Memcached 进程的ID STAT uptime 179982 ----> 进程运行时间 STAT time 1382361665 ---->当前时间 STAT version 1.4.15 ----> Memcached 版本 STAT libevent 1.4.13-stable STAT pointer_size 32 STAT rusage_user 21.916668 STAT rusage_system 40.576831 STAT curr_connections 11 STAT total_connections 329 STAT connection_structures 23 STAT reserved_fds 20 STAT cmd_get 2363348 ----> 总共获取数据的次数(等于 get_hits + get_misses ) STAT cmd_set 279971 ----> 总共设置数据的次数 STAT cmd_flush 0 STAT cmd_touch 0 STAT get_hits 2286284 ----> 命中了多少次数据,也就是从 Memcached 缓存中成功获取数据的次数 STAT get_misses 77064 ----> 没有命中的次数 STAT delete_misses 30803 STAT delete_hits 48876 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 574591015 STAT bytes_written 4353057466 STAT limit_maxbytes 67108864 ----> 总的存储大小,默认为 64M STAT accepting_conns 1 STAT listen_disabled_num 0 STAT threads 4 STAT conn_yields 0 STAT hash_power_level 16 STAT hash_bytes 262144 STAT hash_is_expanding 0 STAT bytes 4717345 ----> 当前所用存储大小 STAT curr_items 5654 STAT total_items 58461 STAT expired_unfetched 17 STAT evicted_unfetched 0 STAT evictions 0 STAT reclaimed 49
以上数据的命中率:2286284/2363348 = 96.7% 说明当前命中率是比较高的。