《HTTP权威指南》缓存控制-缓存新鲜度算法

1、使用期和新鲜生存期

  为了分辨已缓存文档是否足够新鲜,缓存只需要计算两个值:已缓存副本的使用期(age)和已缓存副本的新鲜生存期(freshness lifetime)。如果已缓存副本的时长小于新鲜生存期,就说明副本足够新鲜,可以使用。用Perl表示为:

$is_refresh_enough=($age<$freshness_lifetime);

  文档的使用期是自从服务器将其发送出来(或者最后一次被服务器再验证)之后“老去”的总时间。缓存可能不知道文档响应是来自上游缓存,还是来自服务器,所以它不能假设文档是最新的。它必须根据显示的Age首部(优先),或者通过对服务器生成的Date首部的处理,来确定文档的使用期。
  文档的新鲜生存期表明,已缓存副本在经过多长时间之后,就会因为新鲜度不足而无法再向客户端提供来。新鲜生存期考虑了文档的过期日期,以及客户端可能请求的任何新鲜度覆盖范围。
  有些客户端可能愿意接受稍微有些过期的文档(使用Cache-Control:max-stale首部)。有些客户端可能无法接受会在近期过期的文档(使用Cache-Control:min-fresh首部)。缓存将服务器过期信息与客户端的新鲜度要求结合在一起,已确定最大的新鲜生存期。

2、使用期的计算

  响应的使用期就是服务器发布响应(或服务器对其在验证)之后经过的总时间。使用期包含了在因特网路由器和网关中游荡的时间,在中间节点缓存中存储的时间,以及响应在你的缓存中停留的时间。
  Http使用期计算的细节有点棘手,但其基本概念很简单。响应到达缓存时,缓存可以通过查看Date首部或Age首部来进行判断响应已使用的时间。缓存还能记录下文档在本地缓存中停留的时间。把这些都加起来,就是响应的总使用期。Http用一些魔法对时钟偏差和网络延时进行来补偿,但基本计算非常简单:

$age=$age_when_document_arrived_at_our_cache+$how_long_copy_has_been_in_out_cache

  缓存可以很方便地判断出缓存副本已经在本地缓存来多长时间(这就是简单的笔记问题),但是很难确定响应抵达缓存时的使用期,因为不是所有的服务器的时钟都是同步的,而且我们也不知道响应到过那里。完善的使用期计算算法会试着对此进行补偿。

2.1 表面使用期是基于Date首部的

  如果所有的计算机都是共享同样的、完全精确的时钟、已缓存文档的使用期就是文档的“表面使用期”--当前时间减去服务器发送文档的时间。服务器发送时间就是Date首部的值。最简单的起始时间计算可以直接使用表面时间:

$apparent_age=$time_got_response-$Date_header_value;
$age_when_document_arrived_at_our_cache=$apparent_age;

但并不是所有的时钟都实现来良好的同步。客户端和服务器时钟之间可能有数分钟的差别,如果时钟没有设置好的话,甚至会有数小时或者数天的区别。
  Web应用程序,尤其是缓存代理,要做好与时间值有很大差异的服务器进行交互的准备。这种问题称为时钟偏差(clock skew)--两台计算机时钟设置的不同。由于时钟偏差的存在,表面使用期有时不太准确,而且有时会是负的。
  如果使用期是负的,就将其设置为0.我们还可以对表面使用期进行完整性检查,一确定它没有大的令人不可思议,不过,实际上,表面使用期可能没有错。我们可能在与一个将文档缓存来很久的父缓存对话(缓存可能还存储来原始的Date首部)。

$apparent_age=max(0,$time_got_response-$Date_header_value);
$age_when_document_arrived_at_out_cache=$apparent_age;

要明确Date首部描述的是原始服务器的日期。代理和缓存一定不能修改这个日期!

2.2 逐跳使用期的计算

  这样就可以去除时钟偏差造成的负数使用期来,但对时钟偏差给精确性带来的整体偏差,我们能做的工作很少。文档经过代理和缓存时,Http/1.1会让每台设备都将相对使用期累加到Age首部中,一次来解决缺乏通过同步时钟的问题。这种方式并不需要进行跨服务器的、端到端的时钟对比。
  文档经过代理时,Age首部值会随之增加。使用Http/1.1的应用程序就应该在Age首部值中加上文档在每个应用程序和网络传输过程中停留时间。每个中间应用程序都可以很容易地使用本地时钟计算出文档的停留时间。
  但响应链中所有的非Http/1.1设备都无法识别Age首部,它们会将首部未经修改地转发出去,或者将其删除掉。因此,在Htt/1.1得到普遍应用之前,Age首部都将是低估了相对使用期。
  除了基于Date计算出来的Age之前,还使用了相对Age值,而且不论是跨服务器的Date值,还是计算出来的Age值都可能被低估,所以会选择使用估计出的两个Age值中最保守的那个(最保守的值就是最老的Age值)。使用这种方式,Http就能容忍Age首部存在的错误,尽管这样可能会搞错究竟哪边更加新鲜:

$apparent_age=max(0,$time_got_response-$Date_header_value);
$corrected_apparent_age=max($apparent_age,$Age_header_value);
$age_when_document_arrived_at_out_cache=$corrected_apparent_age;

2.3 对网络时延的补偿

  事务处理可能会很慢。这是使用缓存的主要原因。但对速度非常慢的网络,或者那些过载的服务器来说,如果文档在网络或服务器中阻塞来很长时间,相对使用期计算可能会极大地低估文档的使用期。
  Date首部说明文档是什么时候离开原始服务器的,但并没有说明文档在到缓存的传输过程中话费来多长时间。如果文档的传输经过来一长串的代理和父缓存,网络时延可能会相当大。
  没有说明简单的方法可以用来测量到缓存的单向网络时延,但往返时延则比较容易测量。缓存知道它请求文档的时间,以及文档抵达的时间。http/1.1会在这些网络时延上加上整个往返时延,以便对其进行保守地校正。这个从缓存到服务器再到缓存的时延高估来从服务器到缓存的时延,但它是保守的。如果出错来,它会使文档比实际使用期要老,并引发不必要的再验证。计算是这样进行的:

$apparent_age=max(0,$time_got_response-$Date_header_value);
$corrected_apparent_age=max($apparent_age,$Age_header_value);
$response_delay_estimate=($time_got_response-$time_issued_request);
$age_when_document_arrived_at_out_cache=$corrected_apparent_age+$response_delay_estimate;

3、完整的使用期计算算法

  上一节说明来当Http所承载的文档到达缓存时,如何计算其使用期。只要将这条响应存储到缓存中去,它就会进一步老化。当对缓存中文档的请求到达时,我们需要知道文档在缓存中停留来多长时间,只要才能计算文档的使用期:

$age=$age_when_document_arrived_at_out_cache+$how_long_copy_has_been_in_out_cache;
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,298评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,701评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,078评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,687评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,018评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,410评论 1 211
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,729评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,412评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,124评论 1 239
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,379评论 2 242
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,903评论 1 257
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,268评论 2 251
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,894评论 3 233
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,014评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,770评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,435评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,312评论 2 260