varnish

结构化数据:按照一定的模式scheme存放数据,如mariadb上的表结构
半结构化数据:数据自带元数据,无固定scheme约束的数据,
非结构化数据:如日志,数据无表头,无元数据
结构化数据:关系型数据库存放,可以分布式存储
半结构化数据:各种各样的nosql存放,可以分布式存储
非结构化数据:文件系统接口存放,可以分布式文件系统存储,若不是文件系统存放,则是分布式块存储
WebPage Cache
缓存按照工作方式划分:
代理式缓存(proxied),如nginx的缓存功能,varnish作为专门缓存
旁路式缓存(bypass),如memcached,临时缓存,客户端访问mysql,把数据请求下来,并自行决定是否缓存到memchaced,称为smart client,客户端需要知道mysql数据的位置,缓存的位置
http
1.0版本:
客户端到服务器请求数据,后端服务器把数据缓存到缓存服务器并且响应数据给客户端,当下次客户端再次请求相同资源时(如根据rul),则到缓存服务器直接命中。但第一次后端服务器缓存数据到缓存服务器的数据是有缓存时间限制的,即缓存时间的有效期,假如从缓存时起2小时(采用绝对时间),缓存数据有效,当缓存数据有效期过后,则失效,需要再次到后端服务器请求数据,但失效的缓存数据的在后端服务器并不一定改变,则浪费带宽,采用过期机制
1.1版本:
再1.0的基础上,采用文件验证,即缓存数据到期后,检验文件内容的校验码,看是否改变,如没有改变,则失效的缓存数据再次获得2个小时(相对时间)的有效缓存期,此过程只有请求和响应的校验码,节约带宽
条件式请求:Etag(extend tag)
If-None-Match 304,not modified或者200 ok ,文件内容不匹配(又称指纹不匹配)
If-modify-since 304 ,not modified 时间戳改变
1.1版本加入了cache-control
public缓存:即缓存的内容是可以共享的
private缓存:缓存的内容不可以共享,涉及私人信息,如cookie,浏览器本地的缓存
User-Agent <–> private cache <–> public cache <–> public cache 2 <–> Original Server
Cache-Control: key=value, key=value
缓存有效性判断机制:
过期时间:Expires
HTTP/1.0
Expires:过期
HTTP/1.1
Cache-Control: maxage=
Cache-Control: s-maxage=
条件式请求:
Last-Modified/If-Modified-Since:基于文件的修改时间戳来判别;
Etag/If-None-Match:基于文件的校验码来判别;
客户端浏览器本地缓存,CDN,缓存服务器等多级缓存可以解决客户端80%的请求资源
在代理服务器之前的缓存,对webpage cache开源解决方案
squid
varnish 主流
varnish官方站点: http://www.varnish-cache.org/
Community
Enterprise
This is Varnish Cache, a high-performance HTTP accelerator.
程序架构:
Manager进程 : #管理cahce子进程,升级,管理
Cacher进程,包含多种类型的线程: #工作进程
accept, worker, expiry, …
shared memory log:
统计数据:计数器;
日志区域:日志记录;
varnishlog(日志), varnishncsa(ncsa格式日志), varnishstat(统计日志)…
配置接口:VCL
Varnish Configuration Language, DSL(Domain Specific Language)域专用语言
vcl complier –> c complier –> shared object
vcl配置语言,即对varnish的配置文件配置好之后,要生效,需要编译为c语言,再用c语言编译为程序,即可生效
varnish的每个版本使用都不一样
每个引擎都有自己的专用域配置,即类似iptables中的netfilter的5个勾子
如图4.0版本的图,椭圆形代表一个引擎
两类配置
配置varnishd守护进程
配置缓存系统
state engine
前端:vcl_recv,vcl_pipe(4层代理),vcl_hash(7层代理),vcl_hit,vcl_pass,vcl_purge,vcl_synth,vcl_delive
后端:vcl_backend_fetch,vcl_backend_response,vcl_backend_error
vcl_init,vcl_fin
[root@varnish ~ ]#yum info varnish
Loaded plugins: fastestmirror, langpacks
Loading mirror speeds from cached hostfile
Available Packages
Name : varnish
Arch : x86_64
Version : 4.0.5
Release : 1.el7
Size : 453 k
Repo : epel1/7
Summary : High-performance HTTP accelerator
URL : http://www.varnish-cache.org/
License : BSD
Description : This is Varnish Cache, a high-performance HTTP accelerator.
: Documentation wiki and additional information about Varnish is
: available on the following web site: http://www.varnish-cache.org/
缓存存放
key,value
key→keys_zone 内存存放
value→disk hash url的3级路由寻址,按照文件层级放在磁盘上
如nginx的缓存功能
memory
malloc,free 内核调用内存分配,free为释缓存c语言编写的系统调用
jemalloc 在2006年为提高低性能的malloc而写的Jemalloc。Jemalloc是从2007年开始以FreeBSD标准引进来的。软件技术革新很多是FreeBSD发起的。在FreeBSD应用广泛的技术会慢慢导入到linux。Redis2.4版本之后,默认使用Jemalloc来做内存管理
disk
single bin file
persistent基于磁盘的持久存储
disk,experimental
[root@varnish ~ ]#rpm -ql varnish
/etc/logrotate.d/varnish
/etc/varnish
/etc/varnish/default.vcl
/etc/varnish/varnish.params
/usr/lib/systemd/system/varnish.service
/usr/lib/systemd/system/varnishlog.service
/usr/lib/systemd/system/varnishncsa.service
/usr/sbin/varnish_reload_vcl
/usr/sbin/varnishd
/usr/share/doc/varnish-4.0.5
[root@varnish ~ ]#cd /etc/varnish/
[root@varnish varnish ]#ls
default.vcl secret varnish.params
[root@varnish varnish ]#vim varnish.params
# Main configuration file. You probably want to change it.VARNISH_VCL_CONF=/etc/varnish/default.vcl
# Default address and port to bind to. Blank address means all IPv4
ARNISH_LISTEN_PORT=6081 #面向后端代理服务器的链接端口
# Admin interface listen address and port
VARNISH_ADMIN_LISTEN_ADDRESS=127.0.0.1
VARNISH_ADMIN_LISTEN_PORT=6082 #管理端口
# Shared secret file for admin interface
VARNISH_SECRET_FILE=/etc/varnish/secret #共享对称密钥做管理功能身份验证
# Backend storage specification, see Storage Types in the varnishd(5)
# man page for details.
VARNISH_STORAGE="malloc,256M" #内存管理,256M有点小
#VARNISH_STORAGE="file,/var/lib/varnish/varnish.bin 16G"
# User and group for the varnishd worker processes
VARNISH_USER=varnish
VARNISH_GROUP=varnish
[root@varnish ~ ]#varnishd -h #帮助文档
[root@varnish ~ ]#varnishadm -h
varnishadm: invalid option -- 'h'
usage: varnishadm [-n ident] [-t timeout] [-S secretfile] -T [address]:port command [...]
-n is mutually exlusive with -S and -T
[root@varnish ~ ]#varnishadm -S /etc/varnish/secret -T 127.0.0.1:6082
help [<command>]
ping [<timestamp>]
auth <response>
quit
banner
status
start
stop
vcl.load <configname> <filename>
vcl.inline <configname> <quoted_VCLstring>
vcl.use <configname>
vcl.discard <configname>
vcl.list
param.show [-l] [<param>]
param.set <param> <value>
panic.show
panic.clear
storage.list
vcl.show [-v] <configname>
backend.list [<backend_expression>]
backend.set_health <backend_expression> <state>
ban <field> <operator> <arg> [&& <field> <oper> <arg>]...
ban.list
[root@varnish varnish ]#vim default.vcl
backend default {
.host = "192.168.31.17";
.port = "8080";
}
[root@varnish varnish ]#varnish_reload_vcl
Loading vcl from /etc/varnish/default.vcl
Current running config name is
Using new config name reload_2018-09-05T11:05:52
VCL compiled.
VCL 'reload_2018-09-05T11:05:52' now active
available 0 boot
active 0 reload_2018-09-05T11:05:52
Done
[root@varnish varnish ]#varnishadm -S /etc/varnish/secret -T 127.0.0.1:6082
vcl.list
200
available 0 boot
active 0 reload_2018-09-05T11:05:52
vcl.use reload_2018-09-05T11:05:52
[root@cos27 ~ ]#curl 192.168.31.7:6081
<!DOCTYPE html>
<html>
<head>
<title>503 Backend fetch failed</title>
</head>
<body>
<h1>Error 503 Backend fetch failed</h1>
<p>Backend fetch failed</p>
<h3>Guru Meditation:</h3>
<p>XID: 3</p>
<hr>
<p>Varnish cache server</p>
</body>
</html>
varnish定义缓存命中
[root@varnish varnish ]#vim default.vcl
backend default {
.host = "192.168.31.17";
.port = "80";
}
vcl.use boot
200
VCL 'boot' now active
vcl.discard reload_2018-09-05T11:05:52
200
vcl.load dhy1 default.vcl
200
VCL compiled.
vcl.use dhy1
200
VCL 'dhy1' now active
[root@cos27 ~ ]#curl 192.168.31.7:6081
<h1>varnish backend server 31.17</h1>
[root@cos27 ~ ]#curl -I 192.168.31.7:6081
HTTP/1.1 200 OK
Date: Wed, 05 Sep 2018 03:18:25 GMT
Server: Apache/2.4.6 (CentOS)
Last-Modified: Wed, 05 Sep 2018 03:09:55 GMT
ETag: "26-575171bdc3afe"
Content-Length: 38
Content-Type: text/html; charset=UTF-8
X-Varnish: 32784 12
Age: 13
Via: 1.1 varnish-v4
Connection: keep-alive
sub vcl_deliver
if (obj.hits>0) {
set resp.http.X-Cache = "HIT via" + " " + server.ip;
} else {
set resp.http.X-Cache = "MISS from " + server.ip;
}
[root@varnish varnish ]#vim default.vcl
Done
[root@varnish varnish ]#varnishadm -S /etc/varnish/secret -T 127.0.0.1:6082
vcl.load dhy2 default.vcl
200
VCL compiled.
vcl.use dhy2
200
VCL 'dhy2' now active
vcl.show -v dhy2
[root@cos27 ~ ]#curl -I 192.168.31.7:6081
HTTP/1.1 200 OK
Date: Wed, 05 Sep 2018 04:08:04 GMT
Server: Apache/2.4.6 (CentOS)
Last-Modified: Wed, 05 Sep 2018 03:09:55 GMT
ETag: "26-575171bdc3afe"
Content-Length: 38
Content-Type: text/html; charset=UTF-8
X-Varnish: 65597 43
Age: 2
Via: 1.1 varnish-v4
X-Cache: HIT via 192.168.31.7 #命中
Connection: keep-alive
不检查缓存
示例1:强制对某类资源的请求不检查缓存:
vcl_recv {
if (req.url ~ "(?i)^/(login|admin)") {
return(pass);
}
}
取消图片的cookid
示例2:对于特定类型的资源,例如公开的图片等,取消其私有标识,并强行设定其可以由varnish缓存的时长; 定义在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;
}
}
后端httpd服务器记录客户端访问的ip地址
示例3:定义在vcl_recv中;
if (req.restarts == 0) {
if (req.http.X-Fowarded-For) {
set req.http.X-Forwarded-For = req.http.X-Forwarded-For + "," + client.ip;
} else {
set req.http.X-Forwarded-For = client.ip;
}
}
在httpd的日志格式配置文件中,添加http.X-Fowarded-For
缓存对象的修剪:purge, ban
配置purge操作:
(1) 能执行purge操作
sub vcl_purge {
return (synth(200,"Purged"));
}
(2) 何时执行purge操作
sub vcl_recv {
if (req.method == "PURGE") {
return(purge);
}
...
}
-----------------
添加此类请求的访问控制法则:
acl purgers {
"127.0.0.0"/8;
"10.1.0.0"/16;
"192.168.31.7"/24;
}
sub vcl_recv {
if (req.method == "PURGE") {
if (!client.ip ~ purgers) {
return(synth(405,"Purging not allowed for " + client.ip));
}
return(purge);
}
...
}
测试
curl -I 192.168.31.7:6081/index.html
curl -X "PURGE" 192.168.31.7:6081/index.html
curl -I 192.168.31.7:6081/index.html
Banning: 检查匹配的url,只是一次生效
(1) varnishadm:
ban <field> <operator> <arg>
示例:
ban req.url ~ (?i)^/javascripts
ban req.url ~ (?I)^/test[456].html$
(2) 在配置文件中定义,使用ban()函数;
示例:
if (req.method == "BAN") {
ban("req.http.host == " + req.http.host + " && req.url == " + req.url);
# Throw a synthetic page so the request won't go to the backend.
return(synth(200, "Ban added"));
}
curl -X BAN http://www.ilinux.io/test1.html
ban req.http.host==www.ilinux.io && req.url==/test1.html
如何设定使用多个后端主机:#动静分离
backend default {
.host = "192.168.31.17";
.port = "80";
} backend appsrv {
.host = "192.168.31.27";
.port = "80";
}
sub vcl_recv {
if (req.url ~ "(?i)\.php$") {
set req.backend_hint = appsrv;
} else {
set req.backend_hint = default;
}
...
}
nginx: proxy_pass
haproxy: use_backend
Director:
varnish是http协议代理服务器缓存,也可以做负载均衡
varnish module;
使用前需要导入:
import directors;
示例:
import directors; # load the directors
backend server1 {
.host = "192.168.31.17";
.port = "80";
}
backend server2 {
.host = "192.168.31.27";
.port = "80";
}
sub vcl_init {
new websrvs = directors.round_robin();
websrvs.add_backend(server1);
websrvs.add_backend(server2);
}
sub vcl_recv {
set req.backend_hint = websrvs.backend();
}
基于随机的调度方式,支持服务器权重:
# sub vcl_init {
# new websrvs = directors.random();
# websrvs.add_backend(srv1,1);
# websrvs.add_backend(srv2,2);
# }
会话绑定
基于cookie的session sticky:
sub vcl_init {
new h = directors.hash();
h.add_backend(one, 1); // backend 'one' with weight '1'
h.add_backend(two, 1); // backend 'two' with weight '1'
}
sub vcl_recv {
// pick a backend based on the cookie header of the client
set req.backend_hint = h.backend(req.http.cookie);
}
后端服务器健康性检查
BE Health Check:
backend BE_NAME {
.host =
.port =
.probe = {
.url=
.timeout=
.interval=
.window=
.threshold=
}
}
.probe:定义健康状态检测方法;
.url:检测时要请求的URL,默认为”/";
.request:发出的具体请求;
.request =
"GET /.healthtest.html HTTP/1.1"
"Host: www.magedu.com"
"Connection: close"
.window:基于最近的多少次检查来判断其健康状态;
.threshold:最近.window中定义的这么次检查中至有.threshhold定义的次数是成功的;成功阈值;
.interval:检测频度;
.timeout:超时时长;
.expecteesponse:期望的响应码,默认为200;
健康状态检测的配置方式:
(1) probe PB_NAME { }
backend NAME = {
.probe = PB_NAME;
...
}
(2) backend NAME {
.probe = {
...
}
}
示例:
probe check {
.url = "/customindex.html";
.window = 5;
.threshold = 4;
.interval = 2s;
.timeout = 1s;
}
backend default {
.host = "192.168.31.7";
.port = "80";
.probe = check;
}
backend appsrv {
.host = "192.168.31.27";
.port = "80";
.probe = check;
}
手动设定BE主机的状态: #强制设定
sick:管理down;
healthy:管理up;
auto:probe auto;
backend.set_health websrv1 auto
设置后端的主机属性:
backend BE_NAME {
...
.connect_timeout = 0.5s;
.first_byte_timeout = 20s;
.between_bytes_timeout = 5s;
.max_connections = 50;
}
varnish的运行时参数:
线程模型:
cache-worker
cache-main
ban lurker
acceptor:
epoll/kqueue:
...
线程相关的参数:使用线程池机制管理线程;
在线程池内部,其每一个请求由一个线程来处理; 其worker线程的最大数决定了varnish的并发响应能力;
thread_pools:Number of worker thread pools. 最好小于或等于CPU核心数量;
thread_pool_max:The maximum number of worker threads in each pool. 每线程池的最大线程数;
thread_pool_min:The minimum number of worker threads in each pool. 额外意义为“最大空闲线程数”;
最大并发连接数 = thread_pools * thread_pool_max
thread_pool_timeout:Thread idle threshold. Threads in excess of thread_pool_min, which have been idle for at least this long, will be destroyed.
thread_pool_add_delay:Wait at least this long after creating a thread.
thread_pool_destroy_delay:Wait this long after destroying a thread.
Timer相关的参数:
send_timeout:Send timeout for client connections. If the HTTP response hasn't been transmitted in this many seconds the session is closed.
timeout_idle:Idle timeout for client connections.
timeout_req: Max time to receive clients request headers, measured from first non-white-space character to double CRNL.
cli_timeout:Timeout for the childs replies to CLI requests from the mgt_param.
设置方式:
vcl.param
param.set
查看
param.show thread_pools
param.show thread_pool_max
param.show thread_pool_min
param.set thread_pools 4
永久有效的方法:
varnish.params #的最后一行
DEAMON_OPTS="-p PARAM1=VALUE -p PARAM2=VALUE"
#DAEMON_OPTS="-p thread_pool_min=5 -p thread_pool_max=500 -p thread_pool_timeout=300"
varnish日志区域:
shared memory log
计数器
日志信息
命令
varnishstat
varnishtop
varnishncsa
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
显示指定参数的当前统计数据;
# varnishstat -l -f MAIN -f MEMPOOL
列出指定配置段的每个参数的意义;
2、varnishtop - Varnish log entry ranking
-1 Instead of a continously updated display, print the statistics once and exit.
-i taglist,可以同时使用多个-i选项,也可以一个选项跟上多个标签;
-I <[taglist:]regex>:对指定的标签的值基于regex进行过滤;
-x taglist:排除列表
-X <[taglist:]regex>:对指定的标签的值基于regex进行过滤,符合条件的予以排除;
3、varnishlog - Display Varnish logs
4、 varnishncsa - Display Varnish logs in Apache / NCSA combined log format
内建函数:
hash_data():指明哈希计算的数据;减少差异,以提升命中率;
regsub(str,regex,sub):把str中被regex第一次匹配到字符串替换为sub;主要用于URL Rewrite
regsuball(str,regex,sub):把str中被regex每一次匹配到字符串均替换为sub;
return():
ban(expression)
ban_url(regex):Bans所有的其URL可以被此处的regex匹配到的缓存对象;
synth(status,"STRING"):生成响应报文;
永久保存日志
systemctl start varnishncsa.service
cat /usr/lib/systemd/system/varnishncsa.service
启动服务即是写到文件中
总结:
varnish: state engine, vcl
varnish 4.0:
vcl_init
vcl_recv
vcl_hash
vcl_hit
vcl_pass
vcl_miss
vcl_pipe
vcl_waiting
vcl_purge
vcl_deliver
vcl_synth
vcl_fini
vcl_backend_fetch
vcl_backend_response
vcl_backend_error
sub VCL_STATE_ENGINE {
...
}
backend BE_NAME {}
probe PB_NAME {}
acl ACL_NAME {}
补充资料:varnish book
http://book.varnish-software.com/4.0/
5881

被折叠的 条评论
为什么被折叠?



