varnish实现Web缓存
一、varnish简介
Varnish 的作者Poul-Henning Kamp是FreeBSD的内核开发者之一,他认为现在的计算机比起1975年已经复杂许多。在1975年时,储存媒介只有两种:内存与硬盘。但现在计算 机系统的内存除了主存外,还包括了CPU内的L1、L2,甚至有L3快取。硬盘上也有自己的快取装置,因此Squid Cache自行处理物件替换的架构不可能得知这些情况而做到最佳化,但操作系统可以得知这些情况,所以这部份的工作应该交给操作系统处理,这就是 Varnish cache设计架构。
varnish项目是2006年发布的第一个版本0.9.距今已经八年多了,此文档之前也提过varnish还不稳 定,那是2007年时候编写的,经过varnish开发团队和网友们的辛苦耕耘,现在的varnish已经很健壮。很多门户网站已经部署了 varnish,并且反应都很好,甚至反应比squid还稳定,且效率更高,资源占用更少。相信在反向代理,web加速方面,varnish已经有足够能力代替squid。
二、Varnish的工作原理
varnish主要运行两个进程:Management进程和Child进程(也叫Cache进程)。
Management进程主要实现应用新的配置、编译VCL、监控varnish、初始化varnish以及提供一个命令行接口等。Management进程会每隔几秒钟探测一下Child进程以判断其是否正常运行,如果在指定的时长内未得到Child进程的回应,Management将会重启此Child进程。
Child进程包含多种类型的线程,常见的如:
Acceptor线程:接收新的连接请求并响应;
Worker线程:child进程会为每个会话启动一个worker线程,因此,在高并发的场景中可能会出现数百个worker线程甚至更多;
Expiry线程:从缓存中清理过期内容;
Varnish依赖“工作区(workspace)”以降低线程在申请或修改内存时出现竞争的可能性。在varnish内部有多种不同的工作区,其中最关键的当属用于管理会话数据的session工作区。
Varnish处理过程
vcl_recv-->lookup-->vcl_hash-->vcl_hit-->vcl_deliver
vcl_recv-->lookup-->vcl_hash-->vcl_miss-->vcl_fetch-->cache-->vcl_deliver
vcl_recv-->pipe-->vcl_pipe
vcl_recv-->pass-->vcl_pass-->vcl_fetch-->nocache-->vcl_deliver
Receive 状态:也就是请求处理的入口状态,根据VCL规则判断该请求应该是Pass或Pipe,或者进入Lookup(本地查询)
Lookup 状态:进入此状态后,会在hash表中查找数据,若找到,则进入Hit状态,否则进入miss状态
Pass 状态:在此状态下,会进入后端请求,即进入fetch状态
Fetch 状态:在Fetch状态下,对请求进行后端的获取,发送请求,获得数据,并进行本地的存储
Deliver 状态:将获取到的数据发送给客户端,然后完成本次请求
三、Varnish特点
1、是基于内存缓存,重启后数据将消失
2、利用虚拟内存方式,I/O性能好
3、支持设置0~60秒内的精确缓存时间
4、VCL配置管理比较灵活
5、32位机器上缓存文件大小为最大2G
6、具有强大的管理功能,例如top,stat,admin,list等
7、状态机设计巧妙,结构清晰
8、利用二叉堆管理缓存文件,达到积极删除目的
四、安装配置varnish
1、环境
OS:CentOS 6.5
Varnish:3.0.7
Varnish IP:192.168.31.178
Web:192.168.31.105
2、安装varnish
[root@varnish-1 ~]# wget https://repo.varnish-cache.org/redhat/varnish-3.0.el6.rpm
[root@varnish-1 ~]# yum install varnish -y
[root@varnish-1 ~]# sed -i 's@VARNISH_LISTEN_PORT=.*@VARNISH_LISTEN_PORT=80@' /etc/sysconfig/varnish
[root@varnish-1 ~]# sed -i 's@VARNISH_STORAGE=.*@VARNISH_STORAGE="malloc,128M"@' /etc/sysconfig/varnish
3、varnish的配置文件内容如下(/etc/varnish/default.vcl)
backend default {
.host = "192.168.31.105";
.port = "80";
}
sub vcl_recv {
if (req.restarts == 0) {
if (req.http.x-forwarded-for) {
set req.http.X-Forwarded-For =
req.http.X-Forwarded-For + ", " + client.ip;
} else {
set req.http.X-Forwarded-For = client.ip;
}
}
if (req.request != "GET" &&
req.request != "HEAD" &&
req.request != "PUT" &&
req.request != "POST" &&
req.request != "TRACE" &&
req.request != "OPTIONS" &&
req.request != "DELETE") {
return (pipe);
}
if (req.request != "GET" && req.request != "HEAD") {
return (pass);
}
if (req.http.Authorization || req.http.Cookie) {
return (pass);
}
return (lookup);
}
sub vcl_pipe {
return (pipe);
}
sub vcl_pass {
return (pass);
}
sub vcl_hash {
hash_data(req.url);
if (req.http.host) {
hash_data(req.http.host);
} else {
hash_data(server.ip);
}
return (hash);
}
sub vcl_hit {
return (deliver);
}
sub vcl_miss {
return (fetch);
}
sub vcl_fetch {
if (beresp.ttl <= 0s ||
beresp.http.Set-Cookie ||
beresp.http.Vary == "*") {
set beresp.ttl = 120 s;
return (hit_for_pass);
}
return (deliver);
}
sub vcl_deliver {
if (obj.hits > 0){
set resp.http.X-Cache = "HIT from " + server.ip;
} else {
set resp.http.X-Cache = "MISS from " + server.ip;
}
return (deliver);
} #红色部分为设置缓存是否命中的标识
sub vcl_init {
return (ok);
}
sub vcl_fini {
return (ok);
}
五、配置后端Web服务器
[root@web-1 ~]# yum install httpd -y
[root@web-1 ~]# echo 192.168.31.105 > /var/www/html/index.html
[root@web-1 ~]# service httpd start
六、测试varnish
[root@varnish-1 ~]# curl -I http://192.168.31.178/index.html
HTTP/1.1 200 OK
Server: Apache/2.2.15 (CentOS)
Last-Modified: Sat, 05 Sep 2015 12:49:01 GMT
ETag: "c0b6d-f-51eff70ceede6"
Content-Type: text/html; charset=UTF-8
Content-Length: 15
Accept-Ranges: bytes
Date: Sat, 05 Sep 2015 20:50:35 GMT
X-Varnish: 1577077233
Age: 0
Via: 1.1 varnish
Connection: keep-alive
X-Cache: MISS from 192.168.31.178 #第一次未命中
[root@varnish-1 ~]# curl -I http://192.168.31.178/index.html
HTTP/1.1 200 OK
Server: Apache/2.2.15 (CentOS)
Last-Modified: Sat, 05 Sep 2015 12:49:01 GMT
ETag: "c0b6d-f-51eff70ceede6"
Content-Type: text/html; charset=UTF-8
Content-Length: 15
Accept-Ranges: bytes
Date: Sat, 05 Sep 2015 20:51:35 GMT
X-Varnish: 1577077234 1577077233
Age: 60
Via: 1.1 varnish
Connection: keep-alive
X-Cache: HIT from 192.168.31.178 #第二次以及第三次都命中了