硬盘级缓存技术在WEB分布式架构中的应用
- Varnish是一款高性能的开源HTTP加速器,挪威最大的在线报纸 Verdens Gang 使用3台Varnish代替了原来的12台Squid,性能比以前更好。
- 图中Cache Server使用了Varnish高性能硬盘缓存服务器,对后端WEB服务器进行文件缓存,提升HTTP访问速度。
- 整理个WEB分布式架构,由客户端发起访问请求,到负载均衡层,负载系统根据预先设定的调度方式,将客户请求分配到后端硬盘缓存服务器,如果命中,立即返回客户请求数据。没有命中则请求后端WEB服务器,WEB服务器先到内存缓存服务器中查询数据,如果存在立即将数据返回,否则继续往数据库服务器集群查询相应数据。
- 在后端的内存服务器和数据库服务器基础上,同时加做了四层负载均衡,使用整个架构具备全均衡状态。后期扩展服务器只需要在负载均衡服务器上增加新服务IP就可以做到整体的平滑扩展。
- 1. Varnish 下载
- 下载地址:http://sourceforge.net/projects/varnish/files/
- 2. Varnish 安装
- #yum install pkgconfig pcre*
- #tar zxvf varnish-2.1.2.tar.gz
- #cd varnish-2.1.2
- #./configure –prefix=/opt/varnish
- #make
- #make install
- 3. Varnish 配置实例
- 通过前端 varnish 缓存服务器反向代理后端 www.test.com 和 www.test2.com 网站,要求对静态文件 js|css|jpg|gif 等文件进行缓存 7 天,对网页中加有 no-cache 头信息页面不缓存。
- 配置文件如下:
- #vi /opt/varnish/etc/varnish/index.vcl
- ###后端服务器分组
- backend te1 {
- .host = "192.168.0.110";
- .port = "80";
- .probe = {
- .url = "/"; #哪个 url需要varnish请求。
- .interval = 5s; #检查的间隔时间。
- .timeout = 1 s; #等待多长时间探针超时。
- .window = 5; #维持5个sliding window的结果。
- .threshold = 3; #至少有三次window是成功的,就宣告bachend健康。
- }
- backend te2 {
- .host = "192.168.0.155";
- .port = "80";
- .probe = {
- .url = "/";
- .interval = 5s;
- .timeout = 1 s;
- .window = 5;
- .threshold = 3;
- }
- ###定义集群
- director myvarnish round-robin {
- { .backend = te1; }
- { .backend = te2; }
- }
- ###清除缓存,访问控制
- acl local {
- "localhost";
- "127.0.0.1";
- }
- ###判断host请求针对哪个后端服务器
- sub vcl_recv {
- if (req.http.host ~ "^(www.)?test.com$") {
- set req.backend = myvarnish;
- }
- #elsif (req.http.host ~ "^(www.)?test2.com$") {
- #set req.backend = te2;
- }
- else {
- error 404 "Unknown HostName!";
- }
- ###不允许非访问控制列表的IP进行缓存清除
- if (req.request == "PURGE") {
- if (!client.ip ~ local) {
- error 405 "Not Allowed.";
- return (lookup);
- }
- }
- ###清除url中有jpg|png|gif等文件的cookie
- if (req.request == "GET" && req.url ~ "\.(jpg|png|gif|swf|jpeg|ico)$") {
- unset req.http.cookie;
- }
- ###获取客户端IP地址
- if (req.http.x-forwarded-for) {
- set reqreq.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);
- }
- ###针对请求和url地址判断是否缓存
- if (req.request != "GET" && req.request != "HEAD") {
- return (pass);
- }
- if (req.http.Authorization || req.http.Cookie) {
- return (pass);
- }
- if (req.request == "GET" && req.url ~ "\.(php)($|\?)") {
- return (pass);
- }
- return (lookup);
- }
- sub vcl_pipe {
- return (pipe);
- }
- sub vcl_pass {
- return (pass);
- }
- sub vcl_hash {
- set req.hash += req.url;
- if (req.http.host) {
- set req.hash += req.http.host;
- } else {
- set req.hash += server.ip;
- }
- return (hash);
- }
- sub vcl_hit {
- if (!obj.cacheable) {
- return (pass);
- }
- return (deliver);
- }
- sub vcl_miss {
- return (fetch);
- }
- sub vcl_fetch {
- if (!beresp.cacheable) {
- return (pass);
- }
- if (beresp.http.Set-Cookie) {
- return (pass); }
- if (beresp.http.Pragma ~ "no-cache" ||
- beresp.http.Cache-Control ~ "no-cache" ||
- beresp.http.Cache-Control ~ "private") {
- return (pass);
- }
- ###让varnish服务器缓存
- if (req.request == "GET" && req.url ~ "\.(js|css|mp3|jpg|png|gif|swf|jpeg|ico)$")
- {
- set beresp.ttl = 7d;
- }
- return (deliver);
- }
- ###查看缓存命中情况
- sub vcl_deliver {
- set resp.http.x-hits = obj.hits ;
- if (obj.hits > 0) {
- set resp.http.X-Cache = "HIT cqtel-bbs";
- } else {
- set resp.http.X-Cache = "MISS cqtel-bbs";
- }
- }
- sub vcl_error {
- set obj.http.Content-Type = "text/html; charset=utf-8";
- synthetic {"
- <?xml version="1.0" encoding="utf-8"?>
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
- <html>
- <head>
- <title>"} obj.status " " obj.response {"</title>
- </head>
- <body>
- <h1>Error "} obj.status " " obj.response {"</h1>
- <p>"} obj.response {"</p>
- <h3>Guru Meditation:</h3>
- <p>XID: "} req.xid {"</p>
- <hr>
- <address>
- <a href="http://www.test.com/">test cache server</a>
- </address>
- </body> </html>
- "};
- return (deliver);
- }
- 4. Varnish 启动与停止,动态加载配置文件
- 创建 www 用户
- #useradd www
- 启动:
- #!/bin/sh
- ulimit -SHn 51200
- /opt/varnish/sbin/varnishd -u www -g www -f /opt/varnish/etc/varnish/bbs.vcl -a 192.168.0.125:80 -s file,/data/varnish_cache/varnish_cache.data,2G -w 1024,51200,10 -t 3600 -T 192.168.0.125:3500
- 参数:
- -u 以什么用运行
- -g 以什么组运行
- -f varnish 配置文件
- -a 绑定 IP 和端口
- -s varnish 缓存文件位置与大小
- -w 最小,最大线程和超时时间
- -T varnish 管理端口,主要用来清除缓存
- 注:32位文件系统限制缓存数据文件大小为 2G
- 停止:
- #pkill varnishd
- 5. Varnish 缓存清除
- #/opt/varnish/bin/varnishadm -T 192.168.0.125:3500 purge "req.http.host ~ www.test.com$ && req.url ~ /static/p_w_picpath/test.php"
- 说明:
- 192.168.0.125:3500 为被清除缓存服务器地址
- www.test.com 为被清除的域名
- /static/p_w_picpath/test.php 为被清除的url地址列表
- 清除所有缓存
- #/opt/varnish/bin/varnishadm -T 127.0.0.1:3500 purge.rul *$
- 清除p_w_picpath目录下所有缓存
- #/opt/varnish/bin/varnishadm -T 127.0.0.1:3500 purge.url /p_w_picpath/