Memcached基础
What is Memcached ? Free & open source, high-performance, distributed memory object caching system 一个开源,免费的高性能,分布式内存缓存系统。 在我们的应用程序中,一般会将数据库的一些经常需要查询用到的数据缓存至Memcached,以提高动态Web应用的响应速度。如下图所示: 快速体验Memcached 由于Memcached使用到了基于libevent的事件处理机制,因此安装之前需要确保已经安装libevent库。由于我用的是最新稳定版1.4.22(下载网址:http://memcached.org/),对libevent的版本还有要求,如果版本过低,还不能启动Memcached,可以到http://libevent.org/ 下载较新的libevent版本使用。 【关于libevent的简要说明:libevent就是一个程序库,他将Linux的epoll、BSD系统的kqueue等事件处理机制封装成统一的接口,即使对服务器的连接增加,也能发挥0(1)的性能。Memcached使用这个库,可以在Linux平台上发挥其高性能。】 过程如下:
启动Memcached
可以利用./memcached -h的方式来了解一些选项的作用: -p <num> TCP port number to listen on (default: 11211) 指定端口 -l <addr> interface to listen on (default: INADDR_ANY, all addresses) 监听地址,想一想,如果我们的机器上有多个网卡我们监听在哪个网卡上呢? -d run as a daemon 表示以一个后台服务的方式运行 -u <username> assume identity of <username> (only when run as root) 以哪个用户的身份运行 -m <num> max memory to use for items in megabytes (default: 64 MB) 以M为单位指定最大的内存空间 -f <factor> chunk size growth factor (default: 1.25) 指定增长因子 -n <bytes> minimum space allocated for key+value+flags (default: 48) 最小存储单位。实际上,这里指定的是最小的slab chunk大小 在上面启动过程中,我们使用了-vvv的方式输出了启动过程的详细信息,那么slab class , chunk这些是什么呢?增长因子又是干什么的? 端口验证:
Memcached启动后,我们怎么连接进行操作呢? 要知道Memcached是基于Client/Server架构的,上面的是启动Server端,表示Memcached已经有64M内存空间来进行缓存数据管理。至于设置哪些缓存数据,数据有效期是多少等这些都是客户端的事情。很多语言都实现了Memcached客户端,比如Java/PHP等。需要注意的是,Memcached的一个重要特征--协议简单。比如,我们就可以使用telnet来操作Memcached:
stats命令可以获取到Memcached运行时相关信息。 一些常用命令: add命令 添加新键 add keyname flag timeout datasize
get命令 取得键值 get keyname
set 无条件设置一个键 说白了,就是有键则覆盖,无键则添加。 set keyname flag timeout datasize replace 替换已经存在的KEY replace keyname flag timeout datasize append keyname flag timeout append_datasize prepend keyname flag timeout prepend_datasize
incr keyname increments 对键值增长 decr keyname decrements 对键值减少
delete keyname 删除指定键 flush_all 清理所有键 stats 状态信息 quit 表示退出 version 查看版本 |
Memcached的内存存储和删除机制
Memcached是一个缓存服务器,并且它认为自己缓存的数据并不是关键性数据,也就是如果Memcached重启,缓存数据会丢失,需要重新建立。Memcached对高可用的支持不是很好,但是对分布式提供了很好的支持。下面我们来分析下Memcached的内存存储机制:
Memcached的内存存储机制采用了Slab Allocator的方式,按照预先规定的大小,将分配的内存分割成特定长度的块,以减少内存碎片问题。Slab Allocator可以重复使用以分配的内存。如下图所示: 有多个Slab Class类别,每一个Slab Class里面有多个相同大小的Chunk,而Chunk就是Memcached存储数据的最小单元。当Memcached接受到数据需要缓存时,会选择最适合数据大小的Slab,然后从Slab中选择空闲的Chunk进行存储。当然这种方式是无法避免内存浪费的。 在启动Memcached时,我们指定了-f选项,其实是在指定Slab中Chunk大小的增长因子,这是Memcached为我们提供的一个可以进行调优的选项。我们可以根据客户端缓存数据的大小,做一个预估,通过增长因子来调整Slab的差别,以获得最恰当的设置。 在Memcached中缓存数据的时候,我们可以指定数据的失效期,可以指定到秒。那么如果时间到了,Memcached会怎么做呢? Memcached并不会释放已经分配的内存,超时后,客户端就无法在看到该记录了。Memcached的删除机制思想如下: LAZY机制 Memcached内部不会去监控记录是否过期,而是在get的时候去判断一下时间戳,这样就知道是不是过期了。这样的话,Memcached因为LAZY的机制不会在这个方面去占用CPU。 LRU算法 最近最少使用原理,当Memcached空间不足时,要清理,怎么清理呢?就是清理那些最近未被使用的记录的空间,将这些空间重新分配给新的记录。 |
Memcached的分布式机制与一致性哈希算法
当我们使用多台Memcached来缓存数据时,就利用到了Memcached的分布式。Memcached的分布式的最大特点是不相互通信。在分布式的情况下,当我们要保存一个键时,可以简单的根据键计算一个值,从而决定存储至哪个Memcached中,当要get这个键的时候,利用同样的方式到对应的Memcached服务器中去取。比如,我们有10台Memcached(编号0-9),现在要保存一个key,通过对key进行计算,比如取得它的HASH值,然后对10取余,假设得到8,我们就将这个KEY存储至编号为8的服务器中。这样的话,虽然算法上简单,存取上实现了分布式,但是有一个明显的缺点,就是如果增加或者减少了Memcached的节点个数,我们的大部分缓存就失效了,需要重新建立了。【原因在于取余的结果发生了巨变】那么有没有一种方式,当我们增加或者减少Memcached节点个数时,带来的影响最小呢? 关于一致性HASH算法(Consistent Hashing) 基本原理说明: 有一个HASH环,分布着2的32次方个点,然后求出各个Memcached服务器的HASH值,将其置于环上的各个点上。用相同的方式计算需要保存的数据的键的HASH值,并映射到环上的位置,从映射处开始顺时针开始查找最近的Memcached,找到后就保存至这个服务器。如果要取得数据,也采用相同的方式定位服务器。 这种算法就是一致性HASH算法,通过这样可以在添加、删除服务器时,最大限度的抑制键的重新分布。 |
本文转自zfz_linux_boy 51CTO博客,原文链接:http://blog.51cto.com/zhangfengzhe/1598626,如需转载请自行联系原作者