一、简介
Memcached是以LiveJournal旗下Danga Interactive 公司的Brad Fitzpatric 为首开发的一款开源、高性能、分布式内存对象缓存系统,可应用各种需要缓存的场景,使用非阻塞的网络IO,其主要目的是通过降低对Database的访问来加速动态web应用程序。它是一个基于内存的“键值对”存储,用于存储数据库调用、API调用或页面引用结果的直接数据,如字符串、对象等。目前全球许多站点如Youtube、Twitter、Wikipedia、WordPress.com都使用这个缓存项目来构建自己大负载的网站,来分担数据库的压力。
官网下载地址: http://www.memcached.org/
运行环境: Linux,FreeBSD,Windows,Solaris,Mac OS X
Memcached优点:

  • O(1)的执行效率
    O:从列表中查找数据的速度随着列表长度而变化的百分比(函数趋势)
    1:表示无论队列有多长,找出数据的时间是相同的
    http://blog.csdn.net/qiantujava/article/details/12898461
  • 各服务器间彼此无视:不在服务器间进行数据同步;
  • 简单key/value存储:服务器不关心数据本身的意义及结构,只要是可序列化数据即可。存储项由“键、过期时间、可选的标志及数据”四个部分组成;
  • 功能的实现一半依赖于客户端,一半基于服务器端:客户负责发送存储项至服务器端、从服务端获取数据以及无法连接至服务器时采用相应的动作;服务端负责接收、存储数据,并负责数据项的超时过期;
  • 惰性清理超期数据:默认情况下,Memcached是一个LRU缓存,同时,它按事先预订的时长清理超期数据;但事实上,memcached不会删除任何已缓存数据,只是在其过期之后不再为客户所见;而且,memcached也不会真正按期限清理缓存,而仅是当get命令到达时检查其时长;

工作流程:
1、检查客户端的请求数据是否存在于memcache中,如有直接把请求数据返回,不再对数据库进行任何操作。
2、如果请求的数据不在memcache中,就去查数据库,把从数据库中获取的数据返回给客户端,同时把数据缓存一份到memcache中(memcache本身不负责该操作,需要应用程序明确实现)。
3、每次更新数据库的同时更新memcache中的数据,保证数据一致性。
4、当分配给memcached内存空间用完之后,会使用LRU(Least Recently Used)算法加上到期失效策略,失效数据首先被替换,然后再替换掉最近未使用的数据。
Memcached特征:

  • 协议简单:基于文本行的协议,直接通过telnet在memcached服务器上可进行存取数据操作
  • 分布式:各个memcached服务器之间互不通信,各自独立存取数据,不共享任何信息;服务器并不具有分布式功能,分布式部署取决于memcache客户端。
  • 内置的内存管理方式:所有数据都保存在内存中,存取数据比硬盘快,当内存满后,通过LRU算法自动删除不使用的缓存,但没有考虑数据的容灾问题,重启服务,所有数据会丢失。
  • 基于libevent事件处理:Libevent是一套利用C开发的程序库,它将BSD系统的kqueue,Linux系统的epoll等事件处理功能封装成一个接口,提供了一种机制用来回调函数(事件驱动的IO必须要完成回调),在解决C10K问题上提供了高性能的事件驱动IO框架库,与传统glibc中自带的IO框架库相比,性能提升了许多。

Memcached的内存算法:
这里写图片描述
Memcached利用slab allocation机制来分配和管理内存,它按照预先规定的大小,将分配的内存分割成特定长度的内存块,再把尺寸相同的内存块分成组,数据在存放时,根据键值大小去匹配slab大小,找就近的slab存放,所以存在空间浪费现象。传统的内存管理方式是,使用完通过malloc分配的内存后通过free来回收内存,这种方式容易产生内存碎片并降低操作系统对内存的管理效率。
Memcached的缓存策略:
Memcached的缓存策略是LRU(最近最少使用)加上到期失效策略。当在memcached内存储数据项时,可以指定它在缓存的失效时间,默认为永久。当memcached服务器用完分配的内时,失效的数据被首先替换,然后也是最近未使用的数据。在LRU中,memcached使用的是一种Lazy Expiration策略,自己不会监控存入的key/vlue对是否过期,而是在获取key值时查看记录的时间戳,检查key/value对空间是否过期,这样可减轻服务器的负载。
Memcached的分布式算法:
这里写图片描述
当向memcached集群存入/取出key/value时,memcached客户端程序根据一定的算法计算存入哪台服务器,然后再把key/value值存到此服务器中。也就是说,存取数据分二步,第一步,选择服务器,第二步存取数据。
余数计算分散法
简单来说就是 ” 根据服务器台数的余数进行分散 ”
1.求得传入键的整数哈希值( int hashCode )。
2.使用计算出的 hashCode 除以服务器台数 (N) 取余数( C=hashCode % N )
3.在 N 台服务器中选择序号为 C 的服务器。
余数计算的方法简单,数据的分散性也相当优秀,但也有其缺点。 那就是当添加或移除服务器时,缓存重组的代价相当巨大。 添加服务器后,余数就会产生巨变,这样就无法获取与保存时相同的服务器, 从而影响缓存的命中率。
Consistent Hash
这里写图片描述
简单来说就构建一个首(0)尾(2的32次方)相接的虚拟圆环,然后通过某种HASH算法算出memcached服务器的散列值,根据散列值在圆环上增加虚拟节点(1 个实体节点可以虚拟 N个虚拟阶段,如 160,200,1000 等),KEY 请求的时候,也通过相同的HASH算法计算出存储数据的键的散列值并映射至圆上,然后从数据映射到的位置开始顺时针查找,将数据保存到环上同向最接近的虚拟节点,最后通过虚拟节点与实体节点的对应关系找到服务的实体节点。如果超过2的32次方,依然找不到服务器,就将数据保存到第一台memcached服务器上。memcached 服务器增多后,键就会分散,即使一台memcached 服务器发生故障无法连接,也不会影响其他的缓存,系统依然能继续运行。
二、Memcached安装与启动:
Memcache是项目名称,memcached是服务器端的主程序文件名,基于C/S模式,在服务器端启动服务守护进程,可以指定监听的IP,Port以及使用多少内存来处理Client端的请求等几个关键参数
服务器端:在服务器(一般都是linux系统)上安装memcached实现数据的存储
客户端:是指php(或者其他程序)去使用服务器端的Memcache提供的函数,需要php添加扩展。
安装libevent
memcached依赖于libevent API,因此要事先安装,本文采用的是目前最新版本的源码包libevent-2.0.22-stable.tar.gz 。读者可自行选择需要的版本下载:http://libevent.org/
安装过程:编辑脚本直接安装,此外还需要输出libevent的库文件给系统库查找路径,而后重新载入系统库
这里写图片描述
这里写图片描述
安装配置memcached
1、编辑脚本直接安装
–enable-sasl启用 SASL authentication确保系统上已安装cyrus-sasl-devel,安装完成后输出memcached的man手册至man命令的查找路径
这里写图片描述
这里写图片描述
这里写图片描述
2、memcached的常用选项说明
-l < ip_addr >:指定进程监听的地址;
-u < username >:以指定的用户身份运行memcached进程;
-m < num >:用于缓存数据的最大内存空间,单位为MB,默认为64MB;
-c < num >:最大支持的并发连接数,默认为1024;
-p < num >: 指定监听的TCP端口,默认为11211;
-U < num >:指定监听的UDP端口,默认为11211,0表示关闭UDP端口;
-t < threads >:用于处理入站请求的最大线程数,仅在memcached编译时开启了支持线程才有效;
-f < num >:设定Slab Allocator定义预先分配内存空间大小固定的块时使用的增长因子;
-M:当内存空间不够使用时返回错误信息,而不是按LRU算法利用空间;
-n: 指定最小的slab chunk大小;单位是字节;
-S: 启用sasl进行用户认证;
-d: 以服务模式运行;
启动memcached
这里写图片描述
3、Memcache的管理与性能监控:
可以通过nagios,cacti等web软件进行监控也可通过命令行直接管理与监控;Memcached提供一组基本命令用于基于命令行调用其服务或查看服务器状态等。
存储类命令:set, add, replace, append, prepend
Set:添加一个新条目到memcached或是用新的数据替换替换掉已存在的条目
Add:当KEY不存在的情况下,它向memcached存数据,否则,返回NOT_STORED响应
Replace:当KEY存在的情况下,它才会向memcached存数据,否则返回NOT_STORED响应
Cas:改变一个存在的KEY值 ,但它还带了检查的功能
Append:在这个值后面插入新值
Prepend:在这个值前面插入新值
获取数据类命令:get, delete, incr/decr
Get:取单个值 ,从缓存中返回数据时,将在第一行得到KEY的名字,flag的值和返回的value长度,真正的数据在第二行,最后返回END,如KEY不存在,第一行就直接返回END
Get_multi:一次性取多个值
清理命令: flush_all
统计类命令:stats, stats items, stats slabs, stats sizes

  • Stats:统计memcached的各种信息
  • Stats reset:重新统计数据
  • Stats slabs:显示slabs信息,可以详细看到数据的分段存储情况
  • Stats items:显示slab中的item数目
  • Stats cachedump 1 0:列出slabs第一段里存的KEY值
  • Set|get:保存或获取数据
  • STAT evictions 0:表示要腾出新空间给新的item而移动的合法item数目

