Chinaunix首页 | 论坛 | 博客
  • 博客访问: 141790
  • 博文数量: 7
  • 博客积分: 67
  • 博客等级: 民兵
  • 技术积分: 184
  • 用 户 组: 普通用户
  • 注册时间: 2010-12-04 05:16
文章分类

全部博文(7)

文章存档

2013年(7)

我的朋友

分类: LINUX

2013-01-23 18:52:59

全球中文首发,史上最全面Squid refresh_pattern详解

 

小斯教你玩squid第三弹。

前两弹都是代码相关的,是别人没写过的。今天要说的话题是refresh_pattern,是网上有很多人写过了的。比如这个

refresh_pattern 的算法如下:(当前时间定义为CURRENT_DATE)
1) If ((CURRENT_DATE-DATE(
就是LM里定义的时间)) < min)cache是新鲜的
2) else if ((CURRENT_DATE-DATE) < (min + (max-min)*percent)
cache是新鲜的
3) else cache
是过期的

这个

·        如果有定义refresh_pattern:只要满足以下两个条件之一,缓冲对象过期

·        缓冲对象在squidcache缓冲的时间大于refresh_pattern定义的max

·        缓冲对象在squidcache缓冲的时间大于(原始数据进入squid的缓冲的时间-原始web数据所规定的Last-Modified时间)*percent

·        如果符合多个refresh_pattern定义,以第一条符合定义的refresh_pattern为准

·        如果没有符合定义的refresh_pattern,则按squid的默认处理规则

 

还有这个

FRESH if (CURRENT_DATE DATE) < min

FRESH if (CURRENT_DATE DATE)/(DATE LM_DATE) < percent

STABLE if (CURRENT_DATE DATE) > max

OTHER, STABLE

 

等等。

 

其中有一些是相互矛盾的,有一些没把refresh_pattern的全部选项说清楚,还有refresh_patternmiss时所起的作用很少有人说。

今天我就对照着代码,把refresh_pattern的所有作用,以及squid的过期校验机制全都讲一遍。

1. 先说说refresh_pattern最主要的作用,过期校验。

Squid的过期校验是访问驱动的,如果一个object过期了,却又一直没人访问,那么squid会一直把这个object扔在那里,而不会主动地回源校验它。只有当客户端访问到了这个object的时候,squid才会校验。这样做的原因也不难理解,如果一个object总是不被访问到,就没有必要为了校验它浪费宝贵的cpu和回源带宽资源,等到有人访问它时再校验也不迟。

回源校验的流程发起在

clientProcessRequest

->storeClientCopy

->clientCacheHit

->refreshCheckHTTPStale(const StoreEntry * entry, request_t * request)

         -> refreshCheck (const StoreEntry * entry, request_t * request, time_t delta)

 

 

clientCacheHit往上,都是squid处理客户端请求的代码。从refreshCheckHTTPStale往下,就都是squid专门用来检查过期的函数了。简单地说,就是把请求扔进refreshCheckHTTPStale,然后结果返回给clientCacheHit,然后根据结果来决定是继续HIT还是转到过期流程。

refreshCheckHTTPStale的返回值很有意思,有这么几种:

-1-2013

0是最普遍的,表示未过期。

-1表示stale_hit,也就是过期程度在配置文件的refresh_stale_hit选项规定的范围内,这种情况也算命中。

-2表示stale-while-revalidate生效了。这是squid先给出旧内容到客户端,然后异步地回源校验,校验完成前都会给旧内容

1 表示普通的过期

3表示这个object的过期程度已经大于配置文件中的max_stale所规定的范围,必须回源校验了。这里,返回值13的处理方式是一样的。

 

refreshCheckHTTPStalerefreshCheck共同作用,得到上述的几种返回值。首先,通过refresh_pattern或者原站replyDate头,Expires头和Cache-Control头得到一个staleness,这个staleness代表这个object的过期程度,然后再经过一系列计算,最终得到我们需要的返回值。

