1.Memcached的介绍

  Memcached是一套开源、分布式、高性能的内存对象缓存系统,通常用于在减少web应用对数据库的访问而提升整体性能。Memcached是基于内存的"key-value(键值)"的缓存服务器,并且key是经过HASH编码的,使得其查找速度非常迅速,不会因为数据过多而出现查询过慢的问题。

  Memcached在多数场景下作为数据库前端的公共cache使用,因为它比数据库少了很多SQL的解析、磁盘操作等开销,而且使用内存来管理数据,可以提供比数据库更好的性能。除此之外,Memcached也可以作为服务器之间数据共享的存储媒介。

  Memcached不支持数据的持久化,也就是当系统宕机,数据全部丢失。而且,Memcached本身是一个客户端分布式缓存方案,它的"分布式"功能依赖于客户端的算法。

  注:key-value指得是,一个是关键字(查找的依据),一个是value(所要的值),每个key对应一个value。

  注:只要是可序列化的数据,Memcached就可以缓存。

2.Memcached的设计思想

  Memcached仅仅是一个缓存服务器,为程序员提供缓存功能,其设计哲学思想主要反映在如下:

  (1) 简单key/value缓存:服务器不关心数据本身的意义及结构,只要是可序列化数据即可缓存。存储项由"键、过期时间、可选的标识及数据"四个部分组成;

  (2) 功能的实现一半依赖于客户端,一办依赖于服务器端:

    客户端负责发送存储项至服务器端、从服务端获取数据、以及当无法连接至服务器时采取相应的动作;

    服务器端负责接收来自客户端的数据并将其缓存到内存中,而且需要保证数据的有效性(管理过期超时项)。

  (3) 服务器的分布式特征:各个Memcached服务器之间互相不通信,都是独立的,不共享数据;

  (4) O(1)的执行效率:由于其的key基于HASH编码,并且数据存放于内存中,所以其速度是O(1)级的(在5条数据中查找1条数据的速度和在100条数据中查找1条的速度是一样的);

  (5) 懒惰模式清理过期的数据:默认情况下,Memcached是一个LRU缓存,同时,它按事先规定的时长清理过期的数据;但事实上,Memcached不会删除任何已缓存数据,只不过在数据过期时不在对客户端所见;而且,Memcached也不会真正的按期限去清理缓存,只有当get命令命中目标时才检查该数据是否过期。

3.Memcached的C/S交互

  Memcached提供了为数不多的几个命令来实现客户端/服务器端的交互,C/S基于memcached的协议通信:

  (1) 存储类命令:set(设置),add(新增),replace(替换),append(缓存内容后追加),prepend(缓存内容前追加)

  (2) 获取数据类命令:get(获取),delete(删除),incr/decr(数字+1,例如微博转发数)

  (3) 统计类命令:stats(整体状态信息),stats itmes(itmes信息),stats slabs(slbas信息),stats sizes(slbas大小信息)

  (4) 清理命令:flush_all

  注:Memached协议具有两种通信模式:文本格式(默认)和二进制格式。

4.Memcached的内存分配

  Linux是基于malloc()申请内存,free()释放内存,由于memcached基于内存进行数据进行管理,通常其缓存数据的频率比较大,所以会导致memcached会频繁向Linux(Kernel)发起申请、释放的请求,而Linux的malloc()和free()的性能是低效的,为了解决这个问题,memached基于slab allocator机制对数据进行申请、释放。

  在slab allocator的机制上,memcached启动后申请一段内存页面(Page,内存空间;一个页面默认为1MB),并使用slab allocator对内存页面进行"格式化",将其格式化成为特定大小的N个chunk(区块,缓存数据的空间;例如格式化10个1k的区块,5个2k的区块;同类的区块称作slab class)。从而避免内存的频繁释放、回收,但是由于一个数据只能存放于一个chunk中,此机制可能会浪费内存空间(当你有1k、2k、4k三种chunk时,需要存储一个3k的数据,此时只能存储在4k的chunk中,也就浪费了1k的空间)。

  slab allocator的chunk分配上,需要指定增长因子,例如从1k开始,增长因子如果2,则每次递归2k。增长因子不能过大,否则会出现严重的空间浪费。

