动态万维网页面的受控缓存
立即解锁
发布时间: 2025-08-23 00:10:16 阅读量: 2 订阅数: 18 

# 动态万维网页面的受控缓存
## 1. 引言
如今,越来越多的网站为了提高灵活性和提供最新信息,开始使用动态内容。然而,这种做法会显著增加服务器负载,因为每个请求都需要执行代码,这可能涉及处理和/或访问信息存储库。本文将介绍一种维护动态生成页面服务器端缓存的方案,该方案能在不增加应用程序开发人员负担的情况下,确保缓存的一致性。
### 1.1 内容分类
万维网服务器提供的内容可分为静态和动态两类:
- **静态内容**:由存储在文件中的 HTML 页面和图像组成。
- **动态内容**:由万维网服务器在收到相关请求时,通过执行服务器端程序或脚本(如 CGI、ASP、JSP 等)创建。这些程序通常会接受请求中包含的一些参数,并从信息存储库(如数据库)中提取数据,以生成要返回给请求者的 HTML 页面。
### 1.2 动态内容的问题
早期,万维网中的动态内容很少,但由于 HTML 页面制定需要更高的灵活性以及提供最新信息的需求,其比例不断增加。不过,动态内容会增加服务器的工作量,因为它需要执行(可能成本较高的)代码片段,同时还会产生额外的开销(如环境设置、内务处理等)。对于访问量较大的服务器来说,这种工作量可能会不堪重负,而用于静态 HTML 页面的技术(如客户端缓存、代理服务器)可能无法有效减少这种工作量,因为这些技术没有考虑到动态内容的特殊性,例如参数的存在以及用于生成页面的数据或程序可能在期间发生变化。
## 2. 相关工作
### 2.1 已有方案概述
目前有多种与动态内容缓存相关的方案:
- **成本模型与预生成页面**:有提出网页视图物化的成本模型,也有讨论网页预生成和信息存储库变更的,但缺乏选择最适合缓存页面的算法。
- **不同缓存方式**:包括主动缓存和服务器加速器等。主动缓存中,服务器提供附加到文档的缓存小程序,在用户“命中”缓存对象时执行,虽能减少网络负载,但 CPU 成本较高;服务器加速器位于 Web 服务器前面,曾用于提高奥运会等网站的性能。
- **商业产品**:如 Cold Fusion 可指定生成不变动态页面的程序,其引擎会缓存并重用这些程序的输出;XCache 可集成到 IIS Web 服务器中,维护动态生成页面的缓存,并提供更新 API 以通知缓存引擎页面过时。
### 2.2 现有方案的不足
现有技术都要求应用程序开发人员进行额外的开发和维护,以适应缓存方案,用于更新传播和一致性管理。此外,失效页面的指定使用专有规范或 API,增加了系统的整体复杂性。而且,大多数实现与特定的 Web 服务器耦合,降低了互操作性和可移植性。
## 3. 维护动态生成页面的缓存
### 3.1 系统架构
可使用如图 1 所示的架构以受控方式维护动态内容的服务器端缓存。该方案在现有网站安装基础上增加了两个软件模块:缓存管理器和更新管理器,负责维护缓存并确保在数据修改时缓存能得到一致更新或失效。新模块作为现有安装的前端,无需影响现有系统,仅更新程序可能需要一些添加。
```mermaid
graph LR
classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;
A(客户端请求):::process --> B(缓存管理器):::process
B --> C{页面是否缓存?}:::process
C -->|是| D(返回缓存页面给客户端):::process
C -->|否| E(向 Web 服务器请求页面):::process
E --> F(Web 服务器生成页面):::process
F --> B
B --> D
B --> G{页面是否可缓存?}:::process
G -->|是| H(将页面存入缓存):::process
G -->|否| I(丢弃页面结果):::process
J(更新管理器):::process --> B
K(无效记录存储库):::process --> J
```
图 1:维护动态内容缓存的架构
### 3.2 缓存管理器的工作流程
#### 3.2.1 初始化
缓存管理器启动时,会读取其配置,该配置基于基于类的动态 Web 内容缓存管理方案。在此方案中,网页根据页面 URL 和客户端信息分组为不同的类。URL 信息包括网络路径、程序名称和参数;客户端信息可补充类的规范,包括 cookie、客户端域名或 IP、浏览器信息(如 HTTP_ACCEPT_ENCODING、HTTP_USER_AGENT)等。
#### 3.2.2 处理请求
初始化后,缓存管理器等待 Web 请求。对于每个请求,它会检查请求的页面是否已缓存。在动态内容的上下文中,页面由 URL、传递给服务器端程序的参数以及与请求所属类相关的任何 cookie 和 HTTP 变量来标识。如果页面在缓存中,将立即返回给客户端;否则,缓存管理器会向 Web 服务器请求该页面,并将结果转发给客户端。为了快速确定目标页面是否存在于缓存中,缓存管理器使用一种算法计算请求 URL 的 MD5 校验和,并将其与缓存页面的校验和进行匹配。
#### 3.2.3 缓存决策
随后,缓存管理器会检查其配置,以确定刚提供的页面是否适合缓存。如果适合,页面将被放入缓存中,以供后续请求使用;如果不适合,返回给客户端的结果将被丢弃。当缓存已满且需要插入新页面时,缓存管理器会使用 Greedy Dual - Size 算法(具体是旨在最大化命中率的变体)来确定要移除的先前缓存页面,因为该算法在 Web 缓存方面表现优于其他算法。
#### 3.2.4 与更新管理器协作
缓存管理器与更新管理器协作,以确保发送给客户端的页面不会因数据或生成页面的服务器端程序的更改而过时。
### 3.3 缓存配置示例
以下是三个类的缓存配置示例:
| URL 类 | 可缓存性 | 服务器 | 说明 |
| --- | --- | --- | --- |
| http://www.example.org/php/comments.php?op=submit | 否 | local - www - srv:80 | 由 comments.php 生成的页面,参数 op 设置为 submit 时,由于执行的副作用,不适合缓存 |
| http://www.example.org/php/search.php | 否 | local - www - srv:80 | 搜索结果由于两个用户使用相同搜索文本的概率较小,不适合缓存 |
| http://www.example.org/php | 是 | local - www - srv:80 | 由 php 目录中的服务器端程序生成的页面可缓存,但页面内容取决于 LANGUAGE cookie 的值 |
## 4. 处理数据和程序变更
### 4.1 更新管理器的职责
由服务器端程序生成并存储在缓存中的页面可能会因底层数据或服务器端程序本身的修改而过时。在这种情况下,需要定位缓存中受影响的页面并将其移除或重新生成。更新管理器负责跟踪更新,它是一个独立的软件模块,可以与缓存管理器在同一台机器上运行,也可以在不同的机器上运行。更新管理器会监控无效记录存储库,以定位描述已过时页面的模式。
### 4.2 无效模式信息
每个无效模式包含以下信息:
1. 生成受影响页面的程序的标识。
2. 必须与服务器端程序的调用数据匹配的参数及其相应值,以使页面被视为无效。
### 4.3 无效模式示例
以下是一些无效模式的示例:
| 路径和参数 | 备注 |
| --- | --- |
| (“http://www.example.org/categories.php”, “catid = 2”) | 由 categories.php 生成的所有页面,参数 catid 等于 2,无论其他参数或 cookie 的值如何 |
| (“http://www.example.org/admin/*”, “”) | 由 admin 目录中的任何程序生成的所有页面,无论参数如何 |
| (“http://www.example.org/index.php”, “__cookie:LANGUAGE = en”) | 由 index.php 生成的所有页面,cookie LANGUAGE 设置为 en |
### 4.4 关键程度指定
每个无效模式都有一个关键程度指定,取值范围为 {hard, soft}。“soft” 表示在服务器负载较高时,可使用页面的过时版本作为对请求客户端的回复;“hard” 表示发送过时页面是不可接受的,相应的缓存页面应立即失效。具有 “soft” 关键程度指定的更新会分配给缓存管理器的低优先级线程,该线程使用空闲 CPU 周期来刷新过时页面。
### 4.5 信息传播与管理优势
一旦更新管理器检测到无效记录存储库中有新的无效条目,它会读取相应的数据并将其传播给缓存管理器,以便执行相应的页面失效或重新生成操作。缓存管理器与更新管理器使用私有协议进行通信,修改数据存储库的应用程序无需了解该协议,只需使用熟悉的编程技术将相应的无效条目插入到无效记录存储库(如数据库表、操作系统文件等)中。使用额外的存储库注册无效模式和引入更新管理器的设计决策,旨在减轻更新应用程序开发人员使用专有 API 的负担,避免他们了解缓存管理器的数量和地址细节,或处理通信错误。此外,使用标准的信息存储库(如数据库)进行失效管理,便于 Web 管理员进行干预,而这些干预在更新应用程序开发时可能无法预见。例如,为了强制使 /categories.php 脚本生成的所有页面失效(例如由于脚本更改),Web 管理员可以使用 SQL 将相应的条目追加到无效记录存储库中:
```sql
insert into cache_invalidations(script_path, params, criticality)
values('http://www.example.org/categories.php', '', 'hard');
```
## 5. 定位缓存中受影响的页面
### 5.1 定位难题
当缓存管理器收到无效通知时,它必须定位所有与脚本路径和参数模式匹配的页面,并根据关键程度指定立即或延迟移除或刷新这些页面。由于本文提出的模型允许在脚本路径中指定参数子集或通配符,因此用于服务客户端请求而存储的 URL 的 MD5 校验和不能用于定位受影响的页面,因为哈希函数只能用于全键搜索。为了避免扫描整个缓存页面表(这会很昂贵),除了主要的 MD5 校验和哈希之外,还使用了以下技术:
### 5.2 定位技术
1. **额外的 MD5 校验和**:为缓存中的每个页面的 URL 程序路径部分计算一个额外的 MD5 校验和,并基于此校验和维护一个哈希结构。当无效条目的脚本路径字段不包含通配符时,该哈希结构用于定位由特定服务器端程序生成的页面。对于这些页面,如果需要,使用标准的子字符串搜索进一步过滤匹配指定参数的页面。
2. **二级 B - 树索引**:在缓存页面的脚本路径字段上构建二级 B - 树索引。当无效条目的脚本路径字段包含通配符时,该索引用于定位受影响的页面。由于维护此索引的成本比维护 MD5 哈希表更高,因此提供了一个管理选项来禁用它,但在这种情况下,脚本路径中的通配符匹配将不受支持。
3. **优化提示**:可以为无效条目附加一个优化提示,指定页面指定是完整的,即包含服务器端程序的所有参数。在这种情况下,可以使用主要的 MD5 校验和哈希算法来定位已过时的单个页面,从而最小化内务处理开销。
## 6. 分离失效与更新应用程序
### 6.1 现有问题
在现有文献中提出的方法中,修改数据存储库的应用程序需要以某种方式通知缓存管理器哪些页面已过时。这对程序员来说是一种负担,并且当数据项与依赖的网页之间的映射发生变化时,会引入另一个应用程序维护源。在这些情况下,所有修改相应数据的程序都需要进行跟踪和更新。
### 6.2 解决方案
本文提出的方法允许利用数据存储库提供的主动功能,以减轻程序员的额外编码和维护负担。许多数据库管理系统(如 Oracle 中的触发器、INGRES 中的规则等)都提供了此类主动功能。这些主动功能可用于在底层数据更改时自动向无效记录存储库添加条目。例如,以下 PL/SQL 代码展示了如何使用触发器实现这一点:
```plsql
create trigger category_invalidations
after insert or delete on stories for each row begin
insert into cache_invalidations (script_path, params, criticality)
values('http://www.example.org/categories.php', 'catid=' || catid, 'hard');
end;
```
通过这种方式,可以更高效地管理动态内容的缓存,减轻服务器负载,同时提高网站的性能和可维护性。
## 7. 架构可扩展性与资源利用
### 7.1 可扩展性考量
在考虑系统架构的可扩展性时,需要关注多个方面。随着网站访问量的增加和动态内容的不断丰富,缓存管理器和更新管理器需要能够应对更高的负载。例如,缓存管理器在处理大量请求时,需要确保能够快速判断页面是否缓存以及是否可缓存,同时在缓存满时能够高效地进行页面替换。更新管理器则需要及时准确地检测到数据和程序的变更,并将相应的无效信息传播给缓存管理器。
### 7.2 资源利用优化
为了优化资源利用,可采取以下措施:
1. **缓存策略优化**:继续使用 Greedy Dual - Size 算法来管理缓存页面的替换,以最大化命中率。同时,可以根据不同页面的访问频率和重要性,动态调整缓存的大小和存储策略。
2. **并行处理**:对于更新管理器和缓存管理器的操作,可以采用并行处理的方式提高效率。例如,更新管理器可以同时处理多个无效条目,缓存管理器可以并行处理多个客户端请求。
3. **资源监控与调整**:实时监控系统的资源使用情况,如 CPU、内存和磁盘 I/O 等。根据监控结果,动态调整缓存管理器和更新管理器的参数,以确保系统在不同负载下都能稳定运行。
## 8. 实验结果
### 8.1 实验设置
为了验证所提出方案的有效性,进行了一系列实验。实验环境包括一台服务器,运行 Web 服务器和缓存管理器、更新管理器等软件模块。模拟了不同的客户端请求模式和数据变更频率,以测试系统在不同场景下的性能。
### 8.2 实验指标
主要关注以下实验指标:
1. **缓存命中率**:表示客户端请求的页面在缓存中找到的比例,反映了缓存的有效性。
2. **服务器响应时间**:从客户端发出请求到收到响应的时间,体现了系统的整体性能。
3. **服务器负载**:通过 CPU 使用率、内存使用率等指标来衡量,评估系统在处理请求时的负担。
### 8.3 实验结果分析
实验结果表明,所提出的方案在缓存命中率和服务器响应时间方面都有显著的改善。与未使用缓存的情况相比,缓存命中率大幅提高,减少了服务器的重复计算和数据访问,从而降低了服务器负载。同时,服务器响应时间也明显缩短,提高了用户体验。在不同的请求模式和数据变更频率下,系统都能保持较好的性能,证明了方案的鲁棒性。
| 实验指标 | 未使用缓存 | 使用本文方案 |
| --- | --- | --- |
| 缓存命中率 | 低 | 高 |
| 服务器响应时间 | 长 | 短 |
| 服务器负载 | 高 | 低 |
## 9. 总结与未来工作
### 9.1 方案总结
本文提出了一种维护动态生成页面服务器端缓存的方案,通过引入缓存管理器和更新管理器,有效地减轻了服务器负载,同时确保了缓存的一致性。该方案具有以下优点:
1. **对现有系统影响小**:新模块作为现有网站安装的前端,无需对现有系统进行大规模修改,仅更新程序可能需要少量添加。
2. **减轻开发人员负担**:使用标准的信息存储库和私有协议,避免了应用程序开发人员使用专有 API 和处理复杂的通信问题。
3. **良好的可扩展性和性能**:通过优化缓存策略和资源利用,系统能够应对不同的负载和数据变更,提高了网站的性能和可维护性。
### 9.2 未来工作展望
虽然本文提出的方案取得了较好的效果,但仍有一些方面可以进一步改进和研究:
1. **更智能的缓存策略**:结合机器学习算法,根据页面的历史访问模式、数据变更频率等因素,动态调整缓存策略,以提高缓存命中率。
2. **分布式缓存系统**:随着网站规模的不断扩大,考虑构建分布式缓存系统,将缓存分布在多个服务器上,以提高系统的可扩展性和容错性。
3. **与其他技术的集成**:探索与其他 Web 技术(如内容分发网络、负载均衡器等)的集成,进一步优化网站的性能和用户体验。
```mermaid
graph LR
classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;
A(当前方案):::process --> B(更智能的缓存策略):::process
A --> C(分布式缓存系统):::process
A --> D(与其他技术集成):::process
B --> E(提高缓存命中率):::process
C --> F(增强可扩展性和容错性):::process
D --> G(优化性能和用户体验):::process
```
图 2:未来工作方向
通过不断的研究和改进,有望进一步提升动态内容缓存系统的性能和功能,为用户提供更高效、更稳定的 Web 服务。
0
0
复制全文
相关推荐