4、实例操作:使用telnet命令测试memcached的使用
先连接到memcache,存入数据,回车后系统自动保存,并返回正常值STORED,注意在设定bytes字节后,存入的值的长度一定要与之匹配,否则无法保存成功,key字段为5字节,存入的hello长度为5(总计为5个数字或字母)。
add keyname flag timeout datasize
这里写图片描述
重新刚才设定的key,然后取数据,回车后,第一行返回VALUE,第二行,返回真正值,再次取key,超出设定的过期时间,key失效,直接返回END
这里写图片描述
5、将memcached做成系统服务
SysV的startup脚本代码如下所示,将其建立为/etc/init.d/memcached文件:
这里写图片描述
这里写图片描述
这里写图片描述
提供服务脚本的配置文件,方便根据实际情况修改参数
这里写图片描述
6、使用如下命令配置memcached成为系统服务:
这里写图片描述
三、安装PHP的memcache扩展
1、编辑安装脚本并执行
这里写图片描述
这里写图片描述
上述安装完后会有类似以下的提示:
这里写图片描述
2、编辑memcache.ini,添加如下一行来载入memcache扩展:
这里写图片描述
这里写图片描述
这里写图片描述
而后对memcached功能进行测试,在网站目录中建立测试页面test.php,添加如下内容:
这里写图片描述
如果有输出“Hello World is from memcached.”等信息,则表明memcache已经能够正常工作。
这里写图片描述
这里写图片描述
四、使用libmemcached的客户端工具
访问memcached的传统方法是使用基于perl语言开发的Cache::memcached模块,这个模块在大多数perl代码中都能良好的工作,但也有着众所周知的性能方面的问题。libMemcached则是基于C语言开发的开源的C/C++代码访问memcached的库文件,同时,它还提供了数个可以远程使用的memcached管理工具,如memcat, memping,memstat,memslap等。
1、 编译安装libmemcached,编译时间稍微有点长
这里写图片描述
2、客户端工具
例:memcat –servers=127.0.0.1:11211 keyname指定server&&port获取数据
这里写图片描述
五、Nginx整合memcached
让nginx的数据直接缓存到memcached中,nginx的数据是缓存在磁盘上的,所以性能相对memcached较差

server {
        listen       80;
        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
          set $memcached_key $uri;                    
            ##往memcached上设置数据keyname为当前用户的uri
          memcached_pass  127.0.0.1:11211;               
            ##memcached服务器地址及端口
          default_type      text/html;                     
            ##指定缓存数据的类型
          error_page         404 @fallback;      
           ##如果缓存中没有,返回404,调用fallback location
        }

        location @fallback {
          proxy_pass http://172.16.0.1;      
          ##传递给后端服务器处理,结果保存在缓存中
        }
}

六、让php会话信息保存在memcached当中
1、配置php将会话保存至memcached中
编辑php.ini文件,确保session.save_handler &&session.save_path 两个参数的值分别如下所示:
这里写图片描述
2、测试
新建php页面setsession.php,为客户端设置启用session:
这里写图片描述
新建php页面showsession.php,获取当前用户的会话ID:
这里写图片描述
分别访问测试页面查看效果:
这里写图片描述
这里写图片描述
七、下载memadmin-master.zip解压后,将解压文件夹移至nginx默认根目录下,访问测试

[root@DQ ~]# unzip Downloads/memadmin-master.zip
[root@DQ ~]# mv memadmin-master /usr/html/admaster

这里写图片描述
这里写图片描述
这里写图片描述
参考博文:http://369369.blog.51cto.com/319630/833234
http://blog.csdn.net/sparkliang/article/details/5279393

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