Chinaunix首页 | 论坛 | 博客
  • 博客访问: 151254
  • 博文数量: 53
  • 博客积分: 1776
  • 博客等级: 上尉
  • 技术积分: 545
  • 用 户 组: 普通用户
  • 注册时间: 2008-11-05 00:17
文章分类

全部博文(53)

文章存档

2016年(1)

2013年(2)

2012年(11)

2011年(6)

2010年(9)

2009年(19)

2008年(5)

我的朋友

分类:

2010-09-16 19:11:42

refresh_pattern机制分析概述
refresh_pattern指令间接的控制磁盘缓存。它帮助squid决定,是否某个给定请求是cache命中,或作为cache丢失对待。宽松的设置增加了你的cache命中率,但也增加了用户接收过时响应的机会。另一方面,保守的设置,降低了cache命中率和过时响应。refresh_pattern规则仅仅应用到没有明确过时期限的响应。原始服务器能使用Expires头部,或者Cache-Control:max-age指令来指定过时期限。
你可以在配置文件里放置任意数量的refresh_pattern行。squid按顺序查找它们以匹配正则表达式。当squid找到一个匹配时,它使用相应的值来决定,某个缓存响应是存活还是过期。refresh_pattern语法如下:
refresh_pattern [-i] regexp min percent max [options]
例如:
refresh_pattern -i \.jpg$ 30 50% 4320 reload-into-ims
refresh_pattern -i \.png$ 30 50% 4320 reload-into-ims
refresh_pattern -i \.htm$ 0 20% 1440
refresh_pattern -i \.html$ 0 20% 1440
refresh_pattern -i . 5 25% 2880
regexp参数是大小写敏感的正则表达式。你可以使用-i选项来使它们大小写不敏感。squid按顺序来检查refresh_pattern行;当正则表达式之一匹配URI时,它停止搜索。
min参数是分钟数量。它是过时响应的最低时间限制。如果某个响应驻留在cache里的时间没有超过这个最低限制,那么它不会过期。类似的,max参数是存活响应的最高时间限制。如果某个响应驻留在cache里的时间高于这个最高限制,那么它必须被刷新。
在最低和最高时间限制之间的响应,会面对squid的最后修改系数(LM-factor)算法。对这样的响应,squid计算响应的年龄和最后修改系数,然后将它作为百分比值进行比较。响应年龄简单的就是从原始服务器产生,或最后一次验证响应后,经历的时间数量。源年龄在Last-Modified和Date头部之间是不同的。LM-factor是响应年龄与源年龄的比率。
图7-2论证了LM-factor算法。squid缓存了某个目标3个小时(基于Date和Last-Modified头部)。LM-factor的值是50%,响应在接下来的1.5个小时里是存活的,在这之后,目标会过期并被当作过时处理。假如用户在存活期间请求cache目标,squid返回没有确认的cache命中。若在过时期间发生请求,squid转发确认请求到原始服务器。
图: 基于LM-factor计算过期时间
理解squid检查不同值的顺序非常重要。如下是squid的refresh_pattern算法的简单描述:
假如响应年龄超过refresh_pattern的max值,该响应过期;
假如LM-factor少于refresh_pattern百分比值,该响应存活;
假如响应年龄少于refresh_pattern的min值,该响应存活;
其他情况下,响应过期。
refresh_pattern指令也有少数选项导致squid违背HTTP协议规范。它们如下:
override-expire
该选项导致squid在检查Expires头部之前,先检查min值。这样,一个非零的min时间让squid返回一个未确认的cache命中,即使该响应准备过期。
override-lastmod
改选项导致squid在检查LM-factor百分比之前先检查min值。
reload-into-ims
该选项让squid在确认请求里,以no-cache指令传送一个请求。换句话说,squid在转发请求之前,对该请求增加一个If-Modified-Since头部。注意这点仅仅在目标有Last-Modified时间戳时才能工作。外面进来的请求保留no-cache指令,以便它到达原始服务器。
ignore-reload
该选项导致squid忽略请求里的任何no-cache指令。
源码分析
关键数据结构
refresh_t
   2009 struct _refresh_t {
   2010     const char *pattern;
   2011     regex_t compiled_pattern;
   2012     time_t min;
   2013     double pct;
   2014     time_t max;
   2015     refresh_t *next;
   2016     struct {
   2017     unsigned int icase:1;
   2018 #if HTTP_VIOLATIONS
   2019     unsigned int override_expire:1;
   2020     unsigned int override_lastmod:1;
   2021     unsigned int reload_into_ims:1;
   2022     unsigned int ignore_reload:1;
   2023     unsigned int ignore_no_cache:1;
   2024     unsigned int ignore_private:1;
   2025     unsigned int ignore_auth:1;
   2026 #endif
   2027     unsigned int ignore_stale_while_revalidate:1;
   2028     } flags;
   2029     int max_stale;
   2030     int stale_while_revalidate;
   2031     int negative_ttl;
   2032 }; 
