Web缓存,第 1 部分

作者:David Guerrero

网络无处不在。每个人都在使用它。每个人都在谈论它。但是在这个并不完美的世界中,您知道存在问题。带宽是一个问题。Web 文档延迟(文档到达您的浏览器所需的时间,从其 URL 被请求时算起)是一个问题。随着您使用的带宽空间增加,从互联网检索文档的延迟也会增加。带宽很昂贵,可能是互联网连接中最昂贵的要素。

尽管网络发展迅速,但相同的文档会被反复请求,相同的网站会被重复访问。我们可以利用这一点来避免下载冗余对象。您会惊讶地发现有多少用户阅读 NBA.COM 网页,或者来自 AltaVista 的 GIF 图片跨越您的线路多少次。

即使您对 Web 缓存一无所知,您可能也在您的 Web 浏览器中使用它。大多数常见的浏览器都对您从 Web 检索的文档和对象使用这种方法,将最近文档的副本保存在内存或磁盘中。每次您单击“后退”按钮或访问同一页面时,该页面都在内存中,无需重新检索。这是第一级缓存,该技术可以扩展到整个 Web。

缓存背后的基本思想是将一个用户检索的文档存储在公共位置,从而避免为第二个用户从其源检索相同的文档。相反,第二个用户从公共位置获取文档。当您处理欧洲的组织时,这一点非常重要,因为欧洲的大部分入境流量来自大西洋彼岸,通常通过慢速链路。

这种方法的主要好处是,您用户的浏览现在是协作式的,并且用户检索的大量文档在很短的时间内得到服务。在一个中等规模的组织(拥有 50 到 100 个用户)中,您可以从本地缓存中提供高达 60% 的 URL 请求。

浏览器缓存和代理缓存服务器之间的区别在于,浏览器缓存仅适用于一个用户,并且位于最终用户工作站中,而代理缓存服务器是一个程序,它代表多个 Web 浏览器客户端工作,允许一个客户端读取其他人先前请求的文档。此代理缓存服务器位于公共服务器中,该服务器通常位于本地网络和互联网之间。所有浏览器都从代理服务器请求文档,代理服务器检索文档并将其返回给浏览器。这是组织中的第二级缓存。图 1 显示了这种类型的网络配置。

Caching the Web, Part 1

图 1. 代理缓存服务器网络配置

代理缓存不仅是解决带宽危机的方案;当需要网络防火墙来保证您组织的安全时,它也是理想的。在这种情况下,代理缓存位于所有本地浏览器都可以访问的计算机上,但同时将它们与互联网隔离。这台计算机必须有两个网络接口,分别连接到内部和外部网络,并且必须是唯一可以从互联网访问的计算机。图 2 说明了这种配置。代理缓存服务器必须只能由内部系统访问,以确保互联网上的任何人都无法通过从代理缓存请求您的内部文档来访问它们。我将在本文后面讨论对代理缓存的访问控制。

Caching the Web, Part 1

图 2. 带有防火墙的代理缓存网络配置

多级 Web 缓存

从这种方法向前迈进一步是缓存层级的概念,其中两个或多个代理缓存服务器通过相互提供文档来协作。代理缓存可以在层级结构中扮演两种不同的角色,具体取决于网络拓扑、ISP 策略和系统资源。邻居(或兄弟)缓存是指仅提供其已有的文档的缓存。父缓存可以从层级结构中更高的另一个缓存或从源获取文档,具体取决于在其级别中是否有更多父缓存或邻居缓存。当没有更多机会从同一级别的缓存获取文档时,应使用父缓存。

选择良好的缓存拓扑对于避免产生比没有 Web 缓存更多的网络流量非常重要。一个组织可以选择在其部门网络中拥有多个兄弟缓存,并在靠近互联网网络链路的地方拥有一个父缓存。可以将此父缓存配置为从上游 ISP 中的另一个父缓存请求文档,以防他们拥有一个(大多数都有)。组织和 ISP 之间可以达成协议,以构建兄弟或父缓存,以减少其链路中的流量过载,或通过与常规 IP 流量不同的路径路由 Web 流量。Web 缓存可以被视为应用层路由机制,它使用 ICP(互联网缓存协议)作为其主要协议。图 3 是一个组织如何实施多级 Web 缓存的示例。

Caching the Web, Part 1

图 3. 多级 Web 缓存组织

什么是 ICP?

ICP,互联网缓存协议,是用于在 Web 缓存之间通信的协议。ICP 是一种构建在 UDP 之上的轻量级协议,用于在相邻缓存中定位特定的 Web 对象。缓存之间的大多数对象传输都是使用基于 TCP 的 HTTP 协议完成的,但决定从何处检索对象必须使用更简单、更快速的机制来完成。需要的其他信息是哪些缓存已关闭或链路拥塞。

