图文并茂超详细搭建memcache缓存服务器(nginx+php+memcache+mysql)

博主QQ:819594300javascript

博客地址:http://zpf666.blog.51cto.com/php

有什么疑问的朋友能够联系博主,博主会帮大家解答,谢谢支持!css


1、MemCache简述html

sessionjava

MemCache是一个自由、源码开放、高性能、分布式的分布式内存对象缓存系统,用于动态Web应用以减轻数据库的负载。它经过在内存中缓存数据和对象来减小读取数据库的次数,从而提升了网站访问的速度。 MemCaChe是一个存储键值对的HashMap,在内存中对任意的数据(好比字符串、对象等)所使用的key-value存储,数据能够来自数据库调用、API调用,或者页面渲染的结果。MemCache设计理念就是小而强大,它简单的设计促进了快速部署、易于开发并解决面对大规模的数据缓存的许多难题,而所开放的API使得MemCache能用于Java、C/C++/C#、Perl、Python、PHP、Ruby等大部分流行的程序语言。node

另外,说一下为何会有Memcache和memcached两种名称?其实Memcache是这个项目的名称,而memcached是它服务器端的主程序文件名mysql

MemCache的官方网站为http://memcached.org/linux

MemCache访问模型nginx

为了加深对memcache的理解,以memcache为表明的分布式缓存,访问模型以下:web

wKioL1kZCmiD8nysAAKDWwegddo172.jpg

特别澄清一个问题,MemCache虽然被称为”分布式缓存”,可是MemCache自己彻底不具有分布式的功能,MemCache集群之间不会相互通讯(与之造成对比的,好比JBoss Cache,某台服务器有缓存数据更新时,会通知集群中其余机器更新缓存或清除缓存数据),所谓的”分布式”,彻底依赖于客户端程序的实现,就像上面这张图的流程同样。

同时基于这张图,理一下MemCache一次写缓存的流程:

一、应用程序输入须要写缓存的数据

二、API将Key输入路由算法模块,路由算法根据Key和MemCache集群服务器列表获得一台服务器编号

三、由服务器编号获得MemCache及其的ip地址和端口号

四、API调用通讯模块和指定编号的服务器通讯,将数据写入该服务器,完成一次分布式缓存的写操做

读缓存和写缓存同样,只要使用相同的路由算法和服务器列表,只要应用程序查询的是相同的Key,MemCache客户端老是访问相同的客户端去读取数据,只要服务器中还缓存着该数据,就能保证缓存命中。

这种MemCache集群的方式也是从分区容错性的方面考虑的,假如Node2宕机了,那么Node2上面存储的数据都不可用了,此时因为集群中Node0和Node1还存在,下一次请求Node2中存储的Key值的时候,确定是没有命中的,这时先从数据库中拿到要缓存的数据,而后路由算法模块根据Key值在Node0和Node1中选取一个节点,把对应的数据放进去,这样下一次就又能够走缓存了,这种集群的作法很好,可是缺点是成本比较大。

一致性Hash算法

从上面的图中,能够看出一个很重要的问题,就是对服务器集群的管理,路由算法相当重要,就和负载均衡算法同样,路由算法决定着究竟该访问集群中的哪台服务器,先看一个简单的路由算法。

一、余数Hash

简单的路由算法可使用余数Hash:用服务器数目和缓存数据KEY的hash值相除,余数为服务器列表下标编号,假如某个str对应的HashCode是5二、服务器的数目是3,取余数获得1,str对应节点Node1,因此路由算法把str路由到Node1服务器上。因为HashCode随机性比较强,因此使用余数Hash路由算法就能够保证缓存数据在整个MemCache服务器集群中有比较均衡的分布。

若是不考虑服务器集群的伸缩性,那么余数Hash算法几乎能够知足绝大多数的缓存路由需求,可是当分布式缓存集群须要扩容的时候,就难办了。

就假设MemCache服务器集群由3台变为4台吧,更改服务器列表,仍然使用余数Hash,52对4的余数是0,对应Node0,可是str原来是存在Node1上的,这就致使了缓存没有命中。再举个例子,原来有HashCode为0~19的20个数据,那么:

那么不妨举个例子,原来有HashCode为0~19的20个数据,那么:

wKiom1kZCmjTqWCdAACxFjWQAJc761.jpg

如今扩容到4台,加粗标红的表示命中:

wKioL1kZCmny6EkJAADAZyEXYGk836.jpg

若是扩容到20+的台数,只有前三个HashCode对应的Key是命中的,也就是15%。固然现实状况确定比这个复杂得多,不过足以说明,使用余数Hash的路由算法,在扩容的时候会形成大量的数据没法正确命中(其实不只仅是没法命中,那些大量的没法命中的数据还在原缓存中在被移除前占据着内存)。在网站业务中,大部分的业务数据度操做请求上事实上是经过缓存获取的,只有少许读操做会访问数据库,所以数据库的负载能力是以有缓存为前提而设计的。当大部分被缓存了的数据由于服务器扩容而不能正确读取时,这些数据访问的压力就落在了数据库的身上,这将大大超过数据库的负载能力,严重的可能会致使数据库宕机。

这个问题有解决方案,解决步骤为:

(1)在网站访问量低谷,一般是深夜,技术团队加班,扩容、重启服务器

(2)经过模拟请求的方式逐渐预热缓存,使缓存服务器中的数据从新分布

二、一致性Hash算法

一致性Hash算法经过一个叫作一致性Hash环的数据结构实现Key到缓存服务器的Hash映射。简单地说,一致性哈希将整个哈希值空间组织成一个虚拟的圆环(这个环被称为一致性Hash环),如假设某空间哈希函数H的值空间是0~2^32-1(即哈希值是一个32位无符号×××),整个哈希空间以下:

wKiom1kZCmmSr1coAABtVvs_ySs582.jpg

下一步将各个服务器使用H进行一个哈希计算,具体可使用服务器的IP地址或者主机名做为关键字,这样每台机器能肯定其在上面的哈希环上的位置了,而且是按照顺时针排列,这里咱们假设三台节点memcache经计算后位置以下:

wKioL1kZCmmxRLICAACbdcB-0Q0865.jpg

接下来使用相同算法计算出数据的哈希值h,并由此肯定数据在此哈希环上的位置

假如咱们有数据A、B、C、D、4个对象,通过哈希计算后位置以下:

wKiom1kZCmrglQV4AACYlJn1LaU708.jpg

根据一致性哈希算法,数据A就被绑定到了server01上,D被绑定到了server02上,B、C在server03上,是按照顺时针找最近服务节点方法

这样获得的哈希环调度方法,有很高的容错性和可扩展性:

假设server03宕机:

wKiom1kZCmrxtnkfAAChWGHTeN8420.jpg

能够看到此时C、B会受到影响,将B、C被重定位到Server01。通常的,在一致性哈希算法中,若是一台服务器不可用,则受影响的数据仅仅是此服务器到其环空间中前一台服务器(即顺着逆时针方向行走遇到的第一台服务器)之间数据,其它不会受到影响。

考虑另一种状况,若是咱们在系统中增长一台服务器Memcached Server 04:

wKioL1kZCmujrjsmAACzzHKedEg676.jpg

此时A、D、C不受影响,只有B须要重定位到新的Server04。通常的,在一致性哈希算法中,若是增长一台服务器,则受影响的数据仅仅是新服务器到其环空间中前一台服务器(即顺着逆时针方向行走遇到的第一台服务器)之间数据,其它不会受到影响。

综上所述,一致性哈希算法对于节点的增减都只需重定位环空间中的一小部分数据,具备较好的容错性和可扩展性。

一致性哈希的缺点:在服务节点太少时,容易由于节点分部不均匀而形成数据倾斜问题。咱们能够采用增长虚拟节点的方式解决。

更重要的是,集群中缓存服务器节点越多,增长/减小节点带来的影响越小,很好理解。换句话说,随着集群规模的增大,继续命中原有缓存数据的几率会愈来愈大,虽然仍然有小部分数据缓存在服务器中不能被读到,可是这个比例足够小,即便访问数据库,也不会对数据库形成致命的负载压力。

MemCache实现原理

首先要说明一点,MemCache的数据存放在内存中

一、访问数据的速度比传统的关系型数据库要快,由于Oracle、MySQL这些传统的关系型数据库为了保持数据的持久性,数据存放在硬盘中,IO操做速度慢

二、MemCache的数据存放在内存中同时意味着只要MemCache重启了,数据就会消失

三、既然MemCache的数据存放在内存中,那么势必受到机器位数的限制,32位机器最多只能使用2GB的内存空间,64位机器能够认为没有上限

而后咱们来看一下MemCache的原理,MemCache最重要的是内存如何分配的,MemCache采用的内存分配方式是固定空间分配,以下图所示:

wKioL1kZCmvBSZasAAGYaCm4DAo414.jpg

这张图片里面涉及了slab_class、slab、page、chunk四个概念,它们之间的关系是:

一、MemCache将内存空间分为一组slab

二、每一个slab下又有若干个page,每一个page默认是1M,若是一个slab占用100M内存的话,那么这个slab下应该有100个page

三、每一个page里面包含一组chunk,chunk是真正存放数据的地方,同一个slab里面的chunk的大小是固定的

四、有相同大小chunk的slab被组织在一块儿,称为slab_class

MemCache内存分配的方式称为allocator(分配运算),slab的数量是有限的,几个、十几个或者几十个,这个和启动参数的配置相关。

MemCache中的value存放的地方是由value的大小决定的,value老是会被存放到与chunk大小最接近的一个slab中,好比slab[1]的chunk大小为80字节、slab[2]的chunk大小为100字节、slab[3]的chunk大小为125字节(相邻slab内的chunk基本以1.25为比例进行增加,MemCache启动时能够用-f指定这个比例),那么过来一个88字节的value,这个value将被放到2号slab中。放slab的时候,首先slab要申请内存,申请内存是以page为单位的,因此在放入第一个数据的时候,不管大小为多少,都会有1M大小的page被分配给该slab。申请到page后,slab会将这个page的内存按chunk的大小进行切分,这样就变成了一个chunk数组,最后从这个chunk数组中选择一个用于存储数据。

若是这个slab中没有chunk能够分配了怎么办,若是MemCache启动没有追加-M(禁止LRU,这种状况下内存不够会报Out Of Memory错误),那么MemCache会把这个slab中最近最少使用的chunk中的数据清理掉,而后放上最新的数据。

Memcache的工做流程:

wKiom1kZCmzworzSAACrA0MKnf8475.jpg

一、检查客户端的请求数据是否在memcached中,若是有,直接把请求数据返回,再也不对数据库进行任何操做,路径操做为①②③⑦。

二、若是请求的数据不在memcached中,就去查数据库,把从数据库中获取的数据返回给客户端,同时把数据缓存一份到memcached中(memcached客户端不负责,须要程序明确实现),路径操做为①②④⑤⑦⑥。

三、每次更新数据库的同时更新memcached中的数据,保证一致性。

四、当分配给memcached内存空间用完以后,会使用LRU(Least Recently Used,最近最少使用)策略加上到期失效策略,失效数据首先被替换,而后再替换掉最近未使用的数据。

Memcached特征:

协议简单:

   它是基于文本行的协议,直接经过telnet在memcached服务器上可进行存取数据操做

注:文本行的协议:指的是信息以文本传送,一个信息单元传递完毕后要传送换行。好比对于HTTP的GET请求来讲,GET/index.html HTTP/1.1是一行,接下去每一个头部信息各占一行。一个空行表示整个请求结束

基于libevent事件处理:

    Libevent是一套利用C开发的程序库,它将BSD系统的kqueue,Linux系统的epoll等事件处理功能封装成一个接口,与传统的select相比,提升了性能。

内置的内存管理方式:

    全部数据都保存在内存中,存取数据比硬盘快,当内存满后,经过LRU算法自动删除不使用的缓存,但没有考虑数据的容灾问题,重启服务,全部数据会丢失。

分布式

   各个memcached服务器之间互不通讯,各自独立存取数据,不共享任何信息。服务器并不具备分布式功能,分布式部署取决于memcache客户端。

Memcache的安装

分为两个过程:memcache服务器端的安装和memcached客户端的安装。

所谓服务器端的安装就是在服务器(通常都是linux系统)上安装Memcache实现数据的存储。

所谓客户端的安装就是指php(或者其余程序,Memcache还有其余不错的api接口提供)去使用服务器端的Memcache提供的数据,须要php添加扩展。

PHP的Memcache

2、centos7.2+nginx+php+memcache+mysql

环境描述:

wKiom1kZCmzxrWG_AAEPbDUo4jE485.jpg

nginx和php:

所需软件:nginx-1.10.2.tar.gz

php-5.6.27.tar.gz

ip地址:192.168.1.8

mysql:

所需软件:mysql-5.7.13.tar.gz

ip地址:192.168.1.9

memcache:

所需软件:memcached-1.4.33.tar.gz

ip地址:192.168.1.10

虚拟机环境以下:

wKiom1kZCmzj_gGjAACEwPrH14w317.jpg

下面开始正式的实验操做:

1)安装nginx

①解压缩zlib

wKioL1kZCm2xHOkgAAENnCfSbf8107.jpg

注意:不须要编译,只须要解压就行。

②解压缩pcre

wKiom1kZCm3SmuQeAAER8L0-qt8789.jpg

注意:不须要编译,只须要解压就行。

③yum安装nginx依赖包

wKioL1kZCm6xiIspAACosMXVtXE651.jpg

④下载安装nginx源码包

下载nginx的源码包:http://nginx.org/download

解压缩、编译及安装nginx源码包:

wKiom1kZCm-i8XruAAJp-v1Z5no448.jpg

图中配置、编译安装部分以下所示:

./configure--prefix=/usr/local/nginx1.10 --with-http_dav_module--with-http_stub_status_module --with-http_addition_module--with-http_sub_module --with-http_flv_module --with-http_mp4_module--with-pcre=/root/pcre-8.39 --with-zlib=/root/zlib-1.2.8 --with-http_ssl_module--with-http_gzip_static_module --user=www --group=www && make&& make install

说明:--with-pcre:用来设置pcre的源码目录。

         --with-zlib:用来设置zlib的源码目录。

         由于编译nginx须要用到这两个库的源码。

⑤作软连接

wKioL1kZCm-C4N7kAACw3t5mTmQ652.jpg

⑥nginx配置文件语法检测

wKiom1kZCnCSzo5kAADY9W3JOGQ400.jpg

⑦启动nginx

wKiom1kZCnCwv4q5AADCZf2xqA8809.jpg

⑧防火墙开启80端口例外

wKioL1kZCnCCvjCNAAEngl9noGU668.jpg

⑨在一台客户机浏览器上浏览nginx网页,测试一下nginx

wKiom1kZCnHRpdFbAAEhEMR50gA395.jpg

2)安装php

①安装libmcrypt

wKioL1kZCnHitEr6AAEBWfkQot0381.jpg

②yum安装php依赖包

wKioL1kZCnKR0peTAACXmGyYR5A532.jpg

③解压缩、编译及安装php源码包

wKiom1kZCnLTZTNtAAJTjgKlb3E936.jpg

图中配置、编译安装部分以下所示:

./configure --prefix=/usr/local/php5.6 --with-mysql=mysqlnd --with-pdo-mysql=mysqlnd --with-mysqli=mysqlnd --with-openssl --enable-fpm --enable-sockets--enable-sysvshm --enable-mbstring --with-freetype-dir --with-jpeg-dir--with-png-dir --with-zlib --with-libxml-dir=/usr --enable-xml --with-mhash --with-mcrypt=/usr/local/libmcrypt --with-config-file-path=/etc --with-config-file-scan-dir=/etc/php.d --with-bz2 --enable-maintainer-zts && make && make install

④拷贝php.ini样例文件

wKioL1kZCnSDPdU8AADMBWxYnxc226.jpg

修改/etc/php.ini文件,将short_open_tag修改成on,修改后的内容以下:

wKiom1kZCnTSZh74AAC9TSK1EFg531.jpg

wKioL1kZCnTg63O7AAA5d32Hd0Y539.jpg//支持php短标签

⑤建立php-fpm服务启动脚本并启动服务

wKiom1kZCnWhyhYwAAEX2wN5DSA737.jpg

提供php-fpm配置文件并编辑:

wKioL1kZCnaSR8RvAADmkCHvgWQ814.jpg

wKiom1kZCnbzPT_gAAA_mh4EPI8923.jpg

wKiom1kZCnbBtvTUAABO9f69WzM309.jpg

说明:若是是nginx和php分离部署,这里须要改为php真实的ip,而后php服务器还要开始9000端口例外。除此以外都和本博文同样便可。

wKioL1kZCnfRsG-7AABDWn1BDrM840.jpg

wKiom1kZCq2BgXRvAAA-joxh_Wo041.jpg

wKioL1kZCq3BcrcjAABHa1wvWVE118.jpg

wKiom1kZCq3Rfdp9AABG9gncDLc953.jpg

启动php-fpm服务:

wKioL1kZCq6xxPuNAADqNZtLKF0919.jpg

3)安装mysql

(在192.168.1.9主机上操做)

由于centos7.2默认安装了mariadb-libs,因此先要卸载掉

查看是否安装mariadb

#rpm-qa | grep mariadb

卸载mariadb

rpm-e --nodeps mariadb-libs

wKioL1kZCq7R3ftXAACy9rMRCIo795.jpg

而后具体的mysql安装请参考个人mysql5.7.13的安装,博文地址:

http://zpf666.blog.51cto.com/11248677/1908988

这里个人mysql是安装好的,咱们看一下服务是否启动:

wKiom1kZCq_A1NfDAACeYiWsTKg938.jpg

防火墙开启3306端口例外:

wKiom1kZCq_Ae_LcAAEauFteYpg255.jpg

四、安装memcached服务端

(在192.168.1.10主机操做)

memcached是基于libevent的事件处理。libevent是个程序库,它将Linux的epoll、BSD类操做系统的kqueue等事件处理功能封装成统一的接口。即便对服务器的链接数增长,也能发挥I/O的性能。 memcached使用这个libevent库,所以能在Linux、BSD、Solaris等操做系统上发挥其高性能。

①安装memcached依赖库libevent

wKioL1kZCrDS0JLsAAEPyB1Sbio340.jpg

②安装memcached

