利用Header机制隐掉Vary,提高mod_cache缓存的命中率


HTTP 1.1的规范建议所有的请求输出都包含Vary Header,目的是针对对前端缓存服务器,增加针对Vary制定的各种Header类型进行不同的缓存处理,在浏览器规格复杂的情况下,不利于缓存的命中,所以要在被缓存的服务器上设置:

Header unset Vary

问题是这样被发现的:最近使用Apache 2.2的内存缓存mod_mem_cache机制进行后台静态文件加速。但是总是发现几乎是只代理而不缓存,而内存缓存模式又没有统计工具查看缓存内容和命中率。转为用mod_disk_cache后,前端缓存目录空间增加非常快,以至于经常需要删除文件,而删除文件的I/O损失超过了直接访问后台访问的加速所得。后台明明只有几M模板图片和CSS文件,为什么缓存空间上G而且命中率那么低呢?查看了一下缓存目录下的文件,Apache的前端磁盘缓存就会根据浏览器除了针对内容的.data文件和.header文件外还有一个.vary目录,而这个vary目录下又会按照顶级的cache规则再mapping出2级目录来,目录节点个数过多造成磁盘空间的浪费:

a/b/Jqyw8OvBIlgaef7Zb8lQ.data
a/b/Jqyw8OvBIlgaef7Zb8lQ.header
a/b/Jqyw8OvBIlgaef7Zb8lQ.header.vary/a/b

当遇到和原有Vary不同的Header时,会在 header.vary目录下生成更多的缓存;从Apache的讨论组上看原因就是IE的AcceptEncoding请求头信息里增加了一个空格
IE : Accept-Encoding: gzip, deflate
Firefox: Accept-Encoding: gzip,deflate

于是按照Fernando的方法,将后台的Vary Header禁掉了。缓存空间立刻停止了增长(还是个别有header.vary目录出现)。

另外一个配置优化是不要启用后台的Expires Header;

ExpiresActive off

由前端的Cache服务器设置缓存规则,基本上到后台的访问就很少了;

记录一个调试缓存缓存用命令行看Header输出的方法:
curl -I 查看HTTP头信息;
查看缓存后输出结果:
curl -I http://www.example.com/foo.bar
查看缓存前的服务器输出:
curl -I -H "Host: www.example.com" http://ip.address.of.example/foo.bar

[chedong]$ curl -I -H "Host: public.blogbus.com" http://192.168.1.17/rss/xianguo.png
HTTP/1.1 200 OK
Date: Sat, 12 Apr 2008 07:09:51 GMT
Server: Apache
Last-Modified: Mon, 28 Jan 2008 03:34:55 GMT
Accept-Ranges: bytes
Content-Length: 1353
Content-Type: image/png

[chedong]$ curl -I http://public.blogbus.com/rss/xianguo.png
HTTP/1.1 200 OK
Date: Sat, 12 Apr 2008 07:10:01 GMT
Server: Apache/2.2.8 (Unix)
Last-Modified: Mon, 28 Jan 2008 03:34:55 GMT
Accept-Ranges: bytes
Content-Length: 1353
Cache-Control: max-age=20736000
Expires: Mon, 08 Dec 2008 06:27:41 GMT
Node: B01-AD-01
Age: 2540
Content-Type: image/png

更多参考:
mod_cache:mod_disk_cache实现相对较成熟;

W3上关于HTTP Vary Header的讨论: 对于Proxy是不适合用Vary Header的

>Based on these examples, am I correctly understanding how Vary: is
>supposed to work?
Yes and no. For the request/variant scenario you listed a server SHOULD NOT
BE USING VARY: Sorry to shout, but I want it to be real clear. Vary: is
strictly for those cases where it's hopeless or excessively complicated for
a proxy to replicate what the server would do (other than storing header and
doing strict request header equality comparisons on subsequent requests).
Here's the parallel example for what you described above using the superior
method --> the URI: scheme:

对于删除过大的磁盘缓存目录:

3 1 * * * (/usr/bin/killall find; /usr/bin/find /path/to/cache/ -type f -mtime +5 |/usr/bin/xargs /bin/rm -f )

使用htcacheclean基本跟不上缓存的增长,对于过大的磁盘缓存还是要用find rm

作者:车东 发表于:2008-04-12 09:04 最后更新于:2008-04-12 16:04
版权声明:可以转载,转载时请务必以超链接形式标明文章 的原始出处和作者信息及本版权声明

Comments

呃,不是很理解。
如果原因是IE的Accept-Encoding多了个空格,
最多是缓存占用多一倍的空间啊,
而你的说法是不停的增长,并且不命中。
是否是其他header造成的啊?

我也想問這個

不過, 正常的設定應該是

static compressed file :
can ignore Vary

static uncompressed file
I don't know it is smart enough to cache gzipped bytes rather then gzip them every time

dynamic content:
Ignore Vary may cause problem

我也不是很理解,为什麽我都在httpd.conf里设定好 cache了,但就是不会如这篇文章所说的,会产生cache的目录呢??不知是否可以也把相关的设定值贴出来,参考一下呢??Thanks

发表一个评论

(如果你此前从未在此 Blog 上发表过评论,则你的评论必须在 Blog 主人验证后才能显示,请你耐心等候。)