lnmp的缓存

来源:互联网 发布:怎么在淘宝上买东西 编辑:程序博客网 时间:2024/06/06 16:59

前言

        前几篇文章,我们搭建的lnmp的最基础部分,客户端可以请求我们的资源,请求数少的时候,觉得可以;但如果说我们的的网站的访问量增大之后,那么我们搭建的lnmp就不符合我们的需求了,因为这样的lnmp没有办法处理这么多的请求,性能会下降,响应给客户端的时间也会越来越长。

        我们知道,客户端在发送请求到收到响应,这期间当中,什么占时间呢?有网络I/O,和服务器端的磁盘的I/O。那么我们现在从服务器的磁盘I/O入手,对我们的lnmp进行完善。

        cpu从内存拿数据比从磁盘拿数据要快很多,所以我们来看整个lnmp中那些地方可供我们加缓存。

        我们先来看lnmp的整个框架是怎样的,以便于我们找到加缓存的地方。


如上图所示,

当客户端请求静态数据,nginx自己处理,这里会有磁盘I/O;

当客户端请求动态数据,nginx通过fastcgi把请求转交给后面的应用程序服务器,当这些应用程序拿数据就需要去后面的MySQL去拿,这里就又有一个磁盘I/O。

所以我们可以在这两个地方加缓存,那什么可以用来做缓存呢?




一、缓存系统


1.memcache

       memcache是一套分布式的高速缓存系统,目前被许多网站使用以提升网站的访问速度,尤其对于一些大型的、需要频繁访问数据库的网站访问速度提升效果十分显著[1] 。这是一套开源软件,以BSD license授权发布。


2.Redis

        redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。

        Redis 是一个高性能的key-value数据库。 redis的出现,很大程度补偿了memcached这类key/value存储的不足,在部 分场合可以对关系数据库起到很好的补充作用。它提供了Java,C/C++,C#,PHP,JavaScript,Perl,Object-C,Python,Ruby,Erlang等客户端,使用很方便。


二、PHP添加memcache模块


操作前提:已安装配置好php,

1.下载memcache安装包,并且将memcache解压

# wget http://pecl.php.NET/get/memcache-2.2.3.tgz

# tar -zxvf memcache-2.2.3.tgz


2.将php安装路径下的bin的绝对路径添加到环境变量当中

# vim ~/.bash_profile

PATH=$PATH:$HOME/bin:/usr/local/lnmp/mysql/bin:/usr/local/lnmp/php/bin

# source ~/.bash_profile


3.在memcache的解压目录下执行phpize

# cd memcache-2.2.3/

# phpize                                #phpize是用来扩展php扩展模块的,通过phpize可以建立php的外挂模块


4.安装php-devel,如果已经安装过了就不用了

# yum install -y php-devel


5.编译安装memcached

# ./configure

# make install

# install


6.在配置文件中添加memcached模块

# vim php.ini

在第851行后面任意一行添加 extension=memcache.so

# /etc/init.d/php-fpm reload                      #重启php-fpm

# php -m | grep memcache                      #这回可以显示出来memcache,代表php已经成功安装上了动态模块memcache


7.安装memcached,开启memcached服务

# yum install memcached -y

# /etc/init.d/memcached start

memcached是监听在11211端口上的


/etc/sysconfig/memcached文件:
文件中内容如下
PORT=”11211″         #监听端口
USER=”root”             #使用的身份
MAXCONN=”1024″   #同时最大连接数
CACHESIZE=”64″     #使用的内存大小
OPTIONS=”"             #附加参数,例如:OPTIONS=”-l 127.0.0.1″,只能本机访问,不对公网开放

实验:从网页上测试并查看memcache的命中率

将解压目录下的example.php,memcache.php放到nginx的发布目录里面

example.php:用来连接memcache并发起请求

memcache.php:能显示memcache的命中率


memcache.php需要修改为下图所示


访问memcache.php,通过访问example.php来对memcache发起连接

这里要添的就是上图的用户memcache和密码westos


我们可以看到当没有访问memcache时,他的命中率和未命中率都是50%


其实除了这种安装memcached的安装包的方法,其实还有一种办法是直接重新编译php,编译的时候加上参数–enable-memcache[=DIR] 选项

当php添加了memcache模块之后的请求处理流程:


1.客户端发来请求

2.如果是静态的nginx自己就处理了,如果是动态的,nginx会将请求向后转发给php/tomcat,

3.此时php/tomcat会先去memcache中找,如果找到就直接返回

4.如果找不到,就会去数据库中查找,

5.如果查找到之后,就给memcache保存一份,

6.然后返回给php/tomcat

7.php/tomcat整合好资源之后就返回给nginx

8.nginx响应给客户端


三、nginx+memcache


1.下载安装包openresty-1.11.2.3.tar.gz,解压

# wget https://openresty.org/download/openresty-1.11.2.3.tar.gz

# tar zxf openresty-1.11.2.3.tar.gz


2.编译安装

进入解压后目录

# ./configure

# gmake

# gmake  install


3.安装后配置

# /etc/init.d/memcached start                      # 启动memcached