一个缓存为了找到下载对象的最佳位置,会向其所有兄弟缓存和父缓存发送一个 ICP 请求数据包,它们会发回带有 HIT 或 MISS 代码的 ICP 回复。HIT 代码表示此缓存具有该对象并同意提供它。MISS 代码表示它没有该对象。因此,缓存现在知道谁拥有它需要的对象,并且将此信息与诸如每个响应的往返时间等其他因素相结合,可以执行缓存选择并通过 HTTP 向其选择发出请求。如果所有缓存都回复 MISS 数据包,则它会从其父缓存请求文档。ICP 请求/回复交换应在一两秒内发生,因此延迟会增加浏览器的这次时间,但这通常不会被最终用户注意到。

如果通过 ICP 请求的对象足够小,则可以将其包含在 ICP HIT 回复中,就像 HTTP 重定向一样,但这不是很常见的情况。当然,ICP 仅在具有多个兄弟缓存和父缓存的多级缓存环境中才需要。在如图 1 和图 2 所示的情况下,不需要使用 ICP。当仅涉及一个缓存,或者当一个缓存始终从同一更高级别的缓存请求文档时,ICP 只会增加不必要的开销。

缓存还是不缓存?

在这一点上,我们必须意识到并非 Web 中的所有对象都是可缓存的。大多数 FTP 文件是,以及大多数静态网页也是,但大量 CGI 生成的网页(动态文档)不是。这种文档是不可缓存的,因为它每次请求时都不同。这种对象的两个很好的例子是访问计数器和实时数据库查询。缓存航班预订系统的回复是毫无意义的,因为下一个查询很可能返回更最新的值。其他不应缓存的文档类型包括 SSL 文档(安全传输的文档)。

好的,缓存,但是缓存多久?

即使您没有代理缓存服务器,您也必须意识到其他代理缓存服务器正在对互联网造成的影响。您可能正在您的 Web 服务器上发布信息,其他缓存正在存储和提供这些信息的时间可能比您希望的时间更长。如果您定期更新您的站点,并且对您来说,最终用户永远不会获得过时的页面或图形非常重要,则尤其如此。

缓存服务器中的文档可以有三种不同的状态:新鲜 (FRESH)、正常 (NORMAL) 和陈旧 (STALE)。当对象处于新鲜状态时,当收到对其的请求时,会正常提供它,而无需检查源以查看自上次检索以来对象是否已被修改。如果它处于正常状态,则会向源发送一个 If-Modified-Since GET 请求,因此仅当自上次检索以来对象已更改时,缓存服务器才会从源下载该对象。陈旧文档不再有效,需要再次从源检索。

通常,当 Web 服务器发送文档时,它会添加一个名为 Last-Modified 的 HTTP 标头,其中包含对象创建或上次修改的日期。缓存服务器使用此数据来启发式地计算对象在仍然被视为新鲜状态的情况下可能经过多长时间。通常,使用文档上次修改日期和文档接收日期之间经过的时间的比例。正常的比例是这段时间的 10% 到 30%。如果此比例设置为 20%,则修改于 10 天前的文档将在缓存中保留两天,然后才检查更改。

经常更新其信息的网站管理员需要更多地控制其文档在 Web 缓存中保持未检查状态的时间。在这种情况下,您的服务器提供的文档中的 Expires HTTP 标头可用于指示任何缓存服务器何时必须删除此文档。此标头显式地为缓存提供了文档的到期日期。此标头应使用有效的 RFC1123 时间格式,例如

Expires: Mon, 25 Aug 1997 10:00:00 GMT

可以在 CGI 脚本或 Apache 1.2 中包含的 mod_expires 模块中轻松生成此标头。例如,以下 Apache 指令(在 <Directory> </Directory> 或 .htaccess 中)可以做到这一点

ExpiresActive On
ExpiresByType image/gif A432000
ExpiresByType image/jpeg A432000
ExpiresByType text/html A10800
Expires 标头为所有后续文档激活,JPEG 和 GIF 图像的值为五天,HTML 文档的值为三小时。

如果您有任何服务器或浏览器中永远不应缓存的文档,请使用名为

Pragma: no-cache

当然,缓存可能会更早地过期对象,这取决于站点配置、可用磁盘空间不足、LRU(最近最少使用)策略等,但它永远不会将对象缓存超过其 Expires 时间。

下个月,我们将讨论 Squid,构建代理缓存服务器的最佳免费软件解决方案。

资源

Caching the Web, Part 1
David Guerrero 是西班牙教育和文化部的系统和网络管理员,也是一名独立顾问。自 .98plNN 时代以来,他一直在使用 Linux。不工作时,他喜欢与他的爱人 Yolanda 共度时光,旅行,弹吉他和合成器,或与他的“colegas”外出。可以通过 david@boe.es 与他联系。
加载 Disqus 评论