5.Memcached的分布式:

  Memcached的分布式是由客户端实现的,也就是当应用到Memcached的分布式缓存(多台memcached服务器)时,为了保证缓存的命中率,我们需要让客户端进行计算,使其可以将请求分配到已经缓存了该资源的Memcached上(存储也是同样的过程)。一般常用的有两种算法,一种是根据余数来计算分布,另一种是根据一致性HASH算法来计算分布。余数算法先求得键的整数散列值,再除以服务器台数,根据余数来选择服务器。一致性HASH先算出Memcached服务器节点的散列值,并将其分散到0到2^32次方的圆上,然后用同样的方法算出键的值并映射到圆上,最后从数据映射到的位置开始顺时针查找,以找到的第一台服务器为准。

6.Memcached的并发模型:

  Memcached会涉及到并发请求,所以其依赖于libevent库。libevent库就包含了常用的IO模型,epoll,poll,select。新版本一般为单进程响应多请求。

7.Memcached的客户端(扩展库):

  程序员在开发时,调用memcached的API,memcached的功能才能生效。介于调用API的复杂性,大多数的程序开发语言都提供了已经打包好的扩展库,使得程序员在使用时只需要调用库功能即可:

  (1) memcached:php连接memcached服务器可以使用的扩展库;

  (2) memcache:php连接memcached服务器可以使用的另一个扩展库,少用;

  (3) libmemcached:C连接memcached的扩展库

8.Memcached的安装及配置:

  8.1 memcached的安装:

[root@localhost ~]# yum install -y memcached

  8.2 memcached的常用组件:

[root@localhost ~]# rpm -ql memcached/etc/rc.d/init.d/memcached  #memcached启动脚本/etc/sysconfig/memcached    #memcached启动脚本配置文件/usr/bin/memcached          #memcahed二进制程序,服务器端软件/usr/bin/memcached-tool     #memcached工具.....

  8.3 memcached二进制程序的常用选项及参数:

-l 
  #监听的IP地址-d        #以独立守护进程模式运行,默认运行在前台;Linux有三种进程:超级守护进程(负责多个进程的管理,xinetd)、独立守护进程(自身管理的进程)、瞬时守护进程(超级守护进程管理的进程)-u 
  #指定程序运行者的身份-m 
    #定义memcached可以使用的内存空间,默认是64MB-c 
    #最大并发连接-p 
    #监听的TCP端口,默认为11211-U 
    #监听的UDP端口,默认为11211-M        #指定当内存耗尽时,memcached不清空缓存,而返回错误信息-n 
    #指定最小的chunk大小-f 
   #指定chunk的增长因子-t 
  #指定memcached的工作线程数,默认为4-B 
   #指定memcached协议类型,默认为文本模式;

  8.4 启动Memcached程序:

[root@localhost ~]# memcached -u memcached -d[root@localhost ~]# ss -tunl|grep "11211"udp    UNCONN     0      0                      *:11211                 *:*     udp    UNCONN     0      0                     :::11211                :::*     tcp    LISTEN     0      128                   :::11211                :::*     tcp    LISTEN     0      128                    *:11211                 *:*

  8.5 测试连接到Memcached服务器并写入一条数据:

[root@localhost ~]# telnet localhost 11211Trying ::1...Connected to localhost.Escape character is '^]'.add testkey 0 60 5   #add的格式为 "add key(键) flag(标识) timeout(超时时间) length(长度)"12345   #value(key的值)STORED  #已经存储的提示get testkey  #获取testkey这个键的信息及值VALUE testkey 0 5  #键的信息12345   #键的值END  #结束符

  8.6 PHP安装memcached扩展:

  前面说过,要想使用Memcached的功能,就需要开发人员在编写程序的时候调用memcached的API,不过,大多数的程序都已经提供了Memcached的扩展库,这样只需要调用该库的功能即可。同样的,PHP也为Memcached提供了扩展库,这里以memcached这个扩展库(注意:memcached的m是小写的,这个库的名字就叫做memcached)为例: