1.什么是memcache?
memcache是一套分布式的高速缓存系统,由LiveJournal的Brad Fitzpatrick开发,但目前被许多网站使用以提升网站的访问速度
尤其对于一些大型的、需要频繁访问数据库的网站访问速度提升效果十分显著 ,这是一套开放源代码软件,以BSD license授权发布
MemCache是一个自由、源码开放、高性能、分布式的分布式内存对象缓存系统,用于动态Web应用以减轻数据库的负载
它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高了网站访问的速度
MemCaChe是一个存储键值对的HashMap,在内存中对任意的数据(比如字符串、对象等)所使用的key-value存储
数据可以来自数据库调用、API调用,或者页面渲染的结果
MemCache设计理念就是小而强大,它简单的设计促进了快速部署、易于开发并解决面对大规模的数据缓存的许多难题
而所开放的API使得MemCache能用于Java、C/C++/C#、Perl、Python、PHP、Ruby等大部分流行的程序语言
另外,说一下MemCache和MemCached的区别
(1)MemCache是项目的名称
(2)MemCached是MemCache服务器端可以执行文件的名称
MemCache访问模型
特别澄清一个问题,MemCache虽然被称为"分布式缓存",但是MemCache本身完全不具备分布式的功能
MemCache集群之间不会相互通信
(与之形成对比的,比如JBoss Cache,某台服务器有缓存数据更新时,会通知集群中其他机器更新缓存或清除缓存数据)
所谓的"分布式",完全依赖于客户端程序的实现,就像上面这张图的流程一样
同时基于这张图,理一下MemCache一次写缓存的流程:
1)应用程序输入需要写缓存的数据
2)API将Key输入路由算法模块,路由算法根据Key和MemCache集群服务器列表得到一台服务器编号
3)由服务器编号得到MemCache及其的ip地址和端口号
4)API调用通信模块和指定编号的服务器通信,将数据写入该服务器,完成一次分布式缓存的写操作
读缓存和写缓存一样,只要使用相同的路由算法和服务器列表,只要应用程序查询的是相同的Key,MemCache客户端总是访问相同的客户端去读取数据,只要服务器中还缓存着该数据,就能保证缓存命中
这种MemCache集群的方式也是从分区容错性的方面考虑的,假如Node2宕机了,那么Node2上面存储的数据都不可用了,此时由于集群中Node0和Node1还存在,下一次请求Node2中存储的Key值的时候,肯定是没有命中的,这时先从数据库中拿到要缓存的数据,然后路由算法模块根据Key值在Node0和Node1中选取一个节点,把对应的数据放进去,这样下一次就又可以走缓存了,这种集群的做法很好,但是缺点是成本比较大。
2.MemCache的工作流程如下:
客户端把请求先发送给代理服务器(一般是nginx)
先检查客户端的请求数据是否在memcached中,如有,直接把请求数据返回,不再对数据库进行任何操作
如果请求的数据不在memcached中,就去查数据库,把从数据库中获取的数据返回给客户端
同时把数据缓存一份到memcached中(memcached客户端不负责,需要程序明确实现)
每次更新数据库的同时更新memcached中的数据,保证一致性
当分配给memcached内存空间用完之后,会使用LRU(Least Recently Used,最近最少使用)策略加上到期失效策略
失效数据首先被替换,然后再替换掉最近未使用的数据
Memcache是一个高性能的分布式的内存对象缓存系统,通过在内存里维护一个统一的巨大的hash表
它能够用来存储各种格式的数据,包括图像、视频、文件以及数据库检索的结果等
简单的说就是将数据调用到内存中,然后从内存中读取,从而大大提高读取速度
Memcache是danga的一个项目,最早是LiveJournal 服务的,最初为了加速 LiveJournal 访问速度而开发的,后来被很多大型的网站采用
Memcached是以守护程序(监听)方式运行于一个或多个服务器中,随时会接收客户端的连接和操作
3.Memcache特性和限制
在 Memcached中可以保存的item数据量是没有限制的,只要内存足够 。
Memcached单进程在32位系统中最大使用内存为2G,若在64位系统则没有限制,这是由于32位系统限制单进程最多可使用2G内存
要使用更多内存,可以分多个端口开启多个Memcached进程
最大30天的数据过期时间,设置为永久的也会在这个时间过期,常量REALTIME_MAXDELTA,606024*30控制
最大键长为250字节,大于该长度无法存储,常量KEY_MAX_LENGTH 250控制
单个item最大数据是1MB,超过1MB数据不予存储,常量POWER_BLOCK 1048576进行控制,它是默认的slab大小
最大同时连接数是200,通过 conn_init()中的freetotal进行控制,最大软连接数是1024,通过settings.maxconns=1024 进行控制
跟空间占用相关的参数:settings.factor=1.25, settings.chunk_size=48, 影响slab的数据占用和步进方式
memcached是一种无阻塞的socket通信方式服务,基于libevent库,由于无阻塞通信,对内存读写速度非常之快
memcached分服务器端和客户端,可以配置多个服务器端和客户端,应用于分布式的服务非常广泛
memcached作为小规模的数据分布式平台是十分有效果的
memcached是键值一一对应,key默认最大不能超过128个字 节,value默认大小是1M,也就是一个slabs
如果要存2M的值(连续的),不能用两个slabs,因为两个slabs不是连续的,无法在内存中 存储,故需要修改slabs的大小
多个key和value进行存储时,即使这个slabs没有利用完,那么也不会存放别的数据
可支持C/C++、Perl、PHP、Python、Ruby、Java、C#、Postgres、Chicken Scheme、Lua、MySQL和Protocol等语言客户端
4.实验思想
osi七层模型每一层都会加上属于自己的缓存
现在我们给lnmp中的php和nginx可以加上缓存,最后将mysql加上缓存
服务器一般不会把数据直接存储在自己上面,存储有专门的地方
交叉存储可以保证正常运行,数据共享,都会存储一份,本地存储+交叉存储
当服务器和自己的存储设备都坏了,也可以在其他服务器的存储器上找到自己的数据,可以保证客户正常访问
这篇文章我将教大家如何给php加缓存
从初级php开始,再到nginx,再到后端服务器,一级一级加上缓存,客户访问的速率会越来越快
现在我们先给php加上缓存,使用memcache这个工具缓存,相当于mysql
(类似于加在前端的varnish,用来把数据缓存在内存里面,一旦重启数据都没有了)
数据是缓存在内存里面的,用户请求的时候直接读取缓存
5.实验环境
实验主机名(IP) | 相关配置要求 |
---|---|
虚拟机server1(172.25.8.1) | 源码编译好的Mysql、Nginx、PHP |
物理机 | 172.25.8.250 |
6.实现的具体过程如下:
以下配置过程中使用到的相关资源是建立在PHP源码编译成功的基础上
(我是接着前面的博客写的,如果有什么疑问可以参考前面的文章)
- (1)在server1上面:将之前PHP编译完成的二进制命令加入到环境变量中,可以直接调用PHP命令
vim ~/.bash_profile 将php命令加入环境变量的配置文件当中
source ~/.bash_profile 使其生效
php tab可以看到可以使用php命令了
- (2)从真机给虚拟机传一个memcache的安装包
- (3)在server1上查看上传过来的安装包,解压:注意存放的地方
ls查看memcache的包(一个缓存数据的工具)
tar zxf memcache-2.2.5.tgz 解压
cd memcache-2.2.5/进入解压目录
- (4)创建预编译环境
phpize可以使的它进行编译
phpize是用来扩展php扩展模块的,通过phpize可以建立php的外挂模块
比如你想在原来编译好的php中加入memcached或者ImageMagick等扩展模块,可以使用phpize
phpize工具是在php安装目录下,基于这点phpize对应了当时的php环境
所以是要根据该php的配置情况生成对应的configure文件,建立一个configure文件
必须在一个目录下去运行phpize,那么phpize就知道你的的环境是哪个目录,并且configure文件建立在该目录下
- (5)./configure 编译
- (6)make && make install安装
- (7)在php文件中添加memcache模块
vim /usr/local/lnmp/php/etc/php.ini 将memcache缓存模块与php连接起来
加入 搜索extension 在800多行
加入: extension=memcache.so(这个模块以插件的形式运行)
- (8)重新加载php-fpm服务
/etc/init.d/php-fpm reload重启php服务
php -m | grep memcache可以看到这个模块已经加入到php中
php -m | grep mysql可以看到数据库也与mysql关联
- (9)安装memcache工具,开启memcache服务,监听端口为11211
yum install -y memcached安装这个服务,提供接口11211客户才能用(之前只是一个模块)
rpm -qa | grep memcache查看版本
rpm -ql memcached-1.4.4-3.el6.x86_64查看生成的各种文件
vim /etc/sysconfig/memcached 编辑配置文件
加入:-l 172.0.0.1
/etc/init.d/memcached start启动memcache服务
netstat -tnlp查看可以看到11211端口开启,只对本机
vim /etc/sysconfig/memcached 什么都不加,对所有都开启
/etc/init.d/memcached restart重启
netstat -tnlp
- (10)安装telnet工具,测试
yum install -y telnet安装这个命令
telnet localhost 11211使用这个检测本地的端口,存数据
stats
set name 0(表示顺序:键值) 0(表示缓存时间) 6(表示缓存的字符个数)
westoshaha错误
westos错误,时间已经过去
set name 0 0 6
westos正确
get name有
delete name
get name没有
set name 0 5 6再次创建为westos保存时间为5秒,5秒内查看没有失效,5秒后查看失效
等待5s
get name 没有
quit
创建westos,查看,没有失效,删除,再次查看失效,退出(quit)
0 0 6
编号 缓存时间 限制的字符数
- (11)将下面的文件复制到/usr/local/lnmp/nginx/html/文件下
vim memcache.php
cp memcache.php /usr/local/lnmp/nginx/html/放到默认发布目录下
cd /usr/local/lnmp/nginx/html/
- (12)修改memcache的密码和访问地址
vim memcache.php
加入管理员密码:redhat,名字memcache
172.25.12.1
注释掉一个memcache
重新加载服务
- (13)浏览器访问http://172.25.8.1/memcache.php 要输入用户和密码,可以看到现在命中率33.3%
通过nginx代理服务可以在浏览器输入172.25.12.1/memcache.php看到缓存页面,需要管理员登录
- (14)将下面的文件复制到/usr/local/lnmp/nginx/html/文件下
vim example.php
cp example.php /usr/local/lnmp/nginx/html/
- (15)再打开一个页面访问http://172.25.8.1/example.php
在浏览器输入172.25.8.1/example.php这个就相当于客户访问nginx(web服务器)的资源
多次刷新,返回memcache的页面刷新可以看到命中率接近100%
在浏览器页面看效果:
客户每访问172.25.12.1/example.php一次
172.25.12.1/memcache.php的缓存就会增多
- (16)安装ab命令,压力测试,模拟5000请求量
[root@server1 html]# yum whatprovides *ab
[root@server1 html]# yum install -y httpd-tools-2.2.15-29.el6_4.x86_64
真机测试: 使用ab这个检测工具进行测试
访问index.php慢而且失败500多次
ab -c 10 -n 5000 http://172.25.8.1/index.php慢,去后端加载慢
访问example.php 没有失败而且时间大大减少
ab -c 10 -n 5000 http://172.25.8.1/example.php快(即使并发请求几乎没有失败),直接从缓存中拿资源快
这个文件里面说了去加载memcache读取内存中的内容,这里面的内容我们可以自己写
其实这两个php文件(index.php、example.php)都相当于放在nginx代理服务器下web资源
客户访问的时候先去问nginx代理服务器
如果请求的是静态资源,nginx会直接将静态缓存的资源返回给客户
如果请求的是动态资源,nginx会通过php去找fsatcgi去加载数据库,再把资源给客户端
客户通过php访问后端资源慢,客户通过php的memcache缓存直接访问缓存在内存中的数据很快
类似于在php服务上面加了memcache服务,就可以缓存数据,使的数据的访问更快(也可以说是备份)
memcache.php只是一个管理员的页面而已