WEB缓存深入介绍
缓存
出自PHP Group
【说明:拷贝自我写在公司wiki上的一篇关于缓存的文章,其中有些内容没有详细介绍,只列了提纲,部分连接链接到了公司的wiki上,可能外网用户无法打开。但是基本上介绍了常用的缓存模式,希望对你有帮助。】
目录[隐藏]
|
摘要
本文介绍了缓存的概念和在web开发中缓存的作用,以及如何使用缓存。并用凤凰网的互动产品作为实例来分析。
缓存和缓存的作用
什么是缓存?
缓存就是用来避免频繁的到主存储器(一般来说可能是数据库,结构化的磁盘文件,远程网络接口,程序接口等等提供数据返回的)获取数据而建立的一个存 取更快的临时存储器(缓存)。一般来说,缓存比主存储器更小(不一定,也可能是存储的数据结构不一样,但是存取速度非常快),但是存储的容量也比较小,但 是存取速度非常快。
缓存的作用
缓存一般用来
- .存储频繁访问的数据
- .临时存储耗时的计算结果
- .内存缓存减少磁盘IO
缓存类型
在WEB开发中,缓存可以分为:
数据库端缓存
- 这个可以用以“空间换时间”来说。比如建一个表来存储另外一个表某个类型的数据的总条数,在每次更新数据的时候同事更新 数据表和统计条数的表。在需要获取某个类型的数据的条数的时候,就不需要select count去查询,直接查询统计表就可以了,这样可以提高查询的速度和数据库的性能。
应用层缓存
- 应用层缓存这块跟开发人员关系最大,也是平时经常接触的。
- .缓存数据库的查询结果,减少数据的压力。这个在大型网站是必须做的。
- .缓存磁盘文件的数据。比如常用的数据可以放到内存,不用每次都去读取磁盘,特别是密集计算的程序,比如中文分词的词库。
- .缓存某个耗时的计算操作,比如数据统计。
- 应用层缓存的架构也可以分几种:
- .嵌入式,也就是缓存和应用在同一个机器。比如单机的文件缓存,java中用hashMap来缓存数据等等。这种缓存速度快,没有网络消耗。
- .分布式缓存,把缓存的数据独立到不同的机器,通过网络来请求数据,比如常用的memcache就是这一类。
- 分布式缓存一般可以分为几种:
- .按应用切分数据到不同的缓存服务器,这是一种比较简单和实用的方式。
- .按照某种规则(hash,路由等等)把数据存储到不同的缓存服务器
- .代理模式,应用在获取数据的时候都由代理透明的处理,缓存机制有代理服务器来处理
前端缓存
我们这里说的前端缓存可以理解为一般使用的cdn技术,利用squid等做前端缓冲技术,主要还是针对静态文件类型,比如图片,css,js,html等静态文件。
客户端缓存
浏览器端的缓存,可以让用户请求一次之后,下一次不在从服务器端请求数据,直接从本地缓存读取,可以减轻服务器负担也可以加快用户的访问速度。
缓存的更新和过期
我们这几只讲应用层的缓存。在应用层的缓存由于应经有新的数据加入,数据的修改,数据的删除等等操作,而在某些时间,我们需要这些操作及时的生效(由于用了缓存,可能会导致修改后缓存没有更新,而页面也没有变化),所以出现缓存的更新和过期的概念。
缓存的过期
- 缓存的过期包含
- .时间过期
- 缓存的过期包含
我们在缓存数据的时候我们可以指定数据缓存的最大时间,如果超过这个时间,我们就认为缓存是失效的。
- .基于规则的过期
我们在缓存中存储了某些数据来标明数据的版本。比如存取的时间,更新的时间,数据的版本信息等等。
然后比较这些信息是否有变化来判断是否过期。
缓存的更新
- .被动
- 当缓存失效的时候我们的应用程序重新从主存储器中取数据,然后重新放回缓存中。
- .主动
- 当数据一更新的时候,我们的应用主动的去更新我们的缓存内容。
- .被动和主动结合(基于版本)
- 当数据以更新的时候,我们更新一个数据被更新的标志。然后根据上面讲到的“基于规则的过期”来更新数据。
缓存工具介绍
数据库端
- 普通表,利用普通表来缓存一些统计数据。
- 内存表
应用层端
比较常见的应用层分布式缓存容器,Memcache、共享文件服务器、MemcacheDb、Tokyo Tyrant。 php里面也有比如x-cache,apc等的基于进程的缓存,这种缓存比分布式缓存速度快,但是限于跟应用的一个机器。 java实现的缓存也比较多,比如oscache,jcache ,ehcached等等。
前端
- 前端比较常用的就是squid,Varnish Cache,ncache等等。
Varnish是一款高性能的开源HTTP加速器,挪威最大的在线报纸 Verdens Gang (vg.no) 使用3台Varnish代替了原来的12台squid,性能比以前更好。
客户端
- 客户端缓存依赖于浏览器的实现,目前一般的浏览器都实现了基于http都信息来缓存相应的文件。
如何评价缓存的好坏
速度
- 当然,我们使用缓存的目的之一就是要提高我们应用的速度。如果使用缓存后速度更慢那就没有缓存的必要了。取缓存的速度应 当是非常快的,因为缓存的工作仅仅是取出一个曾经存储好的数据。所以影响缓存速度的因素可能跟缓存所才采用的存储方式有关系,还有可能印象速度的就是分布 式缓存的网络消耗,同样,缓存服务器在并发很大的时候也有可能不堪重负出现瓶颈,变得缓慢。
比如目前凤凰论坛使用的帖子缓存的响应时间在亚毫秒级,也就是还不足1ms的响应时间,这个速度是相当快的。
及时性
- 我们使用缓存的重要一点就是对我们的数据的更新需要缓存也及时的更新。这点非常重要,关系到页面显示的正确性,用户体验等。
命中率
- 命中率直接关系到缓存所起到的作用的大小。如果命中率太低就相当于没有使用缓存,或者我们的缓存的规则有问题,重视命中不到缓存。
如何有效的使用缓存
哪些地方需要缓存
- .页面的打开速度非常慢,每一次都要进行大量的计算,从数据库取一个比较耗时操作的数据。
- .频繁的读取操作,每次请求都要从数据库读取数据,而这些数据的更新并不是很频繁,导致数据库的压力非常大。
- .频繁的写入操作(需要写到数据库),比如页面点击量,投票数的操作。这些操作可以暂时利用缓存,然后定期的写到数据库。
选择什么缓存
- 缓存如此有用,那么这么多的缓存产品,我们如何选择呢?下面我们主要就常用的php方面来说。
- .访问量不是特别大,web前端机器只有一台,对数据库端的内容缓存可以使用文件缓存,这种方式非常简单也比较有效,不需要对服务器做特别的配置。
- 也可以使用apc,x-cached等提供的内存缓存,也非常有效,它比磁盘缓存速度快,但是因为是内存缓存,所以缓存的容量有限。
- .访问量比较大,web前端机器一般超过一台甚至更多,我们一般采用分布式的缓存。我们一般选择memcache作为我们的缓存,memcache是一个基于内存的分布式缓存,它的速度和效率非常高。
- 其实这里也可以使用共享的磁盘缓存,但是基于我们目前所处的环境和对于可靠性,高并发的要求,我们不建议或者说不考虑使用共享磁盘作为缓存。
- 缓存如此有用,那么这么多的缓存产品,我们如何选择呢?下面我们主要就常用的php方面来说。
使用缓存
Memcached
memcache的使用
memcache的分布式缓存
memcached的Replication
- repcached 是一组给 memcached 1.2.x 添加数据复制功能的 patch.主要目的是建立一个冗余的memcached系统, 当然, 还有 Fail over(失败转移).支持所有的memcached命令. 当master挂掉的时候,slave会顶上来.连接时能够完整复制数据.
memcached的监控
memcached的遍历
Tokyo Tyrant
Tokyo Tyrant的使用
Tokyo Tyrant的Replication
Tokyo Tyrant的状态
Tokyo Tyrant的管理
缓存的存储
Berkeley DB
CDB
CDB非常快,但是不可更新。php已经支持。
常见问题(FAQ)
如何更新前端缓存
- 前端缓存在应用层的上方,对应用来讲,一般是不可见的。比如squid控制的缓存。由此,就会出现一个问题。比如我们网站的首页,里面有 很多的css,js文件,这些 css,js文件都可以被缓存在squid中,比如我们缓存30天,这些文件很可能30天都不会更新一次,但是,当我们需要更新某个css,js文件时怎 么办?