varnish的Backend storage的管理

    varnish緩存服務器是工作在代理模式的。意思是說,由varnish接收用戶的請求,把用戶請求資源的URL做“哈唏”編碼後,做爲“鍵”與緩存條目中的鍵做比對:

    1、如果,緩存條目有一模一樣的鍵的話,那麼該鍵對應的值就是用戶請求URL對應的資源,

       varnish把該鍵對應的值取出來,響應給客戶端。

    2、如果,緩存條目沒有與之匹配的鍵的話,那麼varnish 就向後端服務器(backup server)發送

       請求。當後端服務器(backup server )構建完響應報文響應varnish,varnish服務器收到後端

       服務器(backup server)的響應後,會把:用戶請求的URL做“哈唏”編碼後,

       作爲鍵(key),該URL對應的資源作爲值(value),保存在varnish的緩存中。

       這就是所謂的,插入緩存條目。 varnish的緩存條目是:key:value 方式存在的。

       然後,varnish再構建響應報文響應客戶端。

這就是,varnish 緩存服務器的正常工作流程。

如下圖所示:

wKioL1QkITWRXjylAALLTNOHn-Y023.jpg

那麼如何實現varnish緩存的管理呢?

1、varnish接收用戶請求後,是如何根據用戶請求的報文來決定是否查找緩存的呢?

   由上圖所知。當 varnish 服務器接收到用戶請求後,分析用戶請求的 URL 是否符合緩存標準,再查找緩存。這樣是爲了避免花費在與緩存條目比對的時間。如果,緩存條目較多的話,做緩存比對也是需要很長時間的。varnish通過如下方式,控制那些URL可以查找緩存的:

    varnish 在vcl_recv狀態引擎定義策略,怎麼樣處理用戶的請求的。如:varnish 處理的客戶端請求的標準、如果判斷是否查找緩存的。

sub vcl_recv {
    # varnish 在vcl_recv狀態引擎定義的策略來控制,varnish服務器只處理指定http協議請求資源的方法,的URL
   if (req.request != "GET" &&
      req.request != "HEAD" &&
      req.request != "PUT" &&
      req.request != "POST" &&
      req.request != "TRACE" &&\
      req.request != "OPTIONS" &&
      req.request != "DELETE") {
        /* Non-RFC2616 or CONNECT which is weird. */
        return (pipe);  -----> 用戶請求的訪問的服務雖然是:tcp/80 但是,varnish不處理除了,GET、HEAD、PUT、POST、TRACE、OPTIONS、DELETE請求資源的方法。直接讓該請求把該請求交給backup server.
    }

    # 再使用下述策略來過濾用戶請求資源時所使用的方法;判斷用戶請求資源時使用的方法不是:GET、HEAD 就繞過查找緩存的操作
    if (req.request != "GET" && req.request != "HEAD") {
        /* We only deal with GET and HEAD by default */
        return (pass);  -----> 繞過查找緩存操作,varnish直接向 backup server 請求資源
    }
    # 使用vcl_recv狀態引擎判斷用戶的請求,都不符合上述:if 條件。那麼該用戶請求資源所使用的方法一定是:GET或HEAD。但是如果用戶訪問的是資源,需要通過口令認證
    # 纔可以訪問的。用戶請求該資源使用的也是"GET"方法。該用戶請求的URL是不需要查找緩存的。
    if (req.http.Authorization || req.http.Cookie) {
       /* Not cacheable by default */
        return (pass);   -----> 繞過查找緩存操作,varnish直接向 backup server 請求資源
    }

    return (lookup);  ------> 查找緩存
}

說明:

    varnish 有很多內置變量保存了,http協議報文的信息。通過使用if判斷這些信息,來控制varnish是如何使用緩存的。

    如:

req.url            ------> 記錄用戶請求的URL
req.request        -------> 記錄了用戶請求資源使用的方法
req.http.HEADER    -------> 記錄了用戶請求報文的首部。該變量是可寫的。如:req.http.hostreq.restarts          ------->  請求被重啓的次數
server.ip             -------> varnish 的IP地址
server.port           -------> varnish 監聽的端口
server.hostname       -------> 服務器的主機名
client.ip             -------> 客戶端IP
req.backend           -------> 如果,未從緩存中命中。該請求分調度到後端的那個服務器。

例:

   當用戶訪問指定頁面時,禁止查詢緩存

     sub vcl_recv {
	    ...
	    if (req.url ~ "/images/a.jpg$" ) {
	        return (pass);
	    }

	    return (lookup);
	}

2、當緩存沒有命中(cache miss)如何控制 varnish 向緩存中插入緩存條目時,該緩存條目的過期時長呢?

使用 varnish  緩存服務器提供的:vcl_fetch 狀態引擎來控制是否向緩存中插入緩存條目的。

如:

sub vcl_recv {
      ....
           if (req.request == "GET" && req.request ~ "\.png$") {
          set beresp.ttl = 10s;
      }
      ....
}

3、如何修剪(刪除)緩存條目呢?

使用 varnish 提供 purge指令來清除不需要的緩存

如:

(1)、爲了安全,對操作清除緩存條目的指令的用戶做限制

只允許下述用戶修剪緩存條目

   acl purgers {
   "127.0.0.1";
   "172.16.13.0"/24;
}

(2)、在vcl_recv 狀態引擎,放行purge請求方法查詢緩存

sub vcl_recv {
。。。
 if (req.request == "PURGE") { ----------> 開放用戶請求資源使用 purgers 方法,
     if ( client.ip !~ purgers ) {  ------> 檢測發起 PURGE 方法的用戶來源,只允許屬於purgers的用戶的請求查詢緩存
           error 405 "Method not allowed";
      }
          return (lookup);  --------> 查詢緩存
  }

}

(3)、當緩存命中(cache hit)就執行varnish 的purge清除(修剪)緩存條目的指令

sub vcl_hit {
     if (req.request == "PURGE") {
        purge; ----------> 執行varnish 修改緩存的指令
        error 200 "Purged";   ----> 合成狀態碼,和“原因短語”
     } 
     return (deliver);
 }

(4)、使用【curl】指定使用PURGE方法訪問指定的資源,實現緩存修剪

如:

curl -X PURGE http://172.16.13.1/index.html

說明:

 

4、定義緩存大小; 

[root@haproxy2 ~]# vim /etc/sysconfig/varnish
VARNISH_STORAGE_SIZE=64M  ----> 定義緩存大小
VARNISH_STORAGE="malloc,${VARNISH_STORAGE_SIZE}" ---> 明確指定varnish使用內存做爲緩存。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章