一、介绍
1. 特点
(1)是基于内存缓存,重启后数据将消失。
(2)利用虚拟内存方式,io性能好。
(3)支持设置0~60秒内的精确缓存时间。
(4)VCL配置管理比较灵活。
(5)32位机器上缓存文件大小为最大2G。
(6)具有强大的管理功能,例如top,stat,admin,list等。
(7)状态机设计巧妙,结构清晰。
(8)利用二叉堆管理缓存文件,达到积极删除目的。
2.适用场景
需要缓存大量小文件,并发要求不是很大的小型系统和应用
二、部署:
1. 编译安装:
下载最新稳定版:http://varnish-cache.org/_downloads/varnish-4.1.10.tgz
参考官网安装文档安装依赖:
sudo yum install \
make \
autoconf \
automake \
jemalloc-devel \
libedit-devel \
libtool \
ncurses-devel \
pcre-devel \
pkgconfig \
python-docutils \
python-sphinx
编译:
cd varnish-cache
sh autogen.sh
sh configure \
--prefix=/data/webserver/varnish/ \
--enable-dependency-tracking \
--enable-developer-warnings \
--enable-debugging-symbols
安装:
make
sudo make install
生成配置:
cp etc/example.vcl /data/webserver/varnish/etc/default.vcl
安装命令:
将编译后的sbin/*命令文件:1. 拷贝 / 2. 软链接到环境变量目录 / 3. 增加环境变量。使命令生效
2. yum/rpm安装
curl -s https://packagecloud.io/install/repositories/varnishcache/varnish41/script.rpm.sh | sudo bash
sudo yum install varnish-4.1.10-1.el6.x86_64
或
wget --content-disposition https://packagecloud.io/varnishcache/varnish41/packages/el/6/varnish-4.1.10-1.el6.x86_64.rpm/download.rpm
rpm -ivh varnish-4.1.10-1.el6.x86_64.rpm
二、目录架构
以yum安装为例:
/etc/ld.so.conf.d/varnish-x86_64.conf #动态链接库文件
/etc/logrotate.d/varnish #日志切割配置
/etc/rc.d/init.d/{varnish,varnishncsa} #启动脚本
/etc/sysconfig/varnish #Varnish配置文件
/etc/varnish/default.vcl #VCL配置模板
/usr/bin/{varnishadm,varnishhist,varnishlog,varnishncsa,varnishstat,varnishtest,varnishtop} #管理工具
/usr/share/doc/ #文档目录
/usr/share/man/ #man文档
/var/lib64/varnish #lib库文件
/var/lib/varnish #lib库文件
/var/log/varnish #日志文件
三、配置:
1. 配置样例:
/etc/sysconfig/varnish
/etc/varnish/default.vcl
2. 常用配置:
#加载后端负载均衡模块
import directors;
#加载std模块,后端是否正常通过std.healthy(backend)判断
import std;
#创建名为backend_healthcheck的健康检查策略
probe backend_healthcheck {
.url="/";
.interval = 5s;
.timeout = 1s;
.window = 5;
.threshold = 3;
}
#定义后端服务器
backend server1 {
.host = "172.16.17.28";
.port = "80";
.probe = backend_healthcheck;
}
backend server2 {
.host = "172.16.17.132";
.port = "80";
.probe = backend_healthcheck;
}
#定义允许清理缓存的IP
acl purgers {
"127.0.0.1";
"localhost";
"172.16.16.254";
}
#初始化子程序创建后端主机组
sub vcl_init {
new web_cluster = directors.round_robin();
web_cluster.add_backend(server1);
web_cluster.add_backend(server2);
}
#请求入口,用于接收和处理请求。这里一般用作路由处理,判断是否读取缓存和指定该请求使用哪个后端
sub vcl_recv {
#将请求指定使用web后端集群 .在集群名后加上 .backend()
set req.backend_hint = web_cluster.backend();
# 匹配清理缓存的请求
if (req.method == "PURGE") {
if (!client.ip ~ purgers) {
return (synth(405, "Not Allowed."));
}
# 是的话就执行清理
return (purge);
}
}
# 修改response的http的header中的X-cache字段
sub vcl_deliver {
# 如果返回的object中说明缓存命中了, 那么我们记下一条log
if (obj.hits > 0) {
set resp.http.X-Cache="Hit from: " + server.hostname;
} else {
set resp.http.X-Cache="Miss hit";
}
}
# 响应头隐藏服务端信息
# 在 vcl_deliver 子程序中是可以任意修改添加响应头信息,所以服务器中有 varnish 则后端服务器无需修改隐藏配置。
sub vcl_deliver {
# Happens when we have all the pieces we need, and are about to send the
# response to the client.
#
# You can do accounting or modifying the final object here.
# varnish 默认显示版本信息
unset resp.http.Via;
#varnish 默认
unset resp.http.X-Varnish;
#后端服务器版本信息,如:Apache
#set resp.http.Server="no-server";
#删除Server显示
unset resp.http.Server;
}
3. VCL处理流程
4. VCL内置函数
① vcl_recv 函数
用于接收和处理请求。当请求到达并成功接收后被调用,通过判断请求的数据来决定如何处理请求。例如如何响应、怎么响应、使用哪个后端服务器等。
此函数一般以如下几个关键字结束。
pass:表示进入 pass 模式,把请求控制权交给 vcl_pass 函数。
pipe:表示进入 pipe 模式,把请求控制权交给 vcl_pipe 函数。
lookup:表示进入 lookup 模式,把请求控制权交给 lookup 指令处理,在缓存中查找被请求的对象,并且根据查找的结果把控制权交给函数 vcl_hit 或函数 vcl_miss。
error code [reason]:表示返回“code”给客户端,并放弃处理该请求。“code”是错误标识,例如 200 和 405 等。“reason”是错误提示信息。
② vcl_pipe 函数
此函数在进入 pipe 模式时被调用,用于将请求直接传递至后端主机,在请求和返回的内容没有改变的情况下,将不变的内容返回给客户端,直到这个连接被关闭。
此函数一般以如下几个关键字结束。
error code [reason]。
pipe。
③ vcl_pass 函数
此函数在进入 pass 模式时被调用,用于将请求直接传递至后端主机。后端主机在应答数据后将应答数据发送给客户端,但不进行任何缓存,在当前连接下每次都返回最新的内容。
此函数一般以如下几个关键字结束。
error code [reason]。
pass。
restart 重新启动流程,增加启动次数,如果重新启动次数高于 max_restarts 发出一个错误警告
④ vcl_hash
当您想把一个数据添加到 hash 上时,调用此函数。
此函数一般以如下几个关键字结束。
Hash。
⑤ vcl_hit 函数
在执行 lookup 指令后,在缓存中找到请求的内容后将自动调用该函数。
此函数一般以如下几个关键字结束。
deliver:表示将找到的内容发送给客户端,并把控制权交给函数 vcl_deliver。
error code [reason] 。
pass。
restart 重新启动流程,增加启动次数,如果重新启动次数高于 max_restarts 发出一个错误警告
⑥ vcl_miss 函数
在执行 lookup 指令后,在缓存中没有找到请求的内容时自动调用该方法。此函数可用于判断是否需要从后端服务器获取内容。
此函数一般以如下几个关键字结束。
fetch:表示从后端获取请求的内容,并把控制权交给 vcl_fetch 函数。
error code [reason] 。
pass。
⑦ vcl_fetch 函数
在后端主机更新缓存并且获取内容后调用该方法,接着,通过判断获取的内容来决定是将内容放入缓存,还是直接返回给客户端。
此函数一般以如下几个关键字结束。
error code [reason]。
pass。
deliver。
esi。
restart 重新启动流程,增加启动次数,如果重新启动次数高于 max_restarts 发出一个错误警告
⑧ vcl_deliver 函数
将在缓存中找到请求的内容发送给客户端前调用此方法。
此函数一般以如下几个关键字结束。
error code [reason]。
deliver。
restart 重新启动流程,增加启动次数,如果重新启动次数高于 max_restarts 发出一个错误警告
⑨ vcl_error
出现错误时调用此函数。
此函数一般以如下几个关键字结束。
deliver。
restart。
5. VCL内置公共变量
请求到达时可用公共变量
向后端主机请求时可用公共变量
后端主机获取内容时可使用公共变量
对客户端相应时可使用公共变量
三、对比与测试:
1. Varnish与Squid
相同点:
(1)都是一个反向代理服务器。
(2)都是开源软件。
Varnish的优点:
(1)Varnish的稳定性很高,两者在完成相同负荷的工作时,Squid服务器发生故障的几率要高于Varnish,因为使用Squid要经常重启。
(2)Varnish访问速度更快,Varnish采用了“Visual Page Cache”技术,所有缓存数据都直接从内存读取,而squid是从硬盘读取,因而Varnish在访问速度方面会更快。
(3)Varnish可以支持更多的并发连接,因为Varnish的TCP连接释放要比Squid快。因而在高并发连接情况下可以支持更多TCP连接。
(4)Varnish可以通过管理端口,使用正则表达式批量的清除部分缓存,而Squid是做不到的。
(5) squid属于是单进程使用单核CPU,但Varnish是通过fork形式打开多进程来做处理,所以是合理的使用所有核来处理相应的请求。
Varnish缺点
1) varnish进程一旦Hang、Crash或者重启,缓存数据都会从内存中完全释放,此时所有请求都会发送到后端服务器,在高并发情况下,会给后端服务器造成很大压力。
2) 在varnish使用中如果单个url的请求通过HA/F5(负载均衡)每次请求不同的varnish服务器中,被请求varnish服务器都会被穿透到后端,而且同样的请求会在多台服务器上缓存,也会造成varnish的缓存的资源浪费,也会造成性能下降。
解决方案:
1) 综上所述在访问量很大的情况下推荐使用varnish的内存缓存方式启动,而且后面需要跟多台squid服务器。主要为了防止前面的varnish服务、服务器被重启的情况下,前期肯定会有很多的穿透这样squid可以担当第二层CACHE,而且也弥补了varnish缓存在内存中重启都会释放的问题。
2) 这样的问题可以在负载均衡上做url哈希,让单个url请求固定请求到一台varnish服务器上,可以解决该问题。