这里要先介绍一下refresh_pattern的配置方法:

 

refresh_pattern [-i] regex min percent max [options]

-i表示正则匹配时不区分大小写

regex是与url进行匹配的正则表达式

minpercent,max 3个数字,后面会介绍到用处

optionsrefresh_pattern的其他选项,包括以下几种

override-expire

override-lastmod

reload-into-ims

ignore-reload

ignore-no-cache

ignore-private

ignore-auth

stale-while-revalidate=NN

ignore-stale-while-revalidate

max-stale=NN

negative-ttl=NN

作用会在后面介绍

 

在所有的refresh_pattern中,从上往下数,第一个与当前请求url匹配的就会作用于过期判断过程。后面称为“匹配的refresh_pattern

 

 

首先是得到staleness的过程

上面的图看起来有点复杂其实就是,staleness=-1的,表示未过期,其他都是过期了。

然后用这个staleness,加上refresh_pattern中的各种参数,最终得出refreshCheckHTTPStale的结果

上面这个图,就是网上流传甚广的refresh_pattern的说明,其实过期的判断在后面还有很多步骤。但所谓的“refresh_pattern各种参数”并不是非常常见,所以只想了解min,percent,max的人看到这里就可以结束了。

============================割了割了=========================

 

接下来这张图,是refresh_pattern的其他选项与staleness共同作用,对过期判断的影响

 

 

2. 可缓存与否的判断

refresh_pattern在过期判断时的作用已经说完了。接下来说说在miss的时候refresh_pattern起到的作用。

Miss的时候,一个objectheader部分被squid得到之后,是要判断一下,这个object在过期校验层面上,是否适合被缓存。如果不适合,将直接不缓存这个object

判断的过程在

 

httpCachableReply

->refreshIsCachable

    ->refreshCheck

 

refreshIsCachable会返回0或者11表示这个object在过期校验的层面上是可以被缓存的(当然,还需要其他层面也可以缓存才会真正存下来)。而它的核心功能仍然是refreshCheck,只是这次调用refreshCheck的时候,先假定一个delta秒之后的时间为当前时间,再进行refreshCheck的过程(求staleness,然后用refresh_pattern进行修正。参见上面画的2张流程图)。这个delta的取值,正是配置文件中的minimum_expiry_time这个配置项(未配置的情况下默认为60秒),这个选项的意思是,过期时间必须大于多少秒方可缓存。假如minimum_expiry_time=60,并且(原站给出的Expires头是在50秒后,或者Cache-Control:max-age=50),那么这个object将被认为要在50秒后过期,小于不能被缓存。

 

假如refreshCheck的返回在minimum_expiry_time这段时间之后,object并不过期的话,refreshIsCachable还要检查一件事,就是这个object到底能否被校验。我们知道,要校验一个object主要有2种手段,If-Modified-SinceIf-None-Match,一个需要Last-Modified头,一个需要ETag头。这两个头如果都没有的话,object也是不能缓存的。

用流程图来描述,就是

 

3. 校验失败时能否给出旧内容的判断

以上两处,是refresh_pattern相对常用的功能,还有一处稍微冷僻的用处,就是检查当回源校验失败时,是否能将已经过期的object给出去。如果一次回源校验,原站给出了一个5xx的话,squid为了能让客户端继续拿到内容,可能会将磁盘上的旧内容发给客户端,但要有一定的条件,即检查object是否已经“严重过期”。这个判断在

clientHandleIMSReply

->clientGetsOldEntry

    ->refreshCheckStaleOK

        ->refreshCheck

如果通过检查refreshCheck,发现原站给出的reply里面没有要求Cache-Control:must-revalidate,并且没有走到让refreshCheckHTTPStale返回3的那两个分支的话(也就是过期时间在max-stale之内),就可以考虑继续给出旧内容。这里逻辑相对简单,就不画图了。

 

上面反复提到的一个过程就是“过期校验”,这个过程也挺复杂,我们会在后面的博客里继续说明。

阅读(8822) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~