# /etc/init.d/php-fpm  start                             #启动php-fpm

# cd /usr/local/openresty/

# ls

bin  luajit  lualib  nginx  pod  resty.index  site

我们可以发现openresty自带有nginx ,修改nginx的配置文件




启动openresty 自带的nginx,并且编写一个php的测试页

4.进行压力测试

ab命令是Apache的Web服务器的性能测试工具,它可以测试安装Web服务器每秒种处理的HTTP请求

来自: http://man.linuxde.net/ab
ab命令是Apache的Web服务器的性能测试工具,它可以测试安装Web服务器每秒种处理的HTTP请求

来自: http://man.linuxde.net/ab
命令ab:

ab是Apache的Web服务器的性能测试工具,它可以测试安装Web服务器每秒种处理的HTTP请求。

其中-n代表每次并发量,-c代表总共发送的数量

测试结果的意义:

Document Path:          /  ###请求的资源
Document Length:        50679 bytes  ###文档返回的长度,不包括响应头

Concurrency Level:      3000   ###并发个数
Time taken for tests:   30.449 seconds   ###总请求时间
Complete requests:      3000     ###总请求数
Failed requests:        0     ###失败的请求数
Write errors:           0
Total transferred:      152745000 bytes
HTML transferred:       152037000 bytes
Requests per second:    98.52 [#/sec] (mean)      ###平均每秒的请求数
Time per request:       30449.217 [ms] (mean)     ###平均每个请求消耗的时间
Time per request:       10.150 [ms] (mean, across all concurrent requests)  ###上面的请求除以并发数
Transfer rate:          4898.81 [Kbytes/sec] received   ###传输速率

  50%   7778   ###50%的请求都在7778Ms内完成




从上面的信息来看,我们现在服务器的性能还是很差的,我们来继续配置

        upstream memcacheds {
                server 127.0.0.1:11211;                         ##memc-nginx是一个标准的upstream模块,因此首先需要定义memcache的upstream。这里我在本机上启动了一个memcache服务,端口为默认的11211
                keepalive 512;                                         ##keepalive指令是http-upsteram-keepalive-module提供的功能,这里我们最大保持512个不立即关闭的连接用于提升性能。
        }

location /memc {
                        internal;
                        memc_connect_timeout 100ms;
                        memc_send_timeout 100ms;
                        memc_read_timeout 100ms;
                        set $memc_key $query_string;
                        set $memc_exptime 300;
                        memc_pass memcacheds;
                }

上为memc-nginx-module配置location,我们配置为/memc,所有请求都通过请求这个location来操作memcache,memc-nginx-module存取memcache是基于http method语义的,使用http的GET方法表示get、PUT方法表示set、DELETE方法表示delete。这里我们将/memc设为internal表示只接受内部访问,不接收外部http请求,这是为了安全考虑,当然如果需要通过http协议开放外部访问,可以去掉internal然后使用deny和allow指令控制权限。比较重要的是$memc_key这个变量,它表示以什么作为key,这里我们直接使用Nginx内置的$query_string来作为key,$memc_exptime表示缓存失效时间,以秒记。这里统一设为300(5分钟),在实际应用中可以根据具体情况为不同的内容设置不同的过期时间。


        location ~ \.php$ {
            set $key $uri$args;                                     ##设置key的值是
            srcache_fetch GET /memc $key;
            srcache_store PUT /memc $key;
            root           html;
            fastcgi_pass   127.0.0.1:9000;
            fastcgi_index  index.php;
            #fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
            include        fastcgi.conf;
        }



最后我们为“~ \.php$”这个location配置了缓存,这表示所有以“.php”结尾的请求都会结果被缓存,当然这里只是示例需要,实际中一般不会这么配,而是为特定需要缓存的location配置缓存。

srcache_fetch表示注册一个输入拦截处理器到location,这个配置将在location进入时被执行;而srcache_store表示注册一个输出拦截器到location,当location执行完成并输出时会被执行。注意srcache模块实际可以与任何缓存模块进行配合使用,而不必一定是memc。这里我们以$uri$args作为缓存的key。

经过上述配置后,相当于对Nginx增加了如下逻辑:当所请求的uri以“.php”结尾时,首先到memcache中查询有没有以$uri$args为key的数据,如果有则直接返回;否则,执行location的逻辑,如果返回的http状态码为200,则在输出前以$uri$args为key,将输入结果存入memcache。




进行压测


这回性能还不错


添加了nginx+memcache之后,请求处理流程:


1.客户端发来请求

2.如果是静态的nginx自己处理,若是动态的nginx会先去memcache中查找,找到就直接返回

3.如果没找到,再将请求转发给后端

4.后端去数据库中查找,如果没有找到返回错误信息给nginx

5.如果找到的话就放到memcache一份,

6.返回给nginx

7.nginx响应客户端



推荐阅读文章:

Memcache缓存系统原理:http://www.cnblogs.com/WuNaiHuaLuo/p/5225330.html

关于CGI:Tomcat、PHP、Perl、Python和FastCGI之间的关系:http://www.mamicode.com/info-detail-24206.html


原创粉丝点击