架构高性能站点秘笈(二)——动态内容缓存

什么是动态内容缓存?

浏览器向server发送请求后,server会依据浏览器的要求做对应的处理(如:数据库操作)。然后将处理后的结果注入JSP页面生成HTML,最后将生成的HTML返回给浏览器显示。

我们知道,数据库读取操作是非常耗时的,假设能将每次请求中的数据库处理时间去掉,那server的对应速度将会大幅提升。要实现这一点。我们就须要将经常使用的HTML页面事先生成好,当用户发出请求时,server仅仅需从缓存中取出就可以。无需再做数据库处理操作。

综上所述:事先生成HTML页面的技术称为动态内容缓存。


什么是“缓存命中率”?

缓存命中率 = 訪问缓存的请求数/请求总数

缓存命中率是衡量缓存是否有效的重要指标。假设将全部须要訪问的数据均缓存起来,那么缓存命中率是100%。

但一半情况下。为了节约存储空间。仅仅将訪问频率较高的数据缓存起来。那么这样就会造成有一些请求能够通过缓存訪问数据。而有一些请求须要查询数据库訪问数据。

我们没有办法确保缓存的命中率100%,但我们须要使用一些算法确保缓冲命中率较高。也仅仅有当缓冲命中率较高的情况下,缓冲才干发挥它真正的价值。

PS:缓存与缓冲的差别?

这里顺便提一下“缓存”和“缓冲”的差别。

  • 缓冲:缓冲是一块暂时的存储空间,为了解决不同存储设备之间读写速率不匹配而产生的。


    比方:内存的读写速度远远大于硬盘的读写速度。

    当内存中的数据向硬盘中写入时,内存会先将数据写入内存缓冲区,再由内存缓冲区向硬盘写入数据。这样内存高速腾空之后就能够做其它事了,提高了效率。

  • 缓存:缓存是在一些为了避免反复计算,而被暂时性存储的数据。

综上所述:缓冲=缓冲区。它是指内存中的一片区域;而缓存指的是数据,一些味了避免反复计算而被暂时性存储的数据。

它们都是为了提高处理效率而存在的,都採用了“牺牲空间换取时间”的思想。


缓存的三种存储方式

缓存能够存储在三种不同的地方:

  1. 存储在内存
  2. 存储在IO设备
  3. 存储在内存和IO设备上
  4. 存储在缓存server上

对于小型站点,缓存首选的存储位置就是内存。内存相对于IO设备有较快的訪问速度,能大大缩短缓存的读取时间。

但内存资源比較宝贵,假设没钱买大内存的server的话,那就仅仅好考虑另外一种办法,将缓存存在IO设备中。

对于一些小型站点。假设须要存储的缓存数据量比較大,并且买不起大内存的server的话,那存储在IO设备是不错的选择。但IO设备相对于内存来说有个致命的缺陷。那就是慢!

因此,对于资金不充裕的小型站点来说,第三种方式最为合适。

假设既想获得内存的读写速度。又想拥有IO设备的巨大存储空间,那就能够选择两者结合的方式。


内存中开辟一块固定大小的缓冲区,用于存储使用频率较高的缓存数据,而将使用频率较低的缓存数据存储至IO设备。

当缓冲区存满时。你须要使用LRU算法将近期最旧未使用的缓存从缓冲区中扔出去,而将近期一段时间IO设备中訪问频率最高的缓存放进来。从而保证了当前缓冲区中数据的命中可能性是最大的。

最后,对于大型站点来说。能够使用专门的缓存server来存储缓存。这主要有两点优点:

  1. 节约server的内存资源,让server的内存作很多其它数据处理的工作,而把数据存储的工作交给缓存server;
  2. 缓存server具有更好的可扩展性。假设站点须要定期举办一些营销活动,为了应付急剧添加的并发量,缓存server是不二之选。

可是。因为Webserver与缓存server採用TCP通信,而建立和释放TCP连接时间开销比較大。因此对于小型站点来说。直接将缓存存在内存无疑是种首选办法。

怎样实现缓存?

这里就简单地介绍下基于内存的缓存机制,近期我会单独写一篇“基于内存+IO+LRU算法的缓存机制”的博客。敬请关注。

server在接收client发来的请求后,首先依据请求的URL推断内存中是否有对应的缓存;若有的话先推断该缓存是否过期。若没过期就直接返回缓存数据。若过期了。或者内存中根本就没有该请求的缓存的话。就调用业务逻辑层的相关函数,处理client发来的请求。生成client须要的数据。然后给生成的数据设置一个有效期。并存入缓存,供下次使用,最后将数据返回给用户。

静态化页面

之前我们介绍的缓存机制仍然须要server程序去推断存储空间中是否有缓存。而server程序推断的过程也须要时间,假设缓存非常多的话,server程序须要找半天。那么我们是否能把静态页面事先都生成好,让浏览器直接訪问静态页面,而无需再通过server程序訪问缓存。

要知道。浏览器直接訪问静态页面的速度比通过server程序訪问静态页面的速度要快非常多非常多非常多!

要实现这种想法,我们能够这么做:

  1. server程序启动的时候将生成全部须要訪问的HTML页面,存储至server外设中;
  2. 浏览器全部a标签中的href都填写这些静态HTML页面URL;
  3. 在server中开启一条定时线程,每隔一段时间检查动态数据发生改动的HTML页面,并生成新的HTML页面;
  4. 当数据库发生改动时。马上更新与该数据相关的HTML页面。
posted on 2017-07-28 10:49  ljbguanli  阅读(272)  评论(0)    收藏  举报