wKiom1kZCrDBqh2sAAEVwR9UXY8626.jpg

③检测memcache是否安装成功

wKioL1kZCrHQuwKTAAEB_7-AmRg027.jpg

经过以上操做就很简单的把memcached服务端编译好了。这时候就能够打开服务端进行工做了。

④配置环境变量

进入用户宿主目录,编辑.bash_profile,为系统环境变量LD_LIBRARY_PATH增长新的目录,须要增长的内容以下:

wKiom1kZCrHhl6o2AAC53gzVZ4Y369.jpg

wKioL1kZCrKwzFC7AACyY3fNhr0648.jpg

图片中具体内容以下:

MEMCACHED_HOME=/usr/local/memcached

LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$MEMCACHED_HOME/lib

⑤启动memcache服务

wKioL1kZCrLSlGK7AADPPMmMbRY026.jpg

注意:-m后面跟的是分配给memcache的内存,不能大于等于本主机内存。个人主机是2048M内存,我给了1024M。

启动参数说明:

-d      选项是启动一个守护进程。

-m  分配给Memcache使用的内存数量,单位是MB,默认64MB。

-l      监听的IP地址。(默认:INADDR_ANY,全部地址)

-p  设置Memcache的TCP监听的端口,最好是1024以上的端口。

-u  运行Memcache的用户,若是当前为root的话,须要使用此参数指定用户。

-c     选项是最大运行的并发链接数,默认是1024。

-P  设置保存Memcache的pid文件。

-M    内存耗尽时返回错误,而不是删除项

-f      块大小增加因子,默认是1.25

-n     最小分配空间,key+value+flags默认是48

-h     显示帮助

wKiom1kZCrPRmcQjAACrw50ePk0573.jpg

⑥防火墙开启11211端口例外

wKioL1kZCrOgk_zvAAEWxYwi0j4395.jpg

⑦刷新用户环境变量

wKiom1kZCrSRdCzJAACn8s4obgk449.jpg

刷新环境变量的时候报了一个错误,让执行那条命令,你就执行如下便可。

而后再次刷新环境变量:

wKioL1kZCrSTctvdAADwfhuegBM647.jpg

⑧编写memcached服务启停脚本

wKiom1kZCrWhsR56AADQpz0z21g897.jpg

脚本内容以下:

#!/bin/sh

#

# pidfile:/usr/local/memcached/memcached.pid

# memcached_home: /usr/local/memcached

# chkconfig: 35 21 79

# description: Start and stop memcachedService

 

# Source function library

. /etc/rc.d/init.d/functions

 

RETVAL=0

 

prog="memcached"

basedir=/usr/local/memcached

cmd=${basedir}/bin/memcached

pidfile="$basedir/${prog}.pid"

 

#interface to listen on (default:INADDR_ANY, all addresses)

ipaddr="192.168.1.10"

#listen port

port=11211

#username for memcached

username="root"

#max memory for memcached,default is 64M

max_memory=1024

#max connections for memcached

max_simul_conn=10240

start() {

echo -n $"Starting service:$prog"

$cmd -d -m $max_memory -u $username -l$ipaddr -p $port -c $max_simul_conn -P $pidfile

RETVAL=$?

echo

[ $RETVAL -eq 0 ] && touch/var/lock/subsys/$prog

}

 

stop() {

echo -n $"Stopping service:$prog  "

run_user=$(whoami)

pidlist=$(ps -ef | grep $run_user | grepmemcached | grep -v grep | awk '{print($2)}')

for pid in $pidlist

do

kill -9 $pid

if [ $? -ne 0 ]; then

return 1

fi

done

RETVAL=$?

echo

[ $RETVAL -eq 0 ] && rm -f/var/lock/subsys/$prog

}

 

# See how we were called.

case "$1" in

start)

start

;;

stop)

stop

;;

restart)

stop

start

;;

*)

echo "Usage: $0{start|stop|restart|status}"

exit 1

esac

exit $RETVAL

设置脚本可被执行:

wKioL1kZCrXTtYk3AAHtVWxcJ0E374.jpg

说明:

shell脚本中return的做用

1)终止一个函数.

2)return命令容许带一个整型参数, 这个整数将做为函数的"退出状态

码"返回给调用这个函数的脚本, 而且这个整数也被赋值给变量$?.

3)命令格式:returnvalue

  

先别急着闪,memcache服务脚本是配置好了,可是有个问题:

wKiom1kZCrWQGcmfAADhv21Qk2E976.jpg

从上图能够看出,重启不了memcache,这是由于当前memcache服务是运行着的,这个服务是开始的时候第⑤步启动的,因此我们如今用服务脚本是重启不了的,解决办法以下:

wKioL1kZCragwLhBAAD4mPlU78s830.jpg

就是杀死正在运行的memcache服务的进程。

而后开始再重启服务:

wKiom1kZCrbR-zpdAAGNyNMCtpI168.jpg

至此就能够用服务脚本控制memcache服务了。

五、配置nginx.conf文件(在nginx&&php主机上操做)

①配置成以下的nginx.conf文件

wKiom1kZCrfgwuxKAACcA312wpY873.jpg

把原有的东西所有删除,配置成以下内容:

说明一下:我这里nginx&&php主机用的是4核,若是你的不是4核,请修改worker_cpu_affinity,若是是4核,请忽略该问题,所有复制我写好的内容便可。

user www www;

worker_processes  4;

worker_cpu_affinity 0001 0010 0100 1000;

error_log  logs/error.log;

#error_log  logs/error.log  notice;

#error_log  logs/error.log  info;


pid        logs/nginx.pid;


events {

use epoll;

   worker_connections  65535;

multi_accept on;

}


http {

include       mime.types;

   default_type application/octet-stream;


   #log_format  main  '$remote_addr - $remote_user [$time_local]"$request" '

   #                  '$status$body_bytes_sent "$http_referer" '

   #                 '"$http_user_agent" "$http_x_forwarded_for"';


   #access_log  logs/access.log  main;


sendfile        on;

tcp_nopush     on;

   keepalive_timeout  65;

tcp_nodelay on;

client_header_buffer_size 4k;

open_file_cache max=102400 inactive=20s;

   open_file_cache_valid 30s;

open_file_cache_min_uses 1;

   client_header_timeout 15;

   client_body_timeout 15;

reset_timedout_connection on;

   send_timeout 15;

server_tokens off;

client_max_body_size 10m;


   fastcgi_connect_timeout     600;

   fastcgi_send_timeout 600;

   fastcgi_read_timeout 600;

fastcgi_buffer_size 64k;

   fastcgi_buffers     4 64k;

fastcgi_busy_buffers_size 128k;

fastcgi_temp_file_write_size 128k;

   fastcgi_temp_path /usr/local/nginx1.10/nginx_tmp;

fastcgi_intercept_errors on;

   fastcgi_cache_path /usr/local/nginx1.10/fastcgi_cache levels=1:2  keys_zone=cache_fastcgi:128m inactive=1d max_size=10g;


gzip on;

   gzip_min_length  2k;

   gzip_buffers     4 32k;

   gzip_http_version 1.1;

   gzip_comp_level 6;

   gzip_types  text/plain text/csstext/javascript application/json application/javascript application/x-javascript application/xml;

gzip_vary on;

gzip_proxied any;

server {

listen       80;

 server_name  www.benet.com;


       #charset koi8-r;


       #access_log logs/host.access.log  main;


location ~*^.+\.(jpg|gif|png|swf|flv|wma|wmv|asf|mp3|mmf|zip|rar)$ {

valid_referers none blocked  www.benet.com benet.com;

if ($invalid_referer) {

                #return 302  http://www.benet.com/img/nolink.jpg;

return 404;

break;

             }

access_log off;

       }

location / {

root  html;

index index.php index.html index.htm;

       }

location ~*\.(ico|jpe?g|gif|png|bmp|swf|flv)$ {

expires 30d;

            #log_not_found off;

access_log off;

       }


location ~* \.(js|css)$ {

expires 7d;

log_not_found off;

access_log off;

       }


location = /(favicon.ico|roboots.txt) {

access_log off;

log_not_found off;

       }

location /status {

stub_status on;

       }

location ~ .*\.(php|php5)?$ {

root html;

            fastcgi_pass 127.0.0.1:9000;

            fastcgi_index index.php;

include fastcgi.conf;

#            fastcgi_cache cache_fastcgi;

            fastcgi_cache_valid 200 302 1h;

            fastcgi_cache_valid 301 1d;

fastcgi_cache_valid any 1m;

            fastcgi_cache_min_uses 1;

fastcgi_cache_use_stale error timeout invalid_header http_500;

            fastcgi_cache_key http://$host$request_uri;

       }

       #error_page  404              /404.html;

       # redirect server error pages to the static page /50x.html

       #

       error_page   500 502 503 504  /50x.html;

location = /50x.html {

root  html;

       }

  }

}

                        

②重启nginx服务

wKioL1kZCrjRXqp0AAFxeAPqshg195.jpg

③编写一个php测试页

wKiom1kZCrjzbmMnAACssfO-DBA802.jpg

wKioL1kZCrjThbZ9AACOAwoUXVA426.jpg

④在客户端使用浏览器访问test1.php测试页

wKiom1kZCrmAqqszAADdfWYGaHk029.jpg

六、memcache客户端(在nginx&&php主机上操做)

说明:memcache分为服务端和客户端。服务端用来存放缓存,客户端用来操做缓存。

安装php扩展库(phpmemcache)

说明:安装PHP Memcache扩展:

可使用php自带的pecl安装程序

#/usr/local/php5.6/bin/pecl install memcache

也能够从源码安装,他是生成php的扩展库文件memcache.so。

①安装memcache扩展库

wKioL1kZCrryrdscAAINUEZks-s281.jpg

wKioL1kZCrqwcYidAAC7eqSOCBc296.jpg

图片中内容以下:

./configure --enable-memcache --with-php-config=/usr/local/php5.6/bin/php-config && make && make install

wKiom1kZCruD61hUAACNUqROcDc157.jpg

记住安装完毕后,最后一行你的这个路径。

/usr/local/php5.6/lib/php/extensions/no-debug-zts-20131226/

②修改php.ini

wKiom1kZCrviQkA7AAC8-OoxwSw026.jpg

添加以下一行内容:

wKioL1kZCrzTau2vAABNt9As1d0398.jpg

图片中内容以下:

extension=/usr/local/php5.6/lib/php/extensions/no-debug-zts-20131226/memcache.so

③重启php-fpm服务

wKioL1kZCxrTx0OZAAGVcAWOywA271.jpg

④测试

说明:检查php扩展是否正确安装。

主要是看查询结果中是否有memcache项。

wKiom1kZCxuzhX34AAJYLPlMbdA010.jpg

⑤在客户机浏览器上再次访问test1.php

则看到不到memcache和在session会话里面看不到memcache。

这是由于,nginx配置文件里配置了fast-cgi缓存,若是不注释点这一行,客户端访问的test1.php的数据,是fast-cgi缓存的,由于有缓存,memcache就起不到做用了。

解决办法以下:

wKioL1kZCxvhdNILAAChQ8_Bv8s497.jpg

wKiom1kZCxvQfxDDAABUPqvwClI766.jpg

wKioL1kZCxvBZvZqAAEii425iqw491.jpg

再次刷新test1.php页面,就能够看见以下的两个截图:

wKiom1kZCxzRc8tPAABa8sQkIzQ457.jpg

wKioL1kZCxywKxzAAABvSmsCweQ991.jpg

⑥编写test2.php测试页

说明:这个测试页测试的是往memcache服务器写/读数据测试

wKiom1kZCxzBGI9lAACfUZi_G_g516.jpg

具体内容以下:

<?php

$memcache = new Memcache;

$memcache->connect('192.168.1.10',11211) or die ("Could not connect");

$version = $memcache->getVersion();

echo "Server's version:".$version."<br/>";

$tmp_object = new stdClass;

$tmp_object->str_attr = 'test';

$tmp_object->int_attr = 123;

$memcache->set('key', $tmp_object,false, 10) or die ("Failed to save data at the server");

echo "Store data in the cache (datawill expire in 10 seconds)<br/>";

$get_result = $memcache->get('key');

echo "Data from thecache:<br/>";

var_dump($get_result);

?>

在客户机上访问test2.php

wKioL1kZCx2AusuqAADstILwzkE070.jpg

⑦使用memcache实现session共享

配置php.ini中的Session为memcache方式。

wKiom1kZCx6Cz4clAAC_4u41qEM623.jpg

wKiom1kZCx6RFcL0AABnpW_WV-4761.jpg

wKioL1kZCx7SQzxaAABrEOzKkkg047.jpg

说明:1394行是修改

          1424行是添加

两行的文字内容以下:

session.save_handler = memcache

session.save_path = "tcp://192.168.1.10:11211?persistent=1&weight=1&timeout=1&retry_interval=15"

注:

ession.save_handler:设置session的储存方式为memcache 。默认以文件方式存取session数据,若是想要使用自定义的处理来存取session数据,好比memcache方式则修为session.save_handler = memcache

session.save_path:设置session储存的位置,多台memcache用逗号隔开

使用多个 memcached server 时用逗号”,”隔开,能够带额外的参数”persistent”、”weight”、”timeout”、”retry_interval”等等,

相似这样的:

"tcp://host:port?persistent=1&weight=2,tcp://host2:port2"。

memcache实现session共享也能够在某个一个应用中设置:

ini_set("session.save_handler","memcache");

ini_set("session.save_path","tcp://192.168.0.9:11211");

ini_set()只对当前php页面有效,而且不会去修改php.ini文件自己,也不会影响其余php页面。

⑧测试memcache可用性

重启php-fpm:

wKioL1kZCx-TaVHIAAGcny4vtVs896.jpg

在nginx&&php

服务器上新建//usr/local/nginx1.10/html/memcache.php文件。内容以下:

wKiom1kZCx_CPVd8AACh8uEMryc198.jpg

<?php

session_start();

if (!isset($_SESSION['session_time']))

{

 $_SESSION['session_time'] = time();

}

echo "session_time:".$_SESSION['session_time']."<br/>";

echo"now_time:".time()."<br />";

echo"session_id:".session_id()."<br />";

?>

    

这个memcache.php的测试页面主要测试的是:

当客户机访问时,给客户机生成一个session信息,这个session就是记录在什么时间点缓存到memcache的数据。

wKioL1kZCyDSVGw5AADzhyZWOtg461.jpg

刷新一下页面,再看:

wKiom1kZCyGjn7AbAAEEGEEy8w0520.jpg

每刷一次页面,now_time的值就一直在涨,而session_time一直不会变的,由于是session会话保持嘛。

访问网址http://192.168.1.8/memcache.php能够查看session_time是否都是为memcache中的Session,同时能够在不一样的服务器上修改不一样的标识查看是否为不一样的服务器上的。

能够直接用sessionid 去 memcached 里查询一下:

wKiom1kZCyGR0IsqAADKTNH1AT0904.jpg

wKioL1kZCyPT04sNAAXXncjLnUM006.jpg

说明:获得session_time|i:1493893966;这样的结果,说明session 正常工做。

默认memcache会监听11221端口,若是想清空服务器上memecache的缓存,通常使用的是:

wKiom1kZCyTygSIjAAJkbS1JHnU014.jpg

或者

wKioL1kZCyXg6bJfAADKT6h9QYc645.jpg

说明:使用flush_all 后并非删除memcache上的key,而是置为过时。

memcache安全配置:

由于memcache不进行权限控制,所以须要经过iptables将memcache仅开放个web服务器。

七、测试memcache缓存数据库数据

①先在Mysql服务器上建立测试表

wKioL1kZCyXQbjynAAC4YrzKNAc722.jpg

wKiom1kZCyXglxuCAAEiSSINcMI495.jpg

wKioL1kZCybiuJ0QAAEZ2JurJk0225.jpg

wKiom1kZCyaCu7dQAADXFFVnH14227.jpg

wKioL1kZCyeCNYUMAAGp8xQpxIg086.jpg

②编写测试脚本

做用:用于测试memcache是否缓存数据成功。

先须要为这个脚本添加一个只读的数据库用户,命令格式:

wKiom1kZCyfQGqgYAADJw_At5-E631.jpg

在web服务器上建立测试脚本内容以下:

wKioL1kZCyfSG0UuAACk-firJYs465.jpg

<?php

$memcachehost = '192.168.1.10';

$memcacheport =11211;

$memcachelife = 60;

$memcache = new Memcache;

$memcache->connect($memcachehost,$memcacheport)or die ("Could not connect");

$query="select * from test1 limit 10";

$key=md5($query);

if(!$memcache->get($key))

{

                $conn=mysql_connect("192.168.1.9","user","123456");

                mysql_select_db(testdb1);

                $result=mysql_query($query);

while ($row=mysql_fetch_assoc($result))

                {

                        $arr[]=$row;

                }

                $f = 'mysql';

               $memcache->add($key,serialize($arr),0,30);

                $data = $arr ;

}

else{

       $f = 'memcache';

       $data_mem=$memcache->get($key);

       $data = unserialize($data_mem);

}

echo $f;

echo "<br>";

echo "$key";

echo "<br>";

//print_r($data);

foreach($data as $a)

{

echo "number is <b><fontcolor=#FF0000>$a[id]</font></b>";

echo "<br>";

echo "name is <b><font color=#FF0000>$a[name]</font></b>";

echo "<br>";

}

?>

③访问页面测试

wKiom1kZCyjzpnL-AAHBL6UMzg0208.jpg

说明:若是出现mysql表示memcached中没有内容,须要memcached从数据库中取得

再刷新页面,若是有memcache标志表示此次的数据是从memcached中取得的。

memcached有个缓存时间默认是1分钟,过了一分钟后,memcached须要从新从数据库中取得数据。

wKiom1kZCyjR5l8uAAHJfnEsaTA599.jpg

④查看 Memcached 缓存状况

咱们须要使用 telnet 命令查看。

wKioL1kZCymgrKbMAAGtyMdttKo619.jpg

wKioL1kZCyuwbhSTAAUGccE_acY006.jpg

wKiom1kZCy2BTgPiAAPFGUgS6oE045.jpg

wKiom1kZC27hLVbGAAQJzTC84BE474.jpg

本文出自 “IT技术助手” 博客,请务必保留此出处http://zpf666.blog.51cto.com/11248677/1925729

相关文章
相关标签/搜索