《Squid 中文权威指南》第7章 译者:彭勇华
译者序:
本人在工作中维护着数台Squid 服务器,多次参阅Duane Wessels(他也是Squid 的创始人)的这本书,原书名是"Squid: The Definitive Guide",由O'Reilly 出版。我在业余时间把它翻译成中文,希望对中文Squid 用户有所帮助。对普通的单位上网用户,Squid 可充当代理服务器;而对Sina,NetEase 这样的大型站点,Squid 又充当WEB 加速器。这两个角色它都扮演得异常优秀。窗外繁星点点,开源的世界亦如这星空般美丽,而Squid 是其中耀眼的一颗星。
对本译版有任何问题,请跟我联系,我的Email是:yonghua_peng@yahoo.com.cn 彭勇华[/color]
--------------------------------------------------------------------------------------
7.磁盘缓存基础
7.1 cache_dir指令
cache_dir指令是squid.conf配置文件里最重要的指令之一。它告诉squid以何种方式存储cache文件到磁盘的什么位置。cache_dir指令取如下参数:
cache_dir scheme directory size L1 L2 [options]
7.1.1 参数:Scheme
Squid支持许多不同的存储机制。默认的(原始的)是ufs。依赖于操作系统的不同,你可以选择不同的存储机制。在./configure时,你必须使用--enable-storeio=LIST选项来编译其他存储机制的附加代码。我将在8.7章讨论aufs,diskd,coss和null。现在,我仅仅讨论ufs机制,它与aufs和diskd一致。
7.1.2 参数:Directory
该参数是文件系统目录,squid将cache对象文件存放在这个目录下。正常的,cache_dir使用整个文件系统或磁盘分区。它通常不介意是否在单个文件系统分区里放置了多个cache目录。然而,我推荐在每个物理磁盘中,仅仅设置一个cache目录。例如,假如你有2个无用磁盘,你可以这样做:
# newfs /dev/da1d
# newfs /dev/da2d
# mount /dev/da1d /cache0
# mount /dev/da2d /cache1
然后在squid.conf里增加如下行:
cache_dir ufs /cache0 7000 16 256
cache_dir ufs /cache1 7000 16 256
假如你没有空闲硬盘,当然你也能使用已经存在的文件系统分区。选择有大量空闲空间的分区,例如/usr或/var,然后在下面创建一个新目录。例如:
# mkdir /var/squidcache
然后在squid.conf里增加如下一行:
cache_dir ufs /var/squidcache 7000 16 256
7.1.3 参数:Size
该参数指定了cache目录的大小。这是squid能使用的cache_dir目录的空间上限。计算出合理的值也许有点难。你必须给临时文件和swap.state日志,留出足够的自由空间(见13.6章)。我推荐挂载空文件系统,可以运行df:
% df -k
Filesystem 1K-blocks Used Avail Capacity Mounted on
/dev/da1d 3037766 8 2794737 0% /cache0
/dev/da2d 3037766 8 2794737 0% /cache1
这里你可以看到文件系统有大约2790M的可用空间。记住,UFS保留了部分最小自由空间,这里约是8%,这就是squid为什么不能使用全部3040M空间的原因。
你也许试图分配2790M给cache_dir。如果cache不很繁忙,并且你经常轮转日志,那么这样做也许可行。然而,为安全起见,我推荐保留10%的空间。这些额外的空间用于存放squid的swap.state文件和临时文件。
注意cache_swap_low指令也影响了squid使用多少空间。我将在7.2章里讨论它的上限和下限。
底线是,你在初始时应保守的估计cache_dir的大小。将cache_dir设为较小的值,并允许写满cache。在squid运行一段时间后,cache目录会填满,这样你可以重新评估cache_dir的大小设置。假如你有大量的自由空间,就可以轻松的增加cache目录的大小了。
7.1.3.1 Inodes
Inodes(i节点)是unix文件系统的基本结构。它们包含磁盘文件的信息,例如许可,属主,大小,和时间戳。假如你的文件系统运行超出了i节点限制,就不能创造新文件,即使还有空间可用。超出i节点的系统运行非常糟糕,所以在运行squid之前,你应该确认有足够的i节点。
创建新文件系统的程序(例如,newfs或mkfs)基于总空间的大小,保留了一定数量的i节点。这些程序通常允许你设置磁盘空间的i节点比率。例如,请阅读newfs和mkfs手册的-i选项。磁盘空间对i节点的比率,决定了文件系统能实际支持的文件大小。大部分unix系统每4KB创建一个i节点,这对squid通常是足够的。研究显示,对大部分cache代理,实际文件大小大约是10KB。你也许能以每i节点8KB开始,但这有风险。
你能使用df -i命令来监视系统的i节点,例如:
% df -ik
Filesystem 1K-blocks Used Avail Capacity iused ifree %iused Mounted on
/dev/ad0s1a 197951 57114 125001 31% 1413 52345 3% /
/dev/ad0s1f 5004533 2352120 2252051 51% 129175 1084263 11% /usr
/dev/ad0s1e 396895 6786 358358 2% 205 99633 0% /var
/dev/da0d 8533292 7222148 628481 92% 430894 539184 44% /cache1
/dev/da1d 8533292 7181645 668984 91% 430272 539806 44% /cache2
/dev/da2d 8533292 7198600 652029 92% 434726 535352 45% /cache3
/dev/da3d 8533292 7208948 641681 92% 427866 542212 44% /cache4
如果i节点的使用(%iused)少于空间使用(Capacity),那就很好。不幸的是,你不能对已经存在的文件系统增加更多i节点。假如你发现运行超出了i节点,那就必须停止squid,并且重新创建文件系统。假如你不愿意这样做,那么请削减cache_dir的大小。
7.1.3.2 在磁盘空间和进程大小之间的联系
Squid的磁盘空间使用也直接影响了它的内存使用。每个在磁盘中存在的对象,要求少量的内存。squid使用内存来索引磁盘数据。假如你增加了新的cache目录,或者增加了磁盘cache大小,请确认你已有足够的自由内存。假如squid的进程大小达到或超过了系统的物理内存容量,squid的性能下降得非常块。
Squid的cache目录里的每个对象消耗76或112字节的内存,这依赖于你的系统。内存以StoreEntry, MD5 Digest, 和LRU policy node结构来分配。小指令(例如,32位)系统,象那些基于Intel Pentium的,取76字节。使用64位指令CPU的系统,每个目标取112字节。通过阅读cache管理的内存管理文档,你能发现这些结构在你的系统中耗费多少内存(请见14.2.1.2章)。
不幸的是,难以精确预测对于给定数量的磁盘空间,需要使用多少附加内存。它依赖于实际响应大小,而这个大小基于时间波动。另外,Squid还为其他数据结构和目的分配内存。不要假设你的估计正确。你该经常监视squid的进程大小,假如必要,考虑削减cache大小。
7.1.4 参数:L1和L2
对ufs,aufs,和diskd机制,squid在cache目录下创建二级目录树。L1和L2参数指定了第一级和第二级目录的数量。默认的是16和256。图7-1显示文件系统结构。
Figure 7-1. 基于ufs存储机制的cache目录结构
(略图)
某些人认为squid依赖于L1和L2的特殊值,会执行得更好或更差。这点听起来有关系,即小目录比大目录被检索得更快。这样,L1和L2也许该足够大,以便L2目录的文件更少。
例如,假设你的cache目录存储了7000M,假设实际文件大小是10KB,你能在这个cache_dir里存储700,000个文件。使用16个L1和256个L2目录,总共有4096个二级目录。700,000/4096的结果是,每个二级目录大约有170个文件。
如果L1和L2的值比较小,那么使用squid -z创建交换目录的过程,会执行更快。这样,假如你的cache文件确实小,你也许该减少L1和L2目录的数量。
Squid给每个cache目标分配一个唯一的文件号。这是个32位的整数,它唯一标明磁盘中的文件。squid使用相对简单的算法,将文件号转换位路径名。该算法使用L1和L2作为参数。这样,假如你改变了L1和L2,你改变了从文件号到路径名的映射关系。对非空的cache_dir改变这些参数,导致存在的文件不可访问。在cache目录激活后,你永不要改变L1和L2值。
Squid在cache目录顺序中分配文件号。文件号到路径名的算法(例如,storeUfsDirFullPath( )),用以将每组L2文件映射到同样的二级目录。Squid使用了参考位置来做到这点。该算法让HTML文件和它内嵌的图片更可能的保存在同一个二级目录中。某些人希望squid均匀的将cache文件放在每个二级目录中。然而,当cache初始写入时,你可以发现仅仅开头的少数目录包含了一些文件,例如:
% cd /cache0; du -k
2164 ./00/00
2146 ./00/01
2689 ./00/02
1974 ./00/03
2201 ./00/04
2463 ./00/05
2724 ./00/06
3174 ./00/07
1144 ./00/08
1 ./00/09
1 ./00/0A
1 ./00/0B
这是完全正常的,不必担心。
7.1.5 参数:Options
Squid有2个依赖于不同存储机制的cache_dir选项:read-only标签和max-size值。
7.1.5.1 read-only
read-only选项指示Squid继续从cache_dir读取文件,但不往里面写新目标。它在squid.conf文件里看起来如下:
cache_dir ufs /cache0 7000 16 256 read-only
假如你想把cache文件从一个磁盘迁移到另一个磁盘,那么可使用该选项。如果你简单的增加一个cache_dir,并且删除另一个,squid的命中率会显著下降。在旧目录是read-only时,你仍能从那里获取cache命中。在一段时间后,就可以从配置文件里删除read-only缓存目录。
7.1.5.2 max-size
使用该选项,你可以指定存储在cache目录里的最大目标大小。例如:
cache_dir ufs /cache0 7000 16 256 max-size=1048576
注意值是以字节为单位的。在大多数情况下,你不必增加该选项。假如你做了,请尽力将所有cache_dir行以max-size大小顺序来存放(从小到大)。
7.2 磁盘空间基准
cache_swap_low和cache_swap_high指令控制了存储在磁盘上的对象的置换。它们的值是最大cache体积的百分比,这个最大cache体积来自于所有cache_dir大小的总和。例如:
cache_swap_low 90
cache_swap_high 95
如果总共磁盘使用低于cache_swap_low,squid不会删除cache目标。如果cache体积增加,squid会逐渐删除目标。在稳定状态下,你发现磁盘使用总是相对接近cache_swap_low值。你可以通过请求cache管理器的storedir页面来查看当前磁盘使用状况(见14.2.1.39章)。
请注意,改变cache_swap_high也许不会对squid的磁盘使用有太大效果。在squid的早期版本里,该参数有重要作用;然而现在,它不是这样了。
7.3 对象大小限制
你可以控制缓存对象的最大和最小体积。比maximum_object_size更大的响应不会被缓存在磁盘。然而,它们仍然是代理方式的。在该指令后的逻辑是,你不想某个非常大的响应来浪费空间,这些空间能被许多小响应更好的利用。该语法如下:
maximum_object_size size-specification
如下是一些示例:
maximum_object_size 100 KB
maximum_object_size 1 MB
maximum_object_size 12382 bytes
maximum_object_size 2 GB
Squid以两个不同的方法来检查响应大小。假如响应包含了Content-Length头部,squid将这个值与maximum_object_size值进行比较。假如前者大于后者,该对象立刻不可缓存,并且不会消耗任何磁盘空间。
不幸的是,并非每个响应都有Content-Length头部。在这样的情形下,squid将响应写往磁盘,把它当作来自原始服务器的数据。在响应完成后,squid再检查对象大小。这样,假如对象的大小达到 maximum_object_size限制,它继续消耗磁盘空间。仅仅当squid在做读取响应的动作时,总共cache大小才会增大。
换句话说,活动的,或者传输中的目标,不会对squid内在的cache大小值有影响。这点有好处,因为它意味着squid不会删除cache里的其他目标,除非目标不可缓存,并对总共cache大小有影响。然而,这点也有坏处,假如响应非常大,squid可能运行超出了磁盘自由空间。为了减少发生这种情况的机会,你应该使用reply_body_max_size指令。某个达到reply_body_max_size限制的响应立即被删除。
Squid也有一个minimum_object_size指令。它允许你对缓存对象的大小设置最低限制。比这个值更小的响应不会被缓存在磁盘或内存里。注意这个大小是与响应的内容长度(例如,响应body大小)进行比较,后者包含在HTTP头部里。
7.4 分配对象到缓存目录
当squid想将某个可缓存的响应存储到磁盘时,它调用一个函数,用以选择cache目录。然后它在选择的目录里打开一个磁盘文件用于写。假如因为某些理由,open()调用失败,响应不会被存储。在这样的情况下,squid不会试图在其他cache目录里打开另一个磁盘文件。
Squid有2个cache_dir选择算法。默认的算法叫做lease-load;替代的算法是round-robin。
least-load算法,就如其名字的意义一样,它选择当前工作负载最小的cache目录。负载概念依赖于存储机制。对aufs,coss和diskd机制来说,负载与挂起操作的数量有关。对ufs来说,负载是不变的。在cache_dir负载相等的情况下,该算法使用自由空间和最大目标大小作为附加选择条件。
该选择算法也取决于max-size和read-only选项。假如squid知道目标大小超出了限制,它会跳过这个cache目录。它也会跳过任何只读目录。
round-robin算法也使用负载作为衡量标准。它选择某个负载小于100%的cache目录,当然,该目录里的存储目标没有超出大小限制,并且不是只读的。
在某些情况下,squid可能选择cache目录失败。假如所有的cache_dir是满负载,或者所有目录的实际目标大小超出了max-size限制,那么这种情况可能发生。这时,squid不会将目标写往磁盘。你可以使用cache管理器来跟踪squid选择cache目录失败的次数。请见store_io页(14.2.1.41章),找到create.select_fail行。












文章评论
共有 0 位网友发表了评论 此处只显示部分留言 点击查看完整评论页面