.memcached简介

Memcached是一个免费开源、高性能、分布式的内存对象缓存系统。Memcached是在内存中,为特定数据(字符串或对象)构建key-value的小块数据存储。

Memcached项目地址:

现在最新版本为1.4.22,时间点:2015.01.26

 

.实验环境介绍

第一个实验:我们在node3节点实现一个LNMP架构,测试memcached的基本的使用和web gui界面管理;

第二个实验:我们将node3节点当作httpdnginx的反向代理节点,在node4node5节点上搭建tomcat服务器,并安装memcached缓存服务器,实现tomcat的会话保存;我们在node3反向代理节点上将客户端请求负载均衡到后端的tomcat服务器节点,并实现session会话保持;

 

实验实现过程

 

.LNMP构建(Linux+Nginx+Memcached+php-fpm

1.安装php-fpmnginx

需要下载nginx的稳定版本:

nginx-1.6.2-1.el6.ngx.x86_64.rpm

[root@node3 ~]# yum install -y php-fpm  nginx-1.6.2-1.el6.ngx.x86_64.rpm

 

2.配置nginx支持php-fpm,创建php的测试页

配置nginx启用php

[root@node3 ~]# vim/etc/nginx/conf.d/default.conf   location ~ \.php$ {       root           /usr/share/nginx/html/index.php;       fastcgi_pass   127.0.0.1:9000;       fastcgi_index  index.php;       fastcgi_param SCRIPT_FILENAME /usr/share/nginx/html/$fastcgi_script_name;       include        fastcgi_params;    }

如图所示:

创建php测试页:

[root@node3 ~]# vim/usr/share/nginx/html/index.php

 

3.启动nginxphp-fpm服务器

[root@node3 ~]# service nginx startStarting nginx:                                           [  OK  ][root@node3 ~]# service php-fpm startStarting php-fpm:                                         [  OK  ]

 

访问测试如图:

 

4.php-fpm中安装memcached扩展模块

需要下载memcache-2.2.7.tgz,安装前需要php的开发包支持:

我这里提供附件下载;

安装开发包:

[root@node3 ~]# yum install -y php-devel

 

编译安装memcache-2.2.7.tgz

[root@node3 ~]# tar xf memcache-2.2.7.tgz[root@node3 ~]# cd memcache-2.2.7[root@node3 memcache-2.2.7]# phpizeConfiguring for:PHP Api Version:         20090626Zend Module Api No:      20090626Zend Extension Api No:   220090626[root@node3 memcache-2.2.7]# ./configure开始安装:[root@node3 memcache-2.2.7]# make&& make install信息略......Installing shared extensions:     /usr/lib64/php/modules/ 可以发现安装完成生成的模块在/usr/lib64/php/modules/中,我们去查看:[root@node3 memcache-2.2.7]# cd/usr/lib64/php/modules/[root@node3 modules]# lscurl.so fileinfo.so  json.so  memcache.so  phar.so zip.so有memcache.so这个模块,安装完成。

 

 

配置php-fpm加载此模块即可,在如图位置添加扩展模块即可:

[root@node3 ~]# vim /etc/php.iniextension =/usr/lib64/php/modules/memcache.so

配置如图所示:

重启php-fpm服务即可:

[root@node3 ~]# service php-fpm restartStopping php-fpm:                                          [  OK  ]Starting php-fpm:                                         [  OK  ]

 

再次访问测试页可以看见php已经支持memcached扩展了:

 

5.安装memcached软件

libmemcached:是C语言的驱动(api),跟应用连接需要指定的API版本是libmemcached-0.31-1.1.el6.x86_64Memcached软件包:如果希望进行源码编译安装,可以从http://www.memcached.org/ 获取 memcached 源文件;我的yum源已经有了memcached-1.4.4-3.el6.x86_64。

使用yum源安装:

[root@node3 ~]# yum install -y memcached  libmemcached

 

不用配置即可启动memcached服务:

[root@node3 ~]# /etc/init.d/memcached startStarting memcached:                                        [  OK  ]

 

查看服务监听端口:

[root@node3 ~]# netstat -tunlp |grepmemcachedtcp       0      0 0.0.0.0:11211               0.0.0.0:*                   LISTEN      2956/memcached     tcp       0      0 :::11211                    :::*                        LISTEN      2956/memcached     udp       0      0 0.0.0.0:11211               0.0.0.0:*                               2956/memcached     udp       0      0 :::11211                    :::*                                    2956/memcached

 

基本上一个LNMP的简单架构就构建完成了。我们使用这个做memcached的测试。

 

 

.memcahced的基本使用

1. memcached 参数说明:

# memcached -h

 

2. memcached 的参数

常用参数

-p 
 监听的TCP端口号,默认是11211;(port)-l 
 监听的主机地址,默认是INADDR_ANY,即所有地址,
可以是host:port的形式,如果没有指定port,则使用-p或者-U的值;可以指定多个地址,以逗号分隔或者多次使用-l参数;尽量不要使用默认值,有安全隐患。(listen)-d 以守护进程运行 (daemon)-u 
 指定进程的所有者(只有以root用户执行时才可以使用该参数)(username)-m 
 用于存储数据的最大内存,单位是MB,默认是64MB;(memory)-c 
 最大并发连接数,默认是1024;-vv 显示更详细的信息(还显示客户端的命令和响应)-vvv 显示最详细的信息(还显示内部的状态转变)-h 显示帮助信息-P 
 将PID保存到
中,仅和-d参数一起使用;-f 
 chunk的增幅因子,默认是1.25,不同的slabclass,slab page大小相同,但是chunk大小不等,chunk的大小根据这个增幅因子增长;(factor)-n 
 为key+value+flags分配的最小内存,单位bytes,默认是48;chunk数据结构本身要占据48字节,所以实际大小是n+48;-t 
 使用多少个线程,默认是4;(thread)-I 设置slab page的大小,即设置可以保存的item的最大值,默认1MB,最小是1K,最大值128M;

 

其它参数

-U 
 监听的UDP端口号,默认是11211,0表示关闭UDP监听;(UDP)-s 
 要监听的UNIXsocket路径(禁用网络支持)(socket)-a 
 UNIX socket的访问掩码(accessmask),八进制表示,默认是0700. (mask)-r 文件数量的最大值 (rlimit)-M 内存耗尽时返回错误,而不是通过LRU淘汰内容;-k 锁定所有页内存;允许被锁定的内存是有限制的,超过限制可能会失败。-v 显示启动信息(错误和警告信息)(verbose)-i 显示memcached和libevent的licence信息-L 一次申请大的内存页(如果可以);增大内存页的大小,可以提高性能;-D 
 指定key前缀与ID的分隔符,用于stats信息显示,默认是冒号:,如果使用了该参数,则stats收集自动启用了,否则,需要发送命令“stats detail on”命令来启动stats的收集。-R 每一个事件(event)的最大请求数,限制最大请求数可以防止线程饥饿,默认是20;-C 禁用CAS;-b 设置backlog队列限制,默认1024;-B 指定绑定协议,ascii,binary或者auto,其中auto是默认值;3.repcached的参数:-x 
 peer主机的主机名或者ip地址;-X peer主机的TCP端口,即主从同步端口,共同的监听端口

 

常用的参数组合

# memcached -d -m -p 11212 -u nobody -l127.0.0.1 -x 127.0.0.1 -X 11222 -P /tmp/localhost_slave.pid –vv

 

4.我们安装telnet客户端进行简单memcached键值存储演示

 

基本命令与操作

存储的命令

主要有:setaddreplaceappendprependcas;格式为:

command key flag expiration_time bytesvalue

key表示键,flag表示key/value的额外信息,expiration_time表示过期时间,单位为秒,0表示永不过期,bytes表示值所占的字节数,必须完全匹配,value表示key对应的值,总是出现在第二行。

读取的命令

get根据key获取value值;可以获取多个key的值;get key  get key1 key2 格式为:

 

set命令表示存储一个key/value对,如果该key已存在,则更新对应的value值;如果成功,返回STORED

实例:

[root@node3 ~]# telnet localhost 11211Trying ::1...Connected to localhost.Escape character is '^]'.#设置一个简单的testkey,过期时间用不过期,字节长度为11bytesset testkey 0 60 11#输入11个字节,必须和上面的完全匹配;hello world#获取缓存的键值;get testkeyVALUE testkey 0 11hello worldEND

 

add命令也表示增加key/value,如果key/value已存在,add操作失败;保存成功返回STORED,失败返回NOT_STORED

实例:在telnet下操作

add testkey 0 60 2hiSTOREDadd testkey 0 60 11hello worldNOT_STORED

 

replace命令表示更新key对应的value值,如果key/value不存在,replace操作失败;成功返回STORED,失败返回NOT_STORED

实例:在telnet下操作

set testkey 0 60 11hello worldSTOREDget testkeyVALUE testkey 0 11hello worldENDreplace testkey 0 60 5helloSTOREDget testkeyVALUE testkey 0 5helloEND

由于缓存时间有限,所以超时会自动清空缓存。

 

append表示在key对应的value值后追加数据,key必须已存在,否则操作失败;成功返回STORED,失败返回NOT_STORED

实例:在telnet下操作:

set testkey 0 60 5helloSTOREDappend testkey 0 60 6 worldSTOREDget testkeyVALUE testkey 0 11hello worldEND

 

prependkey对应的value值的前面追加数据,key必须已存在,否则操作失败;成功返回STORED,失败返回NOT_STORED

实例:在telnet下操作;

set testkey 0 60 5worldSTOREDprepend testkey 0 60 6helloSTOREDget testkeyVALUE testkey 0 11hello worldEND

 

cas (check and set):先比较后存储,即原子更新,原理类似于乐观锁。每次请求存储某个数据时附带一个cas值,memcached比对这个cas值与当前存储数据的cas值是否相等,如果相等,则更新数据,否则操作失败;当前存储的cas值通过gets命令获取。成功返回STORED,失败返回EXISTS

实例:在telnet下设置:

set testkey 0 60 11hello worldSTOREDget testkeyVALUE testkey 0 11hello worldENDcas testkey 0 60 8 10shanghaiSTOREDcas testkey 0 60 8 13shanghaiEXISTSget testkeyVALUE testkey 0 8shanghaiEND

 

get根据key获取value值;可以获取多个key的值;get key  get key1 key2

例子上面很多啦!

delete命令删除key/value对,一次只能删除一个key/value对;如果要删除的key不存在,操作失败:delete key

实例:

set testkey 0 60 11hello worldSTOREDget testkeyVALUE testkey 0 11hello worldENDdelete testkeyDELETEDget testkeyEND

 

统计的命令

stats显示进程及当前状态等信息。

[root@node3 ~]# telnet localhost 11211Trying ::1...Connected to localhost.Escape character is '^]'.Stats#进程IDSTAT pid 2956#系统运行的时间,单位:秒STAT uptime 59841#系统当前的事件,Unix时间戳表示的时间STAT time 1422337390#memcached版本STAT version 1.4.4#操作系统字大小(64位)STAT pointer_size 64# 进程累计用户时间STAT rusage_user 1.372791#进程累计系统时间STAT rusage_system 1.542765#当前打开的连接数STAT curr_connections 10# 曾打开的连接总数STAT total_connections 42#服务器分配的连接结构数STAT connection_structures 11#执行get命令的总数STAT cmd_get 17#执行set命令的总数STAT cmd_set 22#执行flush_all命令的总数STAT cmd_flush 0STAT get_hits 12STAT get_misses 5STAT delete_misses 0STAT delete_hits 0STAT incr_misses 0STAT incr_hits 0STAT decr_misses 0STAT decr_hits 0STAT cas_misses 0STAT cas_hits 1STAT cas_badval 5STAT auth_cmds 0STAT auth_errors 0STAT bytes_read 1295STAT bytes_written 14526STAT limit_maxbytes 67108864STAT accepting_conns 1STAT listen_disabled_num 0# 线程数STAT threads 4STAT conn_yields 0#存储的item字节数STAT bytes 84#当前item数量STAT curr_items 1#item的总数STAT total_items 13#为获取空间删除的item数量STAT evictions 0END stats items 显示items的相关信息stats itemsSTAT items:1:number 1STAT items:1:age 50209STAT items:1:evicted 0STAT items:1:evicted_nonzero 0STAT items:1:evicted_time 0STAT items:1:outofmemory 0STAT items:1:tailrepairs 0END

 

stats slabs 显示slab的相关信息

stats slabsSTAT 1:chunk_size 96STAT 1:chunks_per_page 10922STAT 1:total_pages 1STAT 1:total_chunks 10922STAT 1:used_chunks 1STAT 1:free_chunks 2STAT 1:free_chunks_end 10919STAT 1:mem_requested 107STAT 1:get_hits 12STAT 1:cmd_set 22STAT 1:delete_hits 0STAT 1:incr_hits 0STAT 1:decr_hits 0STAT 1:cas_hits 1STAT 1:cas_badval 5STAT active_slabs 1STAT total_malloced 1048512END

 

stats sizesstats sizesSTAT 96 1END

 

flush_all 使cache中的所有items都过期,server不会停止,也不会刷新或者释放内存。

set testkey 0 60 11hello worldSTOREDflush_allOKget testkeyEND

 

.创建基于web gui接口管理memcached

 

1.web gui 接口的管理软件是phpMemcachedAdmin

通过php编码实现的,phpMemcachedAdmin是一个用来管理memcached的一个可视化的管理工具,采用php的脚本语言实现,参考学习应运于开发实践不错的例子

 

2.软件安装

软件版本:phpMemcachedAdmin-1.2.2-5.svn262.el6.noarch,由epel源提供。

安装软件:[root@node3 ~]# yum install -y phpMemcachedAdmin查看软件安装路径:[root@node3 ~]# rpm -ql phpMemcachedAdmin/etc/httpd/conf.d/phpMemcachedAdmin.conf/etc/phpMemcachedAdmin/etc/phpMemcachedAdmin/Memcache.php/usr/share/doc/phpMemcachedAdmin-1.2.2/usr/share/doc/phpMemcachedAdmin-1.2.2/LICENSE/usr/share/phpMemcachedAdmin信息略

由于它相当于一个web服务器,是memcached的管理后台,我们下面就去配置一下nginx服务器即可:

 

3.配置nginx服务器

[root@node3 ~]# vim/etc/nginx/conf.d/default.confserver {   listen       80;   server_name  localhost;   location / {       root   /usr/share/phpMemcachedAdmin/;       index  index.html index.htm;    }   error_page   500 502 503 504  /50x.html;   location = /50x.html {       root   /usr/share/nginx/html;    }    location ~ \.php$ {       root          /usr/share/phpMemcachedAdmin/;        fastcgi_pass   127.0.0.1:9000;       fastcgi_index  index.php;       fastcgi_param SCRIPT_FILENAME /usr/share/phpMemcachedAdmin/$fastcgi_script_name;       include        fastcgi_params;    }}

 

 

4.配置完成启动nginx服务:

 

[root@node3 ~]# service nginx restartStopping nginx:                                           [  OK  ]Starting nginx:                                           [  OK  ]

访问测试:

 

 

.通过memcached实现tomcat服务器集群session共享

 

实验架构图

 

 

1.在后端tomcat服务器开始安装配置jdk

安装jdk:#rpm -ivh jdk-7u67-linux-x64.rpm 配置jdk环境变量# vim /etc/profile.d/java.shexport JAVA_HOME=/usr/java/latestexport PATH=$JAVA_HOME/bin:$PATH # source /etc/profile.d/java.sh 运行命令显示java的版本和jre运行时环境:# java -versionjava version "1.7.0_67"Java(TM) SE Runtime Environment (build1.7.0_67-b01)Java HotSpot(TM) 64-Bit Server VM (build24.65-b04, mixed mode)

 

 

2.安装tomcat软件

获得tomcat软件:

apache-tomcat-7.0.55.tar.gz

 

安装tomcat:#tar xf apache-tomcat-7.0.55.tar.gz -C/usr/local 创建软链接:# cd /usr/local/# ln -sv apache-tomcat-7.0.55/ tomcat`tomcat' -> `apache-tomcat-7.0.55/' 配置tomcat环境变量:# vim /etc/profile.d/tomcat.shexport CATALINA_HOME=/usr/local/tomcatexport PATH=$CATALINA_HOME/bin:$PATH 加载环境变量:# source /etc/profile.d/tomcat.sh

 

tomcat安装完成;启动tomcat服务:

#catalina start

访问测试:

 

4.在后端tomcat节点安装memcached

# yum install -y memcached libmemcached

安装完成后启动memcached服务:

# service memcached start

 

5.tomcat服务器session会话保持之session服务器配置

MSM(memcached session manager)是一个高可用的Tomcatsession共享解决方案,除了可以从本机内存快速读取Session信息(仅针对黏性Session)外,同时可使用memcached存取Session,以实现高可用。

    对于非黏性Sessionmemcached直接存储session

    memcached-session-manager项目地址,http://code.google.com/p/memcached-session-manager/

下载如下jar文件至各tomcat节点的tomcat安装目录下的lib目录中,其中的${version}要换成你所需要的版本号,tc${6,7,8}要换成与tomcat版本相同的版本号。

         memcached-session-manager-${version}.jar

         memcached-session-manager-tc${6,7,8}-${version}.jar

         spymemcached-${version}.jar

         msm-javolution-serializer-${version}.jar

         javolution-${version}.jar

 

由于我的节点的tomcat服务器版本是7系列的,我们使用的memcached-session-managerjar包如下:

我这里提供下载,请到附件中下载即可。

将相关的jar包拷贝到指定目录:

node4节点:[root@node4 memcached-session-manager]# cp spymemcached-2.10.2.jar memcached-session-manager-1.8.1.jarjavolution/javolution-5.4.3.1.jar tc7/memcached-session-manager-tc7-1.8.1.jarmsm-javolution/msm-javolution-serializer-1.8.1.jar  /usr/local/tomcat/lib/node5节点:[root@node5 memcached-session-manager]# cp spymemcached-2.10.2.jar memcached-session-manager-1.8.1.jar javolution/javolution-5.4.3.1.jartc7/memcached-session-manager-tc7-1.8.1.jarmsm-javolution/msm-javolution-serializer-1.8.1.jar  /usr/local/tomcat/lib/

 

分别在两个tomcat服务器上的某host上定义一个用于测试的context容器,并在其中创建一个会话管理器,如下所示:

 

          
              
            

 

详细配置如下:

node4节点的配置:

[root@node4 ~]# cat/usr/local/tomcat/conf/server.xml
 
 
 
 
 
 
   
 
 
   
   
    
     
       
           
           
          
                 
         

 

node5节点的配置: 

[root@node5 ~]# cat/usr/local/tomcat/conf/server.xml
 
 
 
 
 
 
   
 
 
   
   
    
     
       
           
          
          
                 
         

如图所示,我们将其添加到默认的host下:

 

分别为两个context提供测试页面:

部署testapp应用:

# mkdir/usr/local/tomcat/webapps/testapp/{lib,classes,WEB-INF} -pv

 

node4节点的testapp部署及测试页面:

# vim/usr/local/tomcat/webapps/testapp/index.jsp添加如下内容:<%@ page language="java" %> Node4    

node4.stu31.com

   
            Session ID   <% session.setAttribute("stu31.com","stu31.com");%>       <%= session.getId() %>                  Created on       <%= session.getCreationTime() %>        

 

 

node5节点的testapp部署及测试页面:

# mkdir -pv/usr/local/tomcat/webapps/testapp/{WEB-INF,classes,lib}# vim/usr/local/tomcat/webapps/testapp/index.jsp添加如下内容:<%@ page language="java" %> Node5    

node5.stu31.com

   
            Session ID   <% session.setAttribute("stu31.com","stu31.com");%>       <%= session.getId() %>                 Created on       <%= session.getCreationTime() %>        

 

配置完成后我们重新启动tomcat服务:

# catalina.sh stop# catalina.sh start

访问测试:

 

配额制前端负载均衡节点,使用httpd服务器反向代理请求到后端tomcat服务器节点:

先注释到主配置文件/etc/httpd/conf/httpd.conf中的中心主机,如图:

配置反向代理:

[root@node3 ~]# vim/etc/httpd/conf.d/proxy.conf
   BalancerMember http://172.16.31.21:8080 loadfactor=1   BalancerMember http://172.16.31.22:8080 loadfactor=1   ProxySet  lbmethod=byrequests ProxyVia OffProxyRequests OffProxyPass / balancer://tomcat/ProxyPa***everse / balancer://tomcat/
   Order Allow,Deny   Allow From all 
   Order Allow,Deny   Allow From all

 

配置完成后检查语法:[root@node3 ~]# httpd -tSyntax OK 启动httpd服务器:[root@node3 ~]# service httpd start

 

访问测试,可以发现session会话实现了绑定;

 

我们将node5节点的memcached服务器关闭,看session会话转移到哪里了:

[root@node5 ~]# service memcached stopStopping memcached:                                        [  OK  ]

 

访问测试:

 

可以发现节点是转移到了node4,但是session会话的ID未改变,实现了缓存会话功能;

 

 

配置前端负载均衡节点,使用nginx服务器反向代理请求到后端tomcat服务器节点:

关闭httpd服务器:

#service httpd stop

 

配置nginx的主配置文件,向其中添加upstream服务器:

[root@node3 ~]# vim /etc/nginx/nginx.conf   upstream tcsrvs {       server 172.16.31.21:8080;       server 172.16.31.22:8080;    }

 

如图:

配置默认default.conf文件:

[root@node3 ~]# vim/etc/nginx/conf.d/default.conf   location / {        proxy_pass http://tcsrvs;       index  index.jsp index.htmlindex.htm;    }

 

配置如图:

配置完成后启动nginx服务器,

[root@node3 ~]# service nginx start

 

访问测试,

 

可以发现实现了会话保持;

 

至此;Apache/Nginx+Tomcat+Memcahced实现session管理的配置就完成了。