缓存的优点:
- 缓存减少了冗余数据的传输
- 缓存减缓网络瓶颈的问题.
- 缓存降低了对原始服务器的要求,减少了过载的出现
- 缓存降低了距离时延
冗余的数据传输
有很多的客户端访问一个流行的原始服务器页面,服务器会出现多愁次的传输同一份文档的情况,这些相同的数据会一遍一遍的进行传输,这些冗余的簌簌会耗费昂贵的带宽,降低传输的速度,加重web服务器的负载,有了缓存,可以保留第一条服务器响应的副本,后继的请求利用缓存的副本进行应对,减少了冗余数据的传输。
带宽瓶颈
很的网络提供的本地网络客户端提供的带宽要比远程的服务器提供的带宽要宽,客户端会以上述路径上的最慢网速来访问服务器。如果客户端要从一个快速局域网的缓存中得到一个副本那么缓存就可以提高性能(在传输大的文件的时候更加明显)
瞬间拥塞
缓存在破坏瞬间拥塞时显得非常重要,在突发事件发生(鹿晗造成微博crash)使很多人同时访问web文档,就会发生瞬间的拥塞。由此造成的过多流量峰值可能使服务器发生灾难性的崩溃。
距离延时
有的时候造成延时的可能是因为距离,每一台网络路由器都会增加因特网流量的延时,及时客户端和服务器之间没有太多的路由器,光速自身也是有延时的。
命中与未命中
及时缓存有这么多的好处,但是缓存也无法保存世界上的每一个文档的副本。我们可以通过已经有的副本为某些到达缓存的请求提供服务,这就被称为缓存命中,到时对于某些到达缓存没有可用副本,从而将请求转发给原始服务器,被称为缓存未命中。
再验证
原始服务器的内容随时都可能发生变化,缓存要时不时的对齐进行检测,看看现在的副本是否是最新的副本,这些‘新鲜度检测’被称为HTTP再验证。从理论上,缓存可以任意时刻以任意的频率对副本进行再验证,但是由于缓存中存在成千上万的文档,而且带宽是很珍贵的,所以大部分的缓存只在客户端发送请求的时候,才会对副本进行验证。
缓存对缓存的副本进行再验证的时候,会向原始服务器发送一个小的再验证请求,如果内容没有发生改变,服务器会以一个小的304
进行响应,只要缓存知道缓存副本仍然有效,就会再次将副本表示为新鲜的,并将缓存的副本提供给客户端,这被叫做再验证命中,或缓慢命中,这个速度介于在服务器中获取对象和在缓存中获取对象的速度。
再验证未命中
如果服务器与已缓存副本不同,服务器就会向客户端发送一条普通的、带有完内容的HTTP200 OK响应。
对象被删除
如果服务器中的对象已经被删除,服务器就回送一个404Not Found,缓存也会将副本进行清除。
缓存的拓扑结构
缓存可以是单个用户专有的,也可以是多个用户共有的,专用缓存被称为私有缓存,共享的缓存被称为共有缓存。
缓存的处理步骤
接受:缓存从网络中读取抵达的请求报文
解析:缓存对报文进行解析,提取URL
和各种首部
查询:缓存查看是都有本地可用的副本,如果没有,就获取一个副本,并将它保存到本地
新鲜度检测:缓存检测本地的副本是否新鲜,如果不是,就访问服务器有任何改动
创建响应:缓存会用新的首部和已缓存的主题来构建一个响应报文。
发送:缓存通过网络将响应发挥给客户端。
日志:缓存可选的创建一个日志文件条目来描述这个事务。
文档过期
通过特殊的HTTP
的Cache-Control
首部和Expires
首部,HTTP
让原始服务器想每一个文档附加一个‘过期日期’。
在缓存日期过期之前,缓存可以任意以任意频率使用这些副本,而且无需和服务器联系,但是一旦文档过期了,缓存就必须要和服务器进行确认,询问文档是否被修改过,如果被修改过,就要获取一份新鲜(带有新的过期日期)的副本。
用条件方法进行再验证
在进行再验证的时候,可以附加条件进行高效的再验证,HTTP
允许缓存向原始服务器发送一个条件,请求服务器只在文档和缓存现有的副本不同的时候,才进行对象的回送。HTTP
定义了5个条件请求首部,其中我们最常用的是If-Modified-Since
和If-None-Match
。If-Modified-Since
条件为假的时候,服务器会向客户端发送一个304响应报文,为了提高性能,报文主体这些没有修改的内容不会再次被返回。一般只会返回一个新的过期时间。一般If-Modified-Since
和Last-Modified
首部进行配合使用。
If-None-Match
有一些情况,仅仅依靠最后修改时间是不够的
a.有些文档是进行周期性的写入,尽管修改日期一直在变,但是文档的内容没有发生任何的改变。
b.有些文档被修改了,但是修改的内容并不重要不需要让世界的缓存(比如说修改了注释)
c.有些服务器没有办法确定最后修改的日期
d.有些服务器提供的文档会在亚秒间隙发生改变,对这些服务器,使用s作为修改日期是远远不够的。
为了解决这些问题,HTTP
允许用户引入称为实体标签(ETag
)的版本标识符进行比较,这个标签可以包含文档的序列号或是版本号,或者文档内容的教研或是其他的指纹信息。
控制缓存的能力
Cache-Control
的no-Store
和no-Cache
首部可以防止缓存提供未经证实的已缓存对象,no-Store
的响应会禁止缓存对响应进行复制,缓存通常会像非缓存代理服务器一样,向客户端转发一条no-Store
响应,然后删除对象、标识为no-Cache
响应实际上是可以存储在本地缓存区内的。知识在与原始服务器进行新鲜度验证之前,缓存不能将其提供给客户端使用,这个首部可以怎么写‘donot-server-from-cache-width-revalidation’,HTTP/1.1
提供的pragma:no-cache
首部是为了兼容来进行设计的。
Cache-Control:no-store
:请求和响应的信息都不应该被存储在对方的磁盘系统中
Cache-Control:no-cache
:浏览器和缓存服务器都不应该缓存页面信息;
Cache-Control:max-age
:表示服务器将文档传来知识,可以保持新鲜的时间是多久。
Cache-Control:s-maxage
:和max-age
差不多,但是仅仅使用与共有缓存
Expires:<date>
响应首部:并不推荐使用,指的是实际过去的时间,但是由于很多的服务器的时钟都不同步,多以并不推荐使用。
must-revalidate
响应首部:可以配置缓存,使其听过一些陈旧的对象,用来提高性能。如果以原始服务器希望缓存可以严格的遵守过期时间,可以在原始响应中添加Cache-Control:must-revalidate
,这个首部告诉缓存,在之前没有和原始服务器进行验证的情况下,不可以提供这个对象的陈旧版本。,如果在缓存尽心must-revalidate
进行新鲜度检测的时候,原始服务器不可用,缓存必须返回一条504Gateway Timeout错误。
试探性过期--采用LM-Factor算法进行试探性过期,意义不大,这里不详细阐述。
客户端进行新鲜度限制
web
浏览器都有refresh
和reload
按钮,可以强制对浏览器或是代理缓存中可能过期的内容进行刷新。refresh
这个按钮会发布一个附加Cache-Control
请求首部的GET
请求,这个请求会强制的进行再验证,或是无条件的从服务器获取文档。
客户端可以通过Cache-Control
的指令来强化活是放松对过期时间的限制。