程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> PHP編程 >> PHP基礎知識 >> varnish緩存策略及緩存時間計算方法說明

varnish緩存策略及緩存時間計算方法說明

編輯:PHP基礎知識
 

varnish作為緩存服務提供者,本身沒有內容,所有內容都是從後端的服務器或其它緩存服務器上取過來的。當varnish收到這些內容之後,需要根椐一定的策略確定是否緩存它,如果需要緩存,還需要確定可以緩存的時間。

 

1、varnish緩存策略

缺省是根椐後端返回的http狀態碼決定是否緩存。可以緩存的狀態碼如下:

200

203

300

301

302

410

404

varnish現在還不支持ranges請求,所以不會緩存206狀態的結果。

管理員可以在vcl的配置文件中的vcl_fetch部分,加入自已的緩存策略,方法是修改beresp.cacheable變量。下面的例子,看後端返回中如果設置了cookie,則不緩存:

sub fetch {

if (beresp.http.Set-Cookie) {

set beresp.cacheable = false;

}

}

2、緩存時間的計算方法

缺省的緩存時間計算方法如下:

. 先根椐max-age確定緩存時間

看返回頭中的Cache-Control頭中,有沒有指定s-maxage或max-age信息,另外,如果後端是一個緩存服務器,它還會指定一個age頭,表明已經緩存過的時間,這樣需要減去age頭指定的時間,計算出對應的緩存時間。

例1 只有max-age,沒有age

CacheControl: max-age=86400

緩存時間:86400秒,即一天

例2 同時有max-age和age信息

CacheControl: max-age=86400

Age: 6400

緩存時間:86400 – 6400 = 80000秒

. 如果沒有max-age信息,則根椐Expires頭部計算緩存時間

先看有沒有Date頭,

如果沒有Date頭

看expires指定的時間是否小於收到數據的時間

小於,表明從後端取得內容已經過期,緩存時間為0,不緩存

>=,則緩存到Expires指定的時刻再過期

如果有Date頭

看Expires指定的時間是否小於Date指定的時間

小於,取到已經過期的內容,緩存時間為0,不緩存

>=,則看Date時間跟取到內容的時間差別(判斷本機和後端的時鐘差異)

小於clock_skew(缺省是10秒,管理員可以設置別的數值),以本機時間為准

看Expires指定的時間是否小於收到數據的時間

小於,表明從後端取得的內容已經過期,緩存時間為0,不緩存

>=,則緩存到Expires指定的時刻再過期

>= clock_skew,以後端的時間為准

緩存時間為Expires – Date的差值

. 如果既沒有max-age信息,又沒有指定Expires過期信息

則按default_ttl(缺省是2分鐘,管理員可以設置成別的數值)設置緩存時間。

管理員可以在vcl的配置文件中的vcl_fetch部分,手工指定緩存時間,方法是修改beresp.ttl變量。下面的例子,將緩存時間設置成20分鐘(1200秒):

set beresp.ttl = 1200s;

3、給用戶返回已經過期的對象

varnish內部有一個grace模式。當後端不可用,或者已經向後端發過更新請求的情況下,別的客戶再請求這個對象時,會收到已經過期的版本,當然過期的時間在可接受的范圍內。

varnish缺省可接受的過期時間范圍是不超過10秒,可以修改params中的default_grace參數。修改這一數值,但這樣的改法相當於改了全局的參數,適應於所有請求。

如果想只修改特定的url對應的對象的grace時間范圍,則需要修改vcl配置,改兩個地方。首先需要修改vcl_recv過程,在收到用戶請求時指定可以接受過期對象的過期時間范圍。其次需要修改vcl_fetch過程,從後端取到內容時,設置對象過期後還可以保留的時間,這樣以便在過期後不會立即被後台線程清理掉。

下面的例子針對特定的請求,將接受對象的grace時間設置為2分鐘

sub vcl_recv {

set req.grace = 2m;

}

sub vcl_fetch {

set beresp.grace = 2m;

}

4、varnish對象過期之後的更新說明

對象過期之後,過了grace時間,就會被後台線程清理掉。下一次用戶再去訪問的時候,會從後端重新抓取該對象。更合適的方法是發一個ims請求,如果後端對應的對象沒有更新就不抓。這一點squid處理得比varnish好。希望以後的版本能改進這一塊。

參考信息:

/bin/varnishd/cache_center.c的cnt_fetch函數

/bin/varnishd/rfc2616.c的RFC2616_Ttl函數

/bin/varnishd/cache_hash.c的HSH_Lookup函數

 
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved