一、web緩存概述
緩存,又稱加速器,用于加速運行速度較快的設備與較慢設備之間的通信?;诔绦虻倪\行具有局部性特征其能實現加速的功能:
時間局部性:一個數據被訪問之后,在隨后較短的時間內有可能被訪問。
空間局部性:一個數據被訪問之后,其周邊的數據也可能被訪問到。
緩存有效與否,是通過緩存命中率來衡量的。緩存命中,意味著在請求某資源時,在緩存中找到該資源,并響應給客戶端。
緩存是把之前訪問到的數據及其周邊的數據放置于具有更快速度的、效率更高的設備中來完成加速。使用緩存之后,資源的請求與響應過程由client–>server–>client改變為client–>cache[–>server]–>client。若在緩存中沒有查找到相應的資源,將會由緩存向server請求該資源,這一過程,會造成額外的開銷,若換成命中率過低,則會造成資源的浪費。因此,提高緩存的命中率是必然的。
緩存命中率的計算方式:hits/(hits+misses) (0-1)
緩存命中率的衡量方式:
頁面命中率:命中的page比率。基于頁面數量衡量
字節命中率:命中的page占用的資源大小比率。根據內容大小衡量。
在計算機單體之間需要使用緩存,
緩存用于http server,其作用為緩存page請求,稱之為web page cache;用于緩存mysql server,其作用為緩存數據查詢結果,稱之為data cache。
程序運行的局部性特征的表現為,在某server提供的資源中存在熱區數據,即少部分的數據帶來大多數的訪問。因此,緩存是針對熱區數據的。
由于server上的源數據可能發生更新,此時緩存服務器上的緩存數據被標記為過期,因此,緩存具有時效性。對應過期的緩存,應進行清理操作。當緩存空間耗盡時,緩存也需要清理。清理緩存使用LRU算法。
如何判斷數據是否應該被緩存:
用戶的私有數據:可以被private cache緩存
公共數據:可以緩存至private or public
cache
二、緩存相關的http首部信息
1)Expires:緩存有效期。判斷緩存是否在有效期內,若是,則以緩存的內容響應客戶端;否,則緩存服務器向http server請求最新的數據,獲得相應的數據之后,構建響應,響應給客戶端,并將數據緩存至本地。一般不應該將此設定的未來過長的時間,一年的長度對大多場景來說足矣;其常用于為純靜態內容如JavaScripts樣式表或圖片指定緩存周期;
http1.0僅支持Expires
http1.1支持Cache-Control中的max-age、s-maxage
2)條件式請求:
2.1)If-Modified-Since/Last-Modified:緩存服務器對比請求數據的時間戳,判斷本地的數據時間戳與http server上的時間戳是否一致,若一致,則http server返回給緩存服務器304(Not-Modified)的狀態碼,緩存服務器直接使用本地的數據響應客戶端;不一致,則http server返回給緩存服務器200(OK)的狀態碼,緩存服務器使用http server發送的最新數據響應給客戶端,并將該數據緩存至本地。
2.2)If-None-Match/Etag:web服務器為某web資源加上一個ETag首部,客戶端請求時能獲取并保持這個首部的值,在后續的請求中,會通過If-None-Match首部附加其認可的標簽列表并讓服務器檢驗器原始內容是否有可以與此列表中的某標簽匹配的標簽。若有,則響應304,否則,則返回原始內容。
若數據內容沒有發生改變,則數據的ETag不會發生改變;反之,則數據的ETag發生改變。緩存服務器在接受到請求之后,會與http server請求比對數據的ETag,若一致,則http server返回給緩存服務器304,緩存服務器直接使用本地的數據響應客戶端;不一致,則http server返回給緩存服務器200(OK)并返回原始數據,緩存服務器使用http server發送的最新數據響應給客戶端,并將該數據緩存至本地。
一般情況下,以上三種方式可以混合使用,也可單獨使用。
3)Cache-Control:可用于請求報文和響應報文,用于定義所有的緩存機制都必須遵循的緩存指示,這些指示是一些特定的指令,Cache-Control中設定的時間會覆蓋Expires中指定的時間。
3.1)在請求報文中,Cache-Control的指令:
no-cache:運行緩存服務器檢查緩存,但需與http server做revalidate之后,才能響應該請求。
no-store:不允許緩存服務器通過檢查緩存來響應該請求
max-age:以秒為單位,指定緩存的相應最大期限。expires是絕對時間
max-stale
min-fresh
no-transform
only-if-cached
cache-extension
3.2)在響應報文中,Cache-Control的指令:
public:此響應的內容可被緩存至任意緩存中
private:此響應的內容只可被緩存至private cache中
no-store:響應的內容不能被緩存服務器緩存
no-cache:響應的內容可以被緩存,但不能直接響應請求,需與http server校驗(revalidate)無誤之后才可響應。
max-age:以秒為單位,指定緩存的相應最大期限。
s-maxage:與max-age類似,但只能用于公共緩存中
must-revalidate:必須做重新校驗
三、web緩存的開源解決方案:squid、varnish
varnish是一個輕量級的Cache和反向代理軟件。
varnish官方站點:http://www.varnish-cache.org/
varnish官方文檔:http://book.varnish-software.com/(3.0|4.0|5.0)/
1、安裝varnish:
1.1CentOS6:
yum install epel-release
rpm --nosignature -i https://repo.varnish-cache.org/redhat/varnish-4.0.el6.rpm
yum install varnish
1.2CentOS7:
yum install epel-release
rpm --nosignature -i https://repo.varnish-cache.org/redhat/varnish-4.0.el7.rpm
yum install varnish
獲取最新版varnish及其安裝:參考https://www.varnish-cache.org/releases/index.html
2、varnish程序環境:
/etc/varnish/vanishparams(CentOS7)或/etc/sysconfig/varnish(CentOS6):配置varnish服務進程的工作特性,例如監聽地址和端口、緩存機制
/etc/varnish/ default.vcl:配置個child/cache線程的工作屬性
/usr/sbin/varnishd:主程序
/usr/bin/varnishadm:命令行接口
Shared Memory Log交互工具:
/usr/bin/varnishhist
/usr/bin/varnishlog
/usr/bin/varnishncsa
/usr/bin/varnishstat
/usr/bin/varnishtop
/usr/bin/varnishtest:測試工具
/usr/sbin/varnish_reload_vcl:配置文件重載程序
System init file:
/etc/rc.d/init.d/varnish:varnish服務
/etc/rc.d/init.d/varnishlog
/etc/rc.d/init.d/varnishncsa
varnish默認監聽在6081端口,管理端口默認監聽在6082端口
3、varnish程序選項:
程序選項:/etc/varnish/vanishparams或/etc/sysconfig/varnish文件
-a address[:port]
-t address[:port]:Admin
-s [name=]type[,options]:定義緩存存儲機制
-u user
-g group
-f config:VCL配置文件
-F:運行于前臺,調試時使用
-p param=value:設定運行參數及其值,可重復使用多次。在服務重啟時會恢復到默認值,可通過修改配置文件/etc/varnish/vanishparams或/etc/sysconfig/varnis中的DAEMON_OPTS選項來實現永久修改。
-r param[,param…]:設定指定的參數為只讀狀態
4、vanishadm命令的使用:
]# varnishadm -S /etc/varnish/secret -T :6082
]# varnishadm -S /etc/varnish/secret -T 127.0.0.1:6082
其子命令:
help [<command>]:獲取幫助
4.1配置文件相關
vcl.load <configname>
<filename>:加載配置文件
vcl.inline <configname>
<quoted_VCLstring>
vcl.use <configname>:使用配置文件
vcl.discard <configname>
vcl.list:已編譯成功的vcl列表
vsl.show [-v] <configname>:查看指定配置文件的詳細信息
例:
varnish> vcl.list 200 available auto/cold 0 boot available auto/cold 0 reload_2016-11-10T11:23:32 active auto/warm 0 reload_2016-11-10T11:24:19
active表示使用中的配置,available表示可用的配置
4.2 運行時參數:
param.show -l:顯示列表;
param.show <PARAM>
param.set <PARAM> <VALUE>
4.3查看緩存存儲:storage.list
4.4查看后端服務器:backend.list
四、varnish系統架構
1、varnish4.0系統架構
Manager Process:主要實現應用新的配置、編譯VCL、監控varnish、初始化vanish以及提供命令行接口等,不直接響應請求。
Cacher Process包含多種類型的線程:
Storage:緩存的存儲管理
Log/Stats:緩存中的數據統計和日志管理。存放于Shared Memory Log中。
Worker threads:線程池中的每個線程響應一個請求,varnish的處理能力由(線程池數*線程池中的線程數)決定。
Acceptor線程:接受新的連接請求并響應
Expiry線程:從緩存中清理過期內容
VCC
Process(Varnish C Compiler)將VCL策略配置文件按轉換為C代碼,之后由C Compiler將其編譯為二進制程序,之后,由manager process將其連接至varnish實例。
2、varnish日志:為了與系統的其他部分進行交互,Cacher Process使用了可以通過文件系統接口進行訪問的共享內存日志(Shared
Memory Log),因此,如果某線程需要記錄信息,其僅需要持有一個鎖,而后向共享內存中的某區域寫入數據,再釋放持有的鎖即可。為了減速競爭,每個worker線程都使用了日志緩存數據。
共享內存日志大小一般為90M,其分為兩個部分,前一部分為計數器,后半部分為客戶端請求的數據。varnish提供了多個不同的工具,如varnishlog、varnishncsa、varnishstat等來分析共享內存日志中的信息并能夠以指定的方式進行顯示。
3、VCL(Varnish Configuration Language):是varnish配置緩存策略的工具,它是一種基于“域”(domain specific)的簡單編程語言,它支持有限的算術運算和邏輯運算操作、允許使用正則表達式進行字符串匹配、允許用戶使用set自定義變量、支持if判斷語句,也有內置的函數和變量等。使用VCL編寫的緩存策略通常保存至.vcl文件中,其需要編譯成二進制的格式后才能由varnish調用。事實上,整個緩存策略就是由幾個特定的子例程如vcl_recv、vcl_fetch等組成,它們分別在不同的位置(或時間)執行,如果沒有事先為某個位置自定義子例程,varnish將會執行默認的定義。
VCL策略在啟用前,會由management進程將其轉換為C代碼,而后再由gcc編譯器將C代碼編譯成二進制程序。編譯完成后,management負責將其連接至varnish實例,即Cache Process。正是由于編譯工作在Cache Proces進程之外完成,它避免了裝載錯誤格式VCL的風險。因此,varnish修改配置的開銷非常小,其可以同時保有幾份尚在引用的舊版本配置,也能夠讓新的配置即刻生效。編譯后的舊版本配置通常在varnish重啟時才會被丟棄,如果需要手動清理,則可以使用varnishadm的vcl.discard命令完成。
4、VCL4.0的語法格式
(1)vcl 版本號
(2)//或#或/*…*/注釋
(3)子例程與函數使用sub關鍵字聲明
(4)不支持循環,但支持變量,支持與引擎密切相關的內建變量(受限于引擎)
(5)使用keyword結束當前狀態引擎,使用return決定返回給哪個狀態引擎
(6)域專用的配置。配置只在當前狀態引擎可用
5、varnish的緩存存儲機制
varnish支持多種不同類型的后端存儲,這可以在varnishd啟動時使用-s選項指定。后端存儲的類型包括:
(1)file:使用特定的文件存儲全部的緩存數據,并通過操作系統的mmap()系統調用將整個緩存文件映射至內存區域(如果條件允許);重啟后所有緩存項失效
(2)malloc:使用malloc()庫調用在varnish啟動時向操作系統申請指定大小的內存空間以存儲緩存對象;重啟后所有緩存項失效
(3)persistent(experimental):與file的功能相同,但可以持久存儲數據(即重啟varnish數據時不會被清除);仍處于測試期;重啟后所有緩存項依然有效
varnish無法追蹤某緩存對象是否存入了緩存文件,從而也就無從得知磁盤上的緩存文件是否可用,因此,file存儲方法在varnish停止或重啟時會清除數據。而persistent方法的出現對此有了一個彌補,但persistent仍處于測試階段,例如目前尚無法有效處理要緩存對象總體大小超出緩存空間的情況,所以,其僅適用于有著巨大緩存空間的場景。
選擇使用合適的存儲方式有助于提升系統性,從經驗的角度來看,建議在內存空間足以存儲所有的緩存對象時使用malloc的方法,反之,file存儲將有著更好的性能的表現。然而,需要注意的是,varnishd實際上使用的空間比使用-s選項指定的緩存空間更大,一般說來,其需要為每個緩存對象多使用差不多1K左右的存儲空間,這意味著,對于100萬個緩存對象的場景來說,其使用的緩存空間將超出指定大小1G左右。另外,為了保存數據結構等,varnish自身也會占去不小的內存空間。
為varnishd指定使用的緩存類型時,-s選項可接受的參數格式如下:
malloc[,size] 或
file[,path[,size[,granularity]]] 或
persistent,path,size {experimental}
file中的granularity用于設定緩存空間分配單位,默認單位是字節,所有其它的大小都會被圓整。
五、VCL狀態引擎
5.1客戶端的請求在VCL的有限狀態引擎之間流轉,VCL有限狀態引擎特性如下:
(1)每個請求被單獨處理
(2)每個請求在任何時間與其他請求都是獨立的
(3)各狀態引擎有相關性,,但彼此間互相隔離
(4)使用return(action)來退出當前狀態并指示varnish進入下一個狀態
(5)內建的VCL代碼會一直有效且會追加至自定義的代碼之后
在VCL狀態引擎中,狀態之間具有相關性,但彼此間互相隔離,每個引擎使用return(x)來退出當前狀態并指示varnish進入下一個狀態。
varnish開始處理一個請求時,首先需要分析HTTP請求本身,比如從首部獲取請求方法、驗正其是否為一個合法的HTT請求等。當這些基本分析結束后就需要做出第一個決策,即varnish是否從緩存中查找請求的資源。這個決定的實現則需要由VCL來完成,簡單來說,要由vcl_recv方法來完成。如果管理員沒有自定義vcl_recv函數,varnish將會執行默認的vcl_recv函數。然而,即便管理員自定義了vcl_recv,但如果沒有為自定義的vcl_recv函數指定其終止操作(terminating),其仍將執行默認的vcl_recv函數。事實上,varnish官方強烈建議讓varnish執行默認的vcl_recv以便處理自定義vcl_recv函數中的可能出現的漏洞。
5.2
varnish4.0中常見的引擎切換機制:
1)緩存命中:vcl_recv–>vcl_hash–return(hit)–>vcl_hit–>vcl_deliver(投遞給客戶端)
2)緩存未命中: vcl_recv–>vcl_hash–return(miss)–>vcl_backend_fetch(向后端服務器獲取對應的資源)–>vcl_backend_response–>vcl_deliver
3)請求內容為清理緩存:vcl_recv–>vcl_hash–return(purge)–>vcl_purge(清理緩存)–>vcl_synth
4)請求首部未知:vcl_recv–>vcl_hash–return(pipe)–>vcl_pipe(建立client與server的隧道,由server直接處理請求)
6)若請求到達時服務器繁忙:vcl_recv–>vcl_hash–return(busy)–>waiting(等待服務器處理)–> vcl_hash
vcl_pass表示略過
7)兩個特殊的引擎:
vcl_init:在處理任何請求之前要執行的vcl代碼:主要用于初始化VMODs;
vcl_fini:所有的請求都已經結束,在vcl配置被丟棄時調用;主要用于清理VMODs;
六、VCL的三類主要語法
1)sub
subroutine {
…
}
2)if CONDITION
{
…
}
else {
…
}
3)return(),
hash_data()
6.1
VCL的內建函數和關鍵字(keywords)
1)內建函數
regsub(str,regex,sub)
regsuball(str,regex,sub):這兩個用于基于正則表達式搜索指定的字符串并將其替換為指定的字符串;但regsuball()可以將str中能夠被regex匹配到的字符串統統替換為sub, regsub()只替換一次;
ban(expression):
ban_url(regex):Bans所有其URL能夠由regex匹配的緩存對象;
purge:從緩存中挑選出某對象以及其相關變種一并刪除,這可以通過HTTP協議的PURGE方法完成;
hash_data(str):
關鍵字
call subroutine:調用函數
return:當某VCL域運行結束時將控制權返回給Varnish,并指示Varnish如何進行后續的動作;其可以返回的指令包括:lookup、pass、pipe、hit_for_pass、fetch、deliver和hash等;但某特定域可能僅能返回某些特定的指令,而非前面列出的全部指令;
return(restart):重新運行整個VCL,即重新從vcl_recv開始進行處理;每一次重啟都會增加req.restarts變量中的值,而max_restarts參數則用于限定最大重啟次數。
new
set:設置變量
unset:撤銷變量
例1: 如果請求被命中,設定響應報文中的http首部中的X-Cache首部的值,區別于未命中時X-Cache的值
obj.hits:記錄緩存的名字數
修改default.vcl配置文件
使用varnishadm連接管理varnish
vcl.load
conf_version1 ./default.vcl #加載最新版本的配置文件并將其命名為conf_version1
varnish>
vcl.list #查看使用中和可以的配置文件版本
200
available auto/cold 0 boot
available auto/cold 0 reload_2016-11-10T11:23:32
active auto/warm 0
reload_2016-11-10T11:24:19
available auto/warm 0 test1
available auto/warm 0 conf_version1
vcl.use
conf_version1 #使用新版本配置
2)VCL內建變量:
req.*:request,表示由客戶端發來的請求報文相關;
req.http.*
req.http.User-Agent, req.http.Referer, …
bereq.*:由varnish發往BE主機的httpd請求相關;
resp.*:與varnish響應給客戶端的報文相關
beresp.*:與varnish收到的后端服務器響應報文相關
beresp.http.*
obj.*:存儲在緩存空間中的緩存對象的屬性;只讀;
2.1、常用變量
a)
bereq.*, req.*:
bereq.http.HEADERS:HEADERS可以自定義
bereq.request:請求方法;
bereq.url:請求的url;
bereq.proto:請求的協議版本;
bereq.backend:指明要調用的后端主機;
req.http.Cookie:客戶端的請求報文中Cookie首部的值;
req.http.User-Agent
~ "chrome"
b)
beresp.*, resp.*:
beresp.http.HEADERS
beresp.status:響應的狀態碼;
reresp.proto:協議版本;
beresp.backend.name:BE主機的主機名;
beresp.ttl:BE主機響應的內容的余下的可緩存時長;
c)
obj.*:
obj.hits:此對象從緩存中命中的次數;
obj.ttl:對象的ttl值
d)
server.*
server.ip
server.hostname
e)
client.*
client.ip
2.2、各內建變量的使用范圍:
例2:強制對某資源的請求不檢查緩存
對客戶端請求的判斷應該放置于配置文件靠前位置
sub vcl_recv { if(req.url ~ "(?i)/(login|admin)"){ return(pass); } }
示例2:對于特定類型的資源,例如公開的圖片等,取消其私有標識,并強行設定其可以由varnish緩存的時長;
sub vcl_backend_response { if (beresp.http.cache-control !~ "s-maxage") { if (bereq.url ~ "(?i)\.(jpg|jpeg|png|gif|css|js)$") { unset beresp.http.Set-Cookie; set beresp.ttl = 3600s; } } }
例3:對來至于firefox或curl的請求不檢查緩存
sub vcl_recv { if(req.http.User-Agent ~ "(curl|firefox)"){ return(pass); } }
七、緩存修剪(purge)
清理后端服務器內容已發生修改,但緩存服務器上的內容仍未過期的內容。
清理緩存的方法:purge、ban
purge:修剪客戶端請求的url
ban:可指定表達式,對本地緩存中該表達式匹配的緩存項進行清理
清理操作應當只有管理員才可執行。
添加此類請求的訪問控制法則:
acl purgers{ "127.0.0.0"/8; "192.168.154.129"/32; } sub vcl_recv { if (req.method == "PURGE") { if (!client.ip ~ purgers) { return(synth(405,"Purging not allowed for " + client.ip)); } return(purge); } ... }
八、后端定義多主機:
1、實現將php的請求分發至192.168.154.128
其余的請求分發至192.168.154.127
#定義后端主機
backend
server1 {
.host =
.port =
}
在sub_recv中判斷url
if(req.url ~ "(?i)\.php"){ set req.backend_hint = phpserver; }else{ set req.backend_hint = default; }
2、實現負載均衡調度至后端主機
import
directors;#導入模塊
#定義后端主機
backend
server1 {
.host =
.port =
}
backend
server1 {
.host =
.port =
}
處理請求之前定義后端服務器集群
sub vcl_init { new webcluster = directors.round-robin(); #定義調度算法 webcluster.add_backend(server1); webcluster.add_backend(server2); }
設置使用自定義的服務器集群響應請求
set
req.backend_hint = webcluster;
配置如下:
import directors; # Default backend definition. Set this to point to your content server. backend default { .host = "192.168.154.127"; .port = "80"; } backend phpserver { .host = "192.168.154.128"; .port = "80"; } sub vcl_init { new webcluster = directors.round_robin(); webcluster.add_backend(default); webcluster.add_backend(phpserver); } sub vcl_recv { set req.backend_hint = webcluster.backend(); if(req.url ~ "(?i)/(login|admin)"){ return(pass); } }
需要注意的是:請求一個可被緩存的頁面一次之后,后續的都將會被調度至同一個服務器;只有不可被緩存的資源才會在服務器集群之間進行輪詢。
九、后端服務器監控狀態檢測
默認情況下啊,varnish并不會對后端服務器進行檢測,當某臺后端服務器出現故障不能正常訪問時,其仍會將請求調度至該服務器。
使用.probe定義健康狀態檢測。
.probe定義健康狀態檢測方式:
.url:檢測時請求的URL,默認為"/"
.request:發出的具體請求
.request =
"GET /.healthtesthtml
HTTP1.1"
"Host www.example.com|ipaddr"
“Connection:close”
.window:基于最近的多少次檢查來判斷其健康狀態
.threshold:最近的.window中定義的檢測次數中至少有.threshhold定義的次數是成功的
.interval:檢測頻度
.timeout:超時時長
.expected_response:期望的響應碼,默認200
健康狀態檢測的配置方式:
(1)每個后端主機定義單獨的檢測方式
backend
NAME {
.host =
.port =
.probe = {
.url
.window
…
}
}
(2)定義一個檢測方式,多個后端主機可以引用同一個檢測方式
probe
PB_Name = {
.url
.window
…….
}
backend
NAME = {
.host =
.port =
.probe = PB_Name;
…….
}
配置示例:
probe
http_check {
.url = "/.healthcheck.html";
.window = 5;
.threshold = 4;
.interval = 2s;
.timeout = 1s;
}
#
Default backend definition. Set this to point to your content server.
backend
default {
.host = "192.168.154.127";
.port = "80";
.probe = http_check;
}
backend
phpserver {
.host = "192.168.154.128";
.port = "80";
.probe = http_check;
}
在varnishadm中使用backend.lis查看后端主機的健康狀態
varnish>
backend.list
200
Backend
name Refs Admin Probe
default(192.168.154.127,,80) 6probe Healthy 5/5
phpserver(192.168.154.128,,80)
4 probe Sick 0/5
十、varnish管理進階
1、可調參數
Varnish有許多參數,雖然大多數場景中這些參數的默認值都可以工作得很好,然而特定的工作場景中要想有著更好的性能的表現,則需要調整某些參數??梢栽诠芾斫涌谥惺褂?span lang="EN-US">param.show命令查看這些參數,而使用param.set則能修改這些參數的值。然而,在命令行接口中進行的修改不會保存至任何位置,因此,重啟varnish后這些設定會消失。此時,可以通過啟動腳本使用-p選項在varnishd啟動時為其設定參數的值。然而,除非特別需要對其進行修改,保持這些參數為默認值可以有效降低管理復雜度。
2、共享內存日志
共享內存日志(shared memory log)通常被簡稱為shm-log,它用于記錄日志相關的數據,大小為80M。varnish以輪轉(round-robin)的方式使用其存儲空間。一般不需要對shm-log做出更多的設定,但應該避免其產生I/O,這可以使用tmpfs實現,其方法為在/etc/fstab中設定一個掛載至/var/lib/varnish目錄(或其它自定義的位置)臨時文件系統即可。
1)、varnishstat
– Varnish Cache statistics
-1
-1 -f FILED_NAME
-l:可用于-f選項指定的字段名稱列表;
MAIN.cache_hit
MAIN.cache_miss
#
varnishstat -1 -f MAIN.cache_hit -f MAIN.cache_miss
2)、varnishtop
– Varnish log entry ranking
-1Instead of a continously updated display, print the statistics once and
exit.
-i taglist,可以同時使用多個-i選項,也可以一個選項跟上多個標簽;
-I <[taglist:]regex>
-x taglist:排除列表
-X<[taglist:]regex>
3)、varnishlog
– Display Varnish logs
4)、varnishncsa – Display Varnish logs in Apache / NCSA combined log format
3、線程模型(Trheading
model)
varnish的child進程由多種不同的線程組成,分別用于完成不同的工作。例如:
cache-worker線程:每連接一個,用于處理請求;
cache-main線程:全局只有一個,用于啟動cache;
ban lurker線程:一個,用于清理bans;
acceptor線程:一個,用于接收新的連接請求;
epoll/kqueue線程:數量可配置,默認為2,用于管理線程池;
expire線程:一個,用于移除老化的內容;
backend poll線程:每個后端服務器一個,用于檢測后端服務器的健康狀況;
在配置varnish時,一般只需為關注cache-worker線程,而且也只能配置其線程池的數量,而除此之外的其它均非可配置參數。與此同時,線程池的數量也只能在流量較大的場景下才需要增加,而且經驗表明其多于2個對提升性能并無益處。
4、線程相關的參數(Threading parameters)
varnish為每個連接使用一個線程,因此,其worker線程的最大數決定了varnish的并發響應能力。下面是線程池相關的各參數及其配置:
thread_pool_add_delay 2 [milliseconds]
thread_pool_add_threshold 2 [requests]
thread_pool_fail_delay 200 [milliseconds]
thread_pool_max 500 [threads]
thread_pool_min 5 [threads]
thread_pool_purge_delay 1000 [milliseconds]
thread_pool_stack 65536 [bytes]
thread_pool_timeout 120 [seconds]
thread_pool_workspace 16384 [bytes]
thread_pools 2 [pools]
thread_stats_rate 10 [requests]
其中最關鍵的當屬thread_pool_max和thread_pool_min,它們分別用于定義每個線程池中的最大線程數和最少線程數。因此,在某個時刻,至少有thread_pool_min*thread_pools個worker線程在運行,但至多不能超出thread_pool_max*thread_pools個。根據需要,這兩個參數的數量可以進行調整,varnishstat命令的n_wrk_queued可以顯示當前varnish的線程數量是否足夠,如果隊列中始終有不少的線程等待運行,則可以適當調大thread_pool_max參數的值。但一般建議每臺varnish服務器上最多運行的worker線程數不要超出5000個。
當某連接請求到達時,varnish選擇一個線程池負責處理此請求。而如果此線程池中的線程數量已經達到最大值,新的請求將會被放置于隊列中或被直接丟棄。默認線程池的數量為2,這對最繁忙的varnish服務器來說也已經足夠。
附件列表
原創文章,作者:M20-1鐘明波,如若轉載,請注明出處:http://www.www58058.com/59626