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

本文探讨了HTTP1.1中VaryHeader对前端缓存的影响,通过禁用VaryHeader和ExpiresHeader,显著提升了缓存效率,减少了磁盘空间消耗。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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
<think>好的,我需要解决用户的问题:为什么在使用Apache的mod_cache_disk模块时,缓存命中状态一直显示为MISS。用户已经提供了他们的配置代码,我需要逐步分析可能的原因。 首先,我应该回顾用户提供的配置,检查是否有明显的错误。用户加载了必要的模块:mod_cachemod_cache_disk和mod_headers。然后,在mod_cache.c部分启用了磁盘缓存,路径是根目录/。这可能意味着所有URL都会被缓存,但需要注意是否有其他配置覆盖了这一点。 接下来,mod_cache_disk.c的配置部分指定了缓存目录为/data/cache,设置了目录结构为两级,每级长度1字符。文件大小限制是100MB以下,最小1字节。同时忽略了Set-Cookie头,并设置了X-Cache头部来显示命中状态。 现在思考可能的问题点: 1. **权限问题**:缓存目录/data/cache是否存在?Apache进程是否有读写权限?如果目录不存在或权限不足,缓存无法写入,导致每次都是MISS。 2. **缓存条件不满足**:虽然启用了缓存,但后端响应可能没有包含允许缓存的头部,比如Cache-Control或Expires。Apache需要这些头部来确定资源是否可缓存。如果响应中没有这些,mod_cache可能不会缓存内容。 3. **动态内容或个性化内容**:如果请求的内容是动态生成的,或者包含如Set-Cookie的头部(即使被忽略),可能导致缓存无法存储。需要检查响应头是否有其他被忽略的头部影响缓存。 4. **配置冲突**:可能存在其他配置覆盖了缓存设置,比如.htaccess文件中的设置,或者主配置中的其他CacheEnable指令。需要确保没有其他地方禁用了缓存。 5. **测试方法问题**:用户可能在测试时没有多次访问同一URL,或者使用了不同的URL导致缓存未命中。或者浏览器在请求中添加了如Pragma: no-cache等头,阻止缓存。 6. **模块加载顺序或缺失**:虽然用户加载了mod_cachemod_cache_disk,但可能存在模块加载顺序的问题,或者模块未正确启用。需要确认这些模块确实已加载,并且没有冲突。 7. **缓存目录结构设置**:CacheDirLevels和CacheDirLength设置可能导致目录结构生成问题,但通常这不会导致完全不缓存,只是路径问题。 8. **日志信息检查**:Apache的错误日志和访问日志可能提供线索。启用mod_cache的调试日志可以查看缓存的具体行为,比如是否尝试存储或检索缓存。 接下来,我应该逐步引导用户检查这些可能性: - 确认缓存目录存在且权限正确。 - 检查后端响应的Cache-Control或Expires头,确保资源被标记为可缓存。 - 检查是否有其他配置或模块干扰缓存设置。 - 建议用户进行多次访问测试,并使用工具查看响应头中的X-Cache值。 - 查看Apache日志,特别是错误日志,是否有权限错误或其他相关提示。 - 确保mod_cachemod_cache_disk和mod_headers模块正确加载,没有冲突。 另外,用户设置的CacheMaxFileSize是104857600字节(即100MB),而说明中提到“1MB以下文件会被缓存”,这可能存在笔误,需要确认是否正确。不过这可能不是导致MISS的原因,但需要指出。 最后,用户可能忽略了某些配置细节,比如CacheDefaultExpire,如果没有设置Expires或Cache-Control头,可能需要这个指令来设置默认的缓存时间。否则,资源可能因为无过期时间而无法被缓存。</think>让我们逐步分析Apache缓存配置导致始终显示`MISS`的可能原因及解决方案: --- ### **一、检查缓存目录权限** - **现象**:若目录`/data/cache`不存在或Apache无写入权限,缓存文件无法生成。 - **验证方法**: ```bash # 检查目录是否存在 ls -ld /data
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值