Apache的缓存体系分为HTTP协议缓存和SOCACHE共享内存缓存两大类,其中mod_cache_disk实现的磁盘缓存是最常用的一种。它的工作原理并不复杂:当请求第一次到达服务器时,mod_cache判断该响应是否可缓存,如果可以,mod_cache_disk就把响应头和响应体序列化后写入磁盘上的缓存目录;当同样的请求再次到来时,模块直接从磁盘读取缓存内容返回给客户端,跳过了磁盘IO读取源文件、执行PHP脚本等耗时操作。本文以Windows环境为例,完整演示这套机制的配置过程。

一、先理清三个模块的分工关系
配置磁盘缓存之前,必须搞清楚mod_cache、mod_cache_disk和可选的mod_cache_socache各自负责什么,否则很容易配错。mod_cache是核心调度模块,它负责实现RFC 2616定义的HTTP缓存协商逻辑,判断哪些请求命中缓存、缓存是否过期,但它自己不存储任何数据。真正把数据写到磁盘的是mod_cache_disk,所以这两个模块必须同时启用。至于mod_cache_socache,它提供了基于共享内存的另一种存储后端,适合缓存体积小的内容,配置磁盘缓存时可以不启用。
另外还有一个容易混淆的模块叫mod_file_cache,它只针对静态文件做内存映射缓存,与mod_cache体系完全是两回事,不要混用。判断模块是否已经编译进Apache的方法很简单,打开C:\Apache24\bin目录,执行httpd.exe -M命令,在输出列表里找cache_disk_module和cache_module。如果前面带static说明已经静态编译,没有的话就需要在配置文件中用LoadModule指令加载。
二、修改httpd.conf加载模块并设置缓存目录
用记事本或者Notepad++打开C:\Apache24\conf\httpd.conf,找到LoadModule区域,确保以下两行存在且没有被注释。如果文件里找不到这两行,说明编译时未包含该模块,需要换用完整编译版的Apache发行包:
LoadModule cache_module modules/mod_cache.so LoadModule cache_disk_module modules/mod_cache_disk.so
接下来设置磁盘缓存的根目录,也就是CacheRoot指令。这里有个Windows平台特有的注意点:路径必须使用反斜杠,例如C:\Apache24\cache\disk,如果写成C:/Apache24/cache/disk这种斜杠形式,某些版本下会出现缓存写入失败的问题。建议在Apache安装目录之外单独建一个缓存分区目录,避免和站点文件混在一起。配置写法如下:
LoadModule cache_module modules/mod_cache.so
LoadModule cache_disk_module modules/mod_cache_disk.so
<IfModule mod_cache_disk.c>
# 缓存根目录,Windows下使用反斜杠路径
CacheRoot "C:\Apache24\cache\disk"
# 缓存目录层级,第一层和第二层各16个子目录
CacheDirLevels 2
CacheDirLength 1
# 单个缓存文件最小和最大体积,单位字节
CacheMinFileSize 1
CacheMaxFileSize 1000000
</IfModule>CacheDirLevels和CacheDirLength这两个参数决定了缓存文件的散列目录结构。CacheDirLevels 2表示缓存文件名经过哈希后取两位字符作为两级目录,CacheDirLength 1表示每级目录名长度为1个字符。如果站点缓存文件数量达到百万级,可以适当加大层级数,否则单个目录下文件过多会拖慢文件系统查找速度。CacheMaxFileSize用于限制缓存体积上限,示例中限制为1MB以内,避免大文件占满磁盘。
配置完成后,手动创建C:\Apache24\cache\disk目录并赋予Apache运行账户读写权限。如果你是以Windows服务方式运行Apache,默认账户可能是LocalSystem,通常对本地目录有完整权限;如果改用自定义账户运行,则需要在目录属性的安全选项卡中手动添加该账户并勾选修改权限。
三、在虚拟主机中挂载缓存策略
前面的配置只是让存储后端就绪,还要告诉mod_cache对哪些内容启用缓存、缓存多久。这一步通过CacheEnable指令完成。CacheEnable disk /表示对根路径下所有请求启用磁盘缓存。下面给一个完整的虚拟主机示例,对一个静态资源站点启用缓存:
<VirtualHost *:80>
ServerName static.ipipp.com
DocumentRoot "C:\www\static"
<IfModule mod_cache.c>
# 对所有URI启用磁盘缓存
CacheEnable disk /
# 禁止对带查询字符串的请求做缓存判断之外的处理
CacheIgnoreNoLastMod On
CacheStorePrivate On
# 缓存600秒后过期
CacheDefaultExpire 600
</IfModule>
<Directory "C:\www\static">
AllowOverride None
Require all granted
</Directory>
</VirtualHost>关于CacheDefaultExpire需要多说几句。如果后端响应头里带有Cache-Control或Expires字段,mod_cache会优先遵循这些字段;只有在响应头没有提供任何过期信息时,才会使用CacheDefaultExpire指定的秒数作为兜底。CacheIgnoreNoLastMod设为On,可以让没有Last-Modified头的响应也被缓存,这对某些动态生成的静态化页面很有用。而CacheStorePrivate设为On要谨慎,它允许缓存带有Cache-Control: private标记的响应,如果站点有登录态内容,可能导致用户之间串缓存,生产环境建议保持Off。
保存配置后,在命令行执行httpd.exe -t检查语法。提示Syntax OK后执行httpd.exe -k restart重启服务,让配置生效。
四、验证缓存是否生效与日常维护
重启后用curl或者浏览器开发者工具连续访问两次同一URL,观察响应头中的X-Cache字段。第一次请求通常是miss,说明缓存未命中,内容从后端生成;第二次请求变为hit或refresh,说明磁盘缓存已经工作。同时打开C:\Apache24\cache\disk目录,能看到类似\f\8\xxx.header和xxx.data这样的成对文件,前一个存放响应头元信息,后一个存放响应体,两者必须成对存在缓存才会命中。
磁盘缓存有个绕不开的问题:文件只增不减。Apache自带了一个清理工具htcacheclean,位于C:\Apache24\bin目录下,可以限制缓存总占用。建议注册成Windows计划任务定期运行,例如每天凌晨清理一次,把缓存总量控制在2GB以内:
C:\Apache24\bin\htcacheclean.exe -p C:\Apache24\cache\disk -l 2G -t
参数-p指定缓存根目录,-l设置容量上限,-t表示分别统计和清理header与data文件。如果配置时开启了CacheDirLevels较深的散列结构,htcacheclean的遍历会需要一些时间,安排在业务低峰期执行更稳妥。
最后补充几个常见报错的排查思路。如果日志里出现cache: Unable to find a cache directory之类的错误,基本是CacheRoot指向的目录不存在或权限不足,重新创建目录并检查账户权限即可;如果发现缓存永远不命中,先确认请求URL是否带了查询参数,再检查响应头是否包含Set-Cookie,mod_cache默认会拒绝缓存带Set-Cookie的响应,必要时可用CacheIgnoreHeaders Set-Cookie调整,但要充分评估业务风险。按照这套流程配置下来,Windows下的Apache磁盘缓存就能稳定跑起来,静态资源的响应速度和服务器负载都会有明显改善。
Apache mod_cache磁盘缓存CacheRoot修改时间:2026-09-14 06:58:35