开启mod_cache模块,缓存动态文件
mod_cache的存储管理模块有两个:
- mod_disk_cache,一个基于磁盘的存储管理模块。
- mod_mem_cache,一个基于内存的存储管理模块。mod_mem_cache可以被配置为两种不同的操作模式:①缓存打开的文件描述符;②在堆(heap)上缓存对象。mod_mem_cache既可以用于缓存本地生成的内容,也可以用于为反向代理模式下的mod_proxy(参见ProxyPass)缓存后端服务器输出的内容。
mod_mem_cache:基于内存的缓存
直接从系统的内存中提供服务通常是取得服务内容最快速的方法。从一个磁盘控制器读取文件,或者更糟糕的是从远程网络读取文件,其速度要慢上几个数量级。磁盘控制器通常涉及到物理动作,访问网络要受限于网络带宽,而访问内存通常仅仅只需要几毫微秒时间。
内存也许是目前单位字节最昂贵的存储器,保证它充分发挥作用非常重要。将文件缓存在内存中将导致系统可用内存的减少。正如我们将要看到的,在操作系统存在内存缓冲区的情况下,这不是一个大问题。但是当使用Apache自己的内存缓冲区的情况下,确保没有为缓冲区分配太多的内存就显得十分重要。否则,操作系统将会使用swap(虚拟内存/交换区),这可能会导致性能急剧下降。
操作系统缓冲
几乎所有现代的操作系统都由内核直接管理文件数据在内存中的缓冲。这是一个强有力的特性,并且在极大程度上操作系统做的非常好。比如在Linux系统上,让我们看看第一次读取一个文件和第二次读取同样的文件所需要的时间:
colm@coroebus:~$ time cat testfile > /dev/null real 0m0.065s user 0m0.000s sys 0m0.001s colm@coroebus:~$ time cat testfile > /dev/null real 0m0.003s user 0m0.003s sys 0m0.000s
即使对于这样的一个小文件,两次读取的时间差异也十分惊人。这是由于内核在内存中缓存了文件的内容。
通过确保在你的系统上始终存在"多余的"内存,你就可以确保会有越来越多的文件内容被缓存在这个缓冲区中。这是一个非常有效的内存缓冲途径,并且根本无需对Apache作出任何额外的配置。
另外,由于操作系统知道文件何时被修改或删除了,它就可以自动的从内存缓冲区中删除失效的文件内容。这是一个优于Apache自身的内存缓冲区的巨大优点,因为Apache无法得知文件被修改或删除的信息。
尽管操作系统自动管理的缓冲区有着性能和洞悉文件状态的优势,但是在某些情况下Apache自己的内存缓冲却更加有效。
首先,操作系统只能缓存它自己知道的文件,如果你将Apache当作一个代理服务器运行,那么Apache可以缓存非本地文件。如果你还想要无可匹敌的内存缓存速度,也必须使用Apache自己的内存缓冲区。
MMapStatic 缓冲
mod_file_cache提供了MMapStatic指令,它可以指示Apache在启动时将一个静态文件的内容映射到内存中(使用mmap()系统调用)。Apache将会使用内存中缓存的内容来为后来对这个文件的访问提供内容。
MMapStatic /usr/local/apache2/htdocs/index.html
使用了CacheFile指令以后,在Apache运行期间,对这些文件所做的任何修改都不会生效。
MMapStatic指令并不关心它占用了多少内存,所以你必须确保不要过度滥用这个指令。每个Apache子进程都将复制这部分内存,所以非常重要的一点是你必须确保被映射的文件不能占用太多的内存,以至于操作系统不得不使用交换区或虚拟内存。
mod_mem_cache 缓冲
mod_mem_cache提供了一个智能的HTTP内存缓冲方案。它同时也直接使用堆内存,这也意味着即使MMap不被你的操作系统所支持,mod_mem_cache仍然能够实现缓冲。
mod_mem_cache模块设置:
<IfModule mod_cache.c> <IfModule mod_mem_cache.c> CacheEnable mem / MCacheSize 4096 MCacheMaxObjectCount 2000 MCacheMinObjectSize 1 MCacheMaxObjectSize 2048 </IfModule> </IfModule>
安装完成之后,需要搜索
LoadModule cache_module modules/mod_cache.so // 去掉前面的# 号使用内存文件缓存:
#LoadModule mem_cache_module modules/mod_mem_cache.so // 去掉前面的# 号参数详细含义如下:
CacheEnable:
启用缓存,使用基于内存的方式存储MCacheSize:
缓存数据最多能使用的内存,单位是 kb,默认是100kb,这里设置为128MMCacheMaxObjectCount:
在内存中最多能存储缓存对象的个数,默认是1009,这里设置为20000MCacheMinObjectSize:
单个缓存对象最小为10bytes,默认为1bytesMCacheMaxObjectSize:
单个缓存对象最大为 1M,默认是10000bytes保存重启 Apache 基于内存的缓存系统应该就能生效了
根据需要可以使基于内存的存储或硬盘文件的存储方式一起使用,只要指明不同的URL路径即可。
mod_disk_cache:基于硬盘文件的缓存
基于硬盘文件存储的缓存由mod_disk_cache模块实现,这是一种智能缓冲,仅在缓存内容没有失效的情况下才从缓冲区中提供服务。
请注意,因为缓冲区位于本地磁盘上,所以操作系统的内存缓冲区通常对它们的访问也有效。所以虽然这些文件被存储在本地磁盘上,但若这些文件被频繁的访问,那么很可能操作系统已经将它们保存在内存中了。
深入理解缓冲存储区(Cache-Store)
要将项目保存在缓冲区中,mod_disk_cache会为被请求的URL创建一个22字符的哈希值。该哈希值包含了该URL的主机名、协议、端口、路径、CGI变量,以确保多个URL不会发生碰撞。
这22个字符的取值范围是64个不同的字符,这意味着最多可以有22^64种可能的取值。例如,一个URL的哈希值可能是:xyTGxSMO2b68mBCykqkp1w 。这个哈希值将被用作缓存中对应于那个URL的文件名前缀,但是首先,这个哈希值将被按照CacheDirLevels和CacheDirLength指令分解成每一级目录名。
CacheDirLevels指定了子目录的层数,CacheDirLength指定了每级子目录名的字符数。使用上述例子的设置,这个哈希值将被转化成如下文件名前缀:/var/cache/apache/x/y/TGxSMO2b68mBCykqkp1w 。
使用这种技术的总体目标是减少某个特定目录中子目录或文件的个数,因为绝大多的文件系统在子目录或文件数过多的情况下的访问速度都会大打折扣。将CacheDirLength设置为"1"将使得任意一层目录下的子目录数都不会超过64,若为设为"2"则为64*64,依此类推。除非你有一个非常好的理由,否则"1"将是CacheDirLength指令的推荐值。
如何设置CacheDirLevels指令的值取决于你预计到将会在缓冲区中保存多少个文件。上述示例使用的"2"将会导致大约会有4096个子目录最终被建立,大约100万个文件被缓存,大约平均每个文件夹存储245个URL缓冲文件。
每个URL在缓冲区中至少会使用两个文件。通常,一个是包含了URL元信息(meta-information)的".header"文件,比如何时失效;另一个是".data"文件,包含了按字节复制的用于为URL提供服务的内容。
在通过使用"Vary"头进行内容协商的情况下,将会为该URL创建一个".vary"目录,该目录下将会保存多个适合不同协商内容的".data"文件。
维护磁盘缓冲区
虽然mod_disk_cache将会删除缓冲区中失效的文件,但是它并不负责维护整个缓冲区总共究竟应该占据多大空间以及至少要保留多少剩余空间。
作为弥补,Apache附带了一个htcacheclean工具,正如你从它的名字猜到的,它可以周期性的清理缓冲区。确定htcacheclean的运行频率以及缓冲区应当占有多大的磁盘空间是一件复杂的事情。必须要经过多次尝试和碰壁才能找到一个最佳值。
htcacheclean有两种运作模型。一种是作为后台守护进程运行,或者由cron周期性的调用。htcacheclean经常使用一个小时或更多的时间来处理非常巨大的(几十G)缓冲区,所以如果你是使用cron来调用它的话,建议你测试一下多长时间运行一次比较合适,以避免在同一时间运行多个实例。
图1: 一个典型的缓冲区增长和清理的周期因为mod_disk_cache模块自身并不关心究竟实际使用了多少磁盘空间,所以你必须确保htcacheclean被配置为在清理了缓冲区以后预留了足够多的"增长空间"。
文件配置:
<IfModule mod_cache.c> CacheDefaultExpire 3600 CacheMaxExpire 86400 CacheLastModifiedFactor 0.1 <IfModule mod_disk_cache.c> CacheRoot /usr/local/apache/cache CacheEnable disk / CacheDirLevels 5 CacheDirLength 3 CacheMaxFileSize 10000000 CacheMinFileSize 1 </IfModule> </IfModule>
拷贝上面内容到apache 的 httpd.con文件中:
在httpd.conf文件中搜索
#LoadModule cache_module modules/mod_cache.so // 去掉前面的# 号使用磁盘文件缓存:
#LoadModule disk_cache_module modules/mod_disk_cache.so // 去掉前面的# 号参数详细含义如下:
CacheDefaultExpire:
设定缓存过期的时间(秒),默认是1小时,只有当缓存的文档没有设置过期时间或最后修改时间时这个指令才会生效CacheMaxExpire:
失效周期的最大值,缓存实体的默认失效周期是一个小时(3600秒) ,这个默认值仅仅用在产生内容的原始资源没有明确指定失效时间或最后修改时间的情况下。CacheLastModifiedFactor:
在事件的文件中不提供到期时间,指令指定的一个因素是用于生成截止日期。例如,如果该文件的最后修改10小时前, 系数为0.1,那么到期期间将设置为10 * 0.1 = 1小时,如果当前时间是下午3:00,然后计算到期时间为3:00+1小时,也就是下午4:00 ,如果到期时间大于CacheMaxExpire 的时间,那么后者优先级高。CacheRoot:
缓存文件所在的目录,运行 Apache 的用户(如daemon 或 nobody)要能对其进行读写,如果不清楚的话可以直接设置成 777,请手动建立该目录并设置好访问权限CacheEnable:
启用缓存,第1个参数是缓存类弄,这里当然是 disk了,第2个参数是缓存路径,指的是 url 路径,这里是缓存所有的东西,直接写上“/”即可,如“/docs”则只缓存 /docs 下的所有文件CacheDirLevels:
缓存目录的深度,默认是3,这里设置为5CacheDirLength:
缓存目录名的字符长度,默认是4,这里设置为5CacheMaxFileSize 和 CacheMaxFileSize:
缓存文件的最大值和最小值(byte),当超过这个范围时将不再缓存,这里设置为 1M 和 10bytes基于硬盘文件存储的文件基本上就这些内容,设置好后重启 Apache 应该就能使用了。一切正常的话,可以在缓存目录下看到 Apache 自动建立的一些目录和缓存的数据文件。