stale_flags
     56 typedef struct
     57 {
     58 unsigned int expires:                        // 是否有过期时间的标记
     59     1;
     60 unsigned int min:                                // 匹配到MIN标记
     61     1;
     62 unsigned int lmfactor:                        // 匹配到百分比标记
     63     1;
     64     unsigned int max;                        // 匹配到MAX标记
     65 } stale_flags;
refresh_pattern检查时机
Refresh_pattern的检查时机位于clientCacheHit()函数中的refreshCheckHTTPStale()函数中。该函数的流程为在disk中找到obj,Hit后即开始检查时间,看是否可以用这个Obj进行回复。
refresh_pattern检查流程
// 过期检查refresh_pattern stale==0时为Hit                                                                                stale = refreshCheckHTTPStale(e, r)                                                                                        {
 int reason = refreshCheck(entry, request, -Config.refresh_stale_window)
 {
         if (check_time > entry->timestamp)
                     age = check_time - entry->timestamp;//检查时间-时间戳
         // 搜索匹配的R规则
         R = uri ? refreshLimits(uri) : refreshUncompiledPattern(".");                                                                if (NULL == R)                                                                                                                        R = &DefaultRefresh;                                                                                                // 检查是否过期,这里描述了max\ percentage\min三个值的比较先后顺序                                                        staleness = refreshStaleness(entry, check_time, age, R, &sf)                                                                {
                 if (entry->expires > -1)
                 {                                                                                                                                // 数据有过期时间标识则用时间来做是否过期的判断依据                                                                        if (entry->expires > check_time)//没过期
                                 return -1
                         else
                                 return (check_time - entry->expires);//过期了
                 }
                     // 比较max的值,如果大于直接过期
                 if (age > R->max)
                         return (age - R->max);
                 // 比较时间戳,如果小于时间戳直接过期
                 if (check_time timestamp)
                         return (entry->timestamp - check_time);
                 // 比较百分比,有最后修改时间
                 if (entry->lastmod > -1 && entry->timestamp > entry->lastmod)
                 {
                         ime_t stale_age = (entry->timestamp - entry->lastmod) * R->pct;
                         //依据此时间做比较
                         if (age >= stale_age)
                                 return (age - stale_age); // 直接过期
                         else
                                 return -1; // 不过期
                 }
          
                 // 比较Min
                 if (age min)
                         return -1;//不过期
                 else
                         return (age - R->min); //过期
                 }
          
                 if (staleness next)
    123     {
    124         if (!regexec(&(R->compiled_pattern), url, 0, 0, 0))
    125             return R;
    126     }
    127     return NULL;
    128 }
可见如果每个正则的pattern很宽松,并且正好匹配到的正则在链表的最末尾,则耗时最长。
               

本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u2/73200/showart_1934760.html
阅读(1062) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~