一、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有许多参数,虽然大多数场景中这些参数的默认值都可以工作得很好,然而特定的工作场景中要想有着更好的性能的表现,则需要调整某些参数。可以在管理接口中使用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.178linux.com/59626