在WEB开发中用来应付高流量最有效的办法就是用缓存技术,能有效的提升服务器负载性能,用空间换取时间。
缓存通常用来php
使用缓存的2个主要缘由:css
应用层缓存这块跟开发人员关系最大,也是平时常常接触的。html
应用层缓存的架构也能够分几种:前端
比较常见的应用层分布式缓存容器,Memcache、共享文件服务器、MemcacheDb、Tokyo Tyrant。 php里面也有好比x-cache,apc等的基于进程的缓存,这种缓存比分布式缓存速度快,可是限于跟应用的一个机器。 java实现的缓存也比较多,好比oscache,jcache ,ehcached等等。java
咱们这里说的前端缓存能够理解为通常使用的cdn技术,利用squid等作前端缓冲技术,主要仍是针对静态文件类型,好比图片,css,js,html等静态文件。
通常针对静态资源如CSS,JS,图片等使用缓存,缘由以下:node
前端比较经常使用的就是squid,Varnish Cache,ncache等等。Varnish是一款高性能的开源HTTP加速器,挪威最大的在线报纸 Verdens Gang (vg.no) 使用3台Varnish代替了原来的12台squid,性能比之前更好。web
客户端缓存依赖于浏览器的实现,目前通常的浏览器都实现了基于http都信息来缓存相应的文件。浏览器端的缓存,可让用户请求一次以后,下一次不在从服务器端请求数据,直接从本地缓存读取,能够减轻服务器负担也能够加快用户的访问速度。
浏览器缓存分为强缓存和协商缓存:数据库
强缓存与协商缓存区别:强缓存不发请求到服务器,协商缓存会发请求到服务器。apache
如何设置缓存
1. HTML Meta标签控制缓存(非HTTP协议定义)
<META HTTP-EQUIV="Pragma" CONTENT="no-cache">
上述代码的做用是告诉浏览器当前页面不被缓存,每次访问都须要去服务器拉取。这种方法使用上很简单,但只有部分浏览器能够支持,并且全部缓存代理服务器都不支持,由于代理不解析HTML内容自己。segmentfault
2. HTTP头信息控制缓存
HTTP头信息发送在HTML代码以前,只能被浏览器和一些中间缓存能看到,一个典型的HTTP 1.1协议返回的头信息看上去像这样:
HTTP/1.1 200 OK Date: Fri, 30 Oct 1998 13:19:41 GMT Server: Apache/1.3.3 (Unix) Cache-Control: max-age=3600, must-revalidate Expires: Fri, 30 Oct 1998 14:19:41 GMT Last-Modified: Mon, 29 Jun 1998 02:28:12 GMT ETag: "3e86-410-3596fbbc" Content-Length: 1040 Content-Type: text/html
头信息空一行后是HTML代码的输出。
HTTP头信息控制缓存是经过Expires(强缓存)、Cache-control(强缓存)、Last-Modified/If-Modified-Since(协商缓存)、Etag/If-None-Match(协商缓存)实现,下面详细介绍。
1)Expires是http1.0提出的一个表示资源过时时间的header,它描述的是一个绝对时间,由服务器返回,用GMT格式的字符串表示,如:Expires:Thu, 31 Dec 2016 23:55:55 GMT,读取缓存数据条件:缓存过时时间(服务器的)< 当前时间(客户端的)。
尽管Expires头颇有用,但它有必定的局限性。首先,由于牵扯到时间,Web服务器端的时钟必须和缓存的同步,不然极可能实现不了预期的结果——缓存把前女朋友当初现女朋友,把现女朋友看成过去式——那就悲剧了。另一个问题是,你很容易忘记给某内容设置了一个特定时间,若是返回内容的时候没有更新这个过时时间,则每一个请求都是上访到服务器,反而增长了负载和响应时间。
缺点:Expires是较老的强缓存管理header,因为它是服务器返回的一个绝对时间,这样存在一个问题,若是客户端的时间与服务器的时间相差很大(好比时钟不一样步,或者跨时区),那么偏差就很大,因此在HTTP 1.1版开始,使用Cache-Control: max-age=秒替代。
2)Cache-Control(缓存控制)HTTP头信息,是HTTP 1.1引入了新的头信息,描述的是一个相对时间,在进行缓存命中的时候,都是利用客户端时间进行判断,因此相比较Expires,Cache-Control的缓存管理更有效,安全一些。读取缓存数据条件:上次缓存时间(客户端的)+max-age < 当前时间(客户端的)。Cache-Control值能够是public、private、no-cache、no- store、no-transform、must-revalidate、proxy-revalidate、max-age
各个消息中的指令含义以下:
注意:这两个header能够只启用一个,也能够同时启用,当response header中,Expires和Cache-Control同时存在时,Cache-Control优先级高于Expires。
3)Last-Modified/If-Modified-Since:Last-Modified/If-Modified-Since要配合Cache-Control使用。
Last-Modified:标示这个响应资源的最后修改时间。web服务器在响应请求时,告诉浏览器资源的最后修改时间。
If-Modified-Since:当资源过时时(强缓存失效),发现资源具备Last-Modified声明,则再次向web服务器请求时带上头 If-Modified-Since,表示请求时间。web服务器收到请求后发现有头If-Modified-Since 则与被请求资源的最后修改时间进行比对。若最后修改时间较新,说明资源又被改动过,则响应整片资源内容(写在响应消息包体内),HTTP 200;若最后修改时间较旧,说明资源无新修改,则响应HTTP 304 (无需包体,节省浏览),告知浏览器继续使用所保存的cache。
缺点:Last-Modified标注的最后修改只能精确到秒级,若是某些文件在1秒钟之内,被修改屡次的话,它将不能准确标注文件的修改时间(没法及时更新文件)
若是某些文件会被按期生成,当有时内容并无任何变化,但Last-Modified却改变了,致使文件无法使用缓存,有可能存在服务器没有准确获取文件修改时间,或者与代理服务器时间不一致等情形(没法使用缓存)。
HTTP1.1中Etag解决了上述问题。
4)Etag/If-None-Match:Etag/If-None-Match也要配合Cache-Control使用。
Etag:web服务器响应请求时,告诉浏览器当前资源在服务器的惟一标识(生成规则由服务器决定)。Apache中,ETag的值,默认是对文件的索引节(INode),大小(Size)和最后修改时间(MTime)进行Hash后获得的。
If-None-Match:当资源过时时(使用Cache-Control标识的max-age),发现资源具备Etage声明,则再次向web服务器请求时带上头If-None-Match (Etag的值)。web服务器收到请求后发现有头If-None-Match 则与被请求资源的相应校验串进行比对,决定返回200或304。
Etag是服务器自动生成或者由开发者生成的对应资源在服务器端的惟一标识符,可以更加准确的控制缓存。Last-Modified与ETag一块儿使用时,服务器会优先验证ETag。
yahoo的Yslow法则中则提示谨慎设置Etag:须要注意的是分布式系统里多台机器间文件的last-modified必须保持一致,以避免负载均衡到不一样机器致使比对失败,Yahoo建议分布式系统尽可能关闭掉Etag(每台机器生成的etag都会不同,由于除了 last-modified、inode 也很难保持一致)。
咱们这几只讲应用层的缓存。在应用层的缓存因为应经有新的数据加入,数据的修改,数据的删除等等操做,而在某些时间,咱们须要这些操做及时的生效(因为用了缓存,可能会致使修改后缓存没有更新,而页面也没有变化),因此出现缓存的更新和过时的概念。
缓存的过时包含
缓存的更新
速度:固然,咱们使用缓存的目的之一就是要提升咱们应用的速度。若是使用缓存后速度更慢那就没有缓存的必要了。取缓存的速度应 当是很是快的,由于缓存的工做仅仅是取出一个曾经存储好的数据。因此影响缓存速度的因素可能跟缓存所才采用的存储方式有关系,还有可能印象速度的就是分布 式缓存的网络消耗,一样,缓存服务器在并发很大的时候也有可能不堪重负出现瓶颈,变得缓慢。
好比目前凤凰论坛使用的帖子缓存的响应时间在亚毫秒级,也就是还不足1ms的响应时间,这个速度是至关快的。
及时性:咱们使用缓存的重要一点就是对咱们的数据的更新须要缓存也及时的更新。这点很是重要,关系到页面显示的正确性,用户体验等。
命中率:命中率直接关系到缓存所起到的做用的大小。若是命中率过低就至关于没有使用缓存,或者咱们的缓存的规则有问题,重视命中不到缓存。
哪些地方须要缓存
选择什么缓存
缓存如此有用,那么这么多的缓存产品,咱们如何选择呢?下面咱们主要就经常使用的php方面来讲。
其实这里也可使用共享的磁盘缓存,可是基于咱们目前所处的环境和对于可靠性,高并发的要求,咱们不建议或者说不考虑使用共享磁盘做为缓存。
一、全页面静态化缓存
也就是将页面所有生成html静态页面,用户访问时直接访问的静态页面,而不会去走php服务器解析的流程。此种方式,在CMS系统中比较常见,好比dedecms;
二、页面部分缓存
该种方式,是将一个页面中不常常变的部分进行静态缓存,而常常变化的块不缓存,最后组装在一块儿显示;可使用相似于ob_get_contents的方式实现,也能够利用相似ESI之类的页面片断缓存策略,使其用来作动态页面中相对静态的片断部分的缓存(ESI技术,请baidu,此处不详讲)。该种方式能够用于如商城中的商品页。
三、数据缓存
顾名思义,就是缓存数据的一种方式;好比,商城中的某个商品信息,当用商品id去请求时,就会得出包括店铺信息、商品信息等数据,此时就能够将这些数据缓存到一个php文件中,文件名包含商品id来建一个惟一标示;下一次有人想查看这个商品时,首先就直接调这个文件里面的信息,而不用再去数据库查询;其实缓存文件中缓存的就是一个php数组之类。Ecmall商城系统里面就用了这种方式。
四、查询缓存
其实这跟数据缓存是一个思路,就是根据查询语句来缓存;将查询获得的数据缓存在一个文件中,下次遇到相同的查询时,就直接先从这个文件里面调数据,不会再去查数据库;但此处的缓存文件名可能就须要以查询语句为基点来创建惟一标示;
按时间变动进行缓存:其实,这一条不是真正的缓存方式;上面的二、三、4的缓存技术通常都用到了时间变动判断;就是对于缓存文件您须要设一个有效时间,在这个有效时间内,相同的访问才会先取缓存文件的内容,可是超过设定的缓存时间,就须要从新从数据库中获取数据,并生产最新的缓存文件;好比,我将咱们商城的首页就是设置2个小时更新一次。
五、按内容变动进行缓存
这个也并不是独立的缓存技术,需结合着用;就是当数据库内容被修改时,即刻更新缓存文件。好比,一我的流量很大的商城,商品不少,商品表必然比较大,这表的压力也比较重;咱们就能够对商品显示页进行页面缓存;当商家在后台修改这个商品的信息时,点击保存,咱们同时就更新缓存文件;那么,买家访问这个商品信息时,实际上访问的是一个静态页面,而不须要再去访问数据库。
试想,若是对商品页不缓存,那么每次访问一个商品就要去数据库查一次,若是有10万人在线浏览商品,那服务器压力就大了;
六、内存式缓存
提到这个,可能你们想到的首先就是Memcached;memcached是高性能的分布式内存缓存服务器。 通常的使用目的是,经过缓存数据库查询结果,减小数据库访问次数,以提升动态Web应用的速度、 提升可扩展性。它就是将须要缓存的信息,缓存到系统内存中,须要获取信息时,直接到内存中取;比较经常使用的方式就是 key–>value方式。
七、apache缓存模块
apache安装完之后,是不容许被cache的。若是外接了cache或squid服务器要求进行web加速的话,就须要在htttpd.conf里进行设置,固然前提是在安装apache的时候要激活mod_cache的模块。
安装apache时:./configure –enable-cache –enable-disk-cache –enable-mem-cache
八、php APC缓存扩展
Php有一个APC缓存扩展,windows下面为php_apc.dll,须要先加载这个模块,而后是在php.ini里面进行配置:
[apc] extension=php_apc.dll apc.rfc1867 = on upload_max_filesize = 100M post_max_size = 100M apc.max_file_size = 200M upload_max_filesize = 1000M post_max_size = 1000M max_execution_time = 600 ; 每一个PHP页面运行的最大时间值(秒),默认30秒 max_input_time = 600 ; 每一个PHP页面接收数据所需的最大时间,默认60 memory_limit = 128M ; 每一个PHP页面所吃掉的最大内存,默认8M
九、Opcode缓存
PHP的缓冲器、加速器,有eaccelerator, apc, phpa,xcache。
首先php代码被解析为Tokens,而后再编译为Opcode码,最后执行Opcode码,返回结果;因此,对于相同的php文件,第一次运行时能够缓存其Opcode码,下次再执行这个页面时,直接会去找到缓存下的opcode码,直接执行最后一步,而再也不须要中间的步骤了。比较知名的是XCache、Turck MM Cache、PHP Accelerator等。
http://www.cnblogs.com/sunli/archive/2009/11/24/1609444.html
https://segmentfault.com/a/1190000006741200
https://my.oschina.net/leejun2005/blog/369148
http://www.oschina.net/news/41397/web-cache-knowledge
http://www.open-open.com/lib/view/open1479181086120.html
http://www.jb51.net/article/49714.htm
http://www.php100.com/html/php/lei/2015/0919/8969.html
版权声明:本文采用署名-非商业性使用-相同方式共享(CC BY-NC-SA 3.0 CN)国际许可协议进行许可,转载请注明做者及出处。 |