缓存详情

可缓存性

并非所有 HTTP 响应都可以被缓存。Cloud CDN 只缓存那些满足本部分所列全部要求的响应。其中一些要求在 RFC 7234 中进行了规定,而其他要求则专门针对 Cloud CDN。

只有满足以下所有条件时,您才能将响应存储在 Cloud CDN 缓存中:

  • 该响应由启用了 Cloud CDN 的后端服务或后端存储分区提供。
  • 该响应是对 GET 请求作出的响应。
  • 该响应的状态代码是 200203206300301302307410
  • 该响应具有 Cache-Control: public 标头。
  • 该响应具有 Cache-Control: s-maxageCache-Control: max-ageExpires 标头。
  • 该响应具有 Content-LengthContent-RangeTransfer-Encoding 标头。
  • 该响应的大小小于或等于大小上限

对于后端存储分区,您可以通过以下几种方法来满足这些要求:

此外,某些检查会禁止系统缓存响应。如果存在以下任一情况,则响应不会被缓存:

  • 该响应具有 Set-Cookie 标头。
  • 该响应具有 Vary 标头,该标头的值不是 AcceptAccept-EncodingOrigin
  • 该响应具有 Cache-Control: no-storeno-cacheprivate 指令。
  • 对应的请求具有 Cache-Control: no-store 指令。

未来这些要求可能会放宽,从而允许 Cloud CDN 缓存更多响应。

请注意,如果存在 Cache-Control: no-storeno-cacheprivate,但由于系统已配置网址签名,因此内容仍会被缓存。如需了解如何防止响应被缓存,请参阅防止缓存部分。

大小上限

Cloud CDN 强制执行大小上限,具体取决于源服务器是否支持字节范围请求

  • 如果源服务器支持字节范围请求,则为 5 TB(5,497,558,138,880 字节)
  • 如果源服务器不支持字节范围请求,则为 10 MB(10,485,760 字节)

不会缓存任何正文大于大小上限的响应。

缓存条目

缓存键

Cloud CDN 缓存中的每个缓存条目由缓存键进行标识。当请求进入缓存时,缓存会将请求的 URI 转换为缓存键,然后将该键与缓存条目的键进行比较。如果找到匹配的键,缓存将返回与该键关联的对象。

对于后端服务,Cloud CDN 默认使用完整请求 URI 作为缓存键。例如,https://example.com/images/cat.jpgcat.jpg 对象的特定请求的完整 URI。该字符串用作默认缓存键。只有确切包含该字符串的请求才会匹配。http://example.com/images/cat.jpghttps://example.com/images/cat.jpg?user=user1 的请求不匹配。

您可以更改将 URI 中的哪些部分用在缓存键中。文件路径和文件名必须始终包含在缓存键中,除此之外,在自定义缓存键时,您可以包含或省略协议、主机或查询字符串中的一项或多项。使用缓存键介绍了如何自定义缓存键。

  • 协议:您可以从缓存键中省略协议。如果您省略协议,则 https://example.com/images/cat.jpg 的请求会接收 example.com/images/cat.jpg 的缓存键。之后,https://example.com/images/cat.jpghttp://example.com/images/cat.jpg 的请求都将被视为与该缓存条目匹配。
  • 主机:您可以从缓存键中省略主机。如果您省略主机,则 example.comexample2.com 的请求均可以匹配相同的缓存条目。如果首先传入 https://example.com/images/cat.jpg 的请求,然后传入 https://example2.com/images/cat.jpg 的请求,则会导致第二个请求出现缓存命中。
  • 查询字符串:您可以从缓存键中省略查询字符串。如果您省略了查询字符串,则 https://example.com/images/cat.jpg?user=user1 的请求会接收 https://example.com/images/cat.jpg 的缓存键,因此,https://example.com/images/cat.jpg?user=user1https://example.com/images/cat.jpg?user=user2 均可以匹配相同的条目。您还可以选择性地省略或包含部分查询字符串。

除了包含或省略整个查询字符串之外,您还可以选择通过白名单和黑名单使用查询字符串的一个或多个部分。

对于后端存储分区,缓存键由不带查询字符串的 URI 组成,因此 https://example.com/images/cat.jpghttps://example.com/images/cat.jpg?user=user1https://example.com/images/cat.jpg?user=user2 是等效的。

查询字符串白名单

您可以选择性地控制 Cloud CDN 将哪些查询字符串参数包含到缓存键中。例如,如果您创建了 user 的白名单,则 https://example.com/images/cat.jpg?user=user1&color=blue 会创建 https://example.com/images/cat.jpg?user=user1 的缓存键,该缓存键也与 https://example.com/images/cat.jpg?user=user1&color=red 匹配。要使用此选项,您必须添加查询字符串、指定非空白名单,并且不指定黑名单。

查询字符串黑名单

您可以通过黑名单选择性地控制 Cloud CDN 将忽略哪些查询字符串参数。例如,如果您创建了 user 的黑名单,则缓存键中将使用除 user 之外的所有查询字符串参数。

在配置上述黑名单并输入 https://example.com/images/cat.jpg?user=user1&color=blue 之后,Cloud CDN 会创建 https://example.com/images/cat.jpg?color=blue 的缓存键,该缓存键也与 https://example.com/images/cat.jpg?user=user2&color=blue(而非 https://example.com/images/cat.jpg?user=user1&color=red)匹配。要使用此选项,您必须添加查询字符串、指定非空黑名单,并且不指定白名单。

Vary 标头

除了请求 URI 之外,Cloud CDN 还会遵循源服务器在响应中加入的任何 Vary 标头。Vary 标头表示,响应根据客户端的请求标头发生变化。例如,如果响应指定了 Vary: Accept,Cloud CDN 将为指定了 Accept: image/webp,image/*,*/*;q=0.8 的请求使用一个缓存条目,并为指定了 Accept: */* 的请求使用另一个缓存条目。

在传送压缩内容时,有时会使用 Vary 标头。Cloud CDN 本身不压缩或解压缩响应,但它可以传送由源服务器压缩的响应。如果您的源服务器根据 Accept-Encoding 请求标头的值来选择是否传送压缩或未压缩的内容,请确保响应指定 Vary: Accept-Encoding

仅当 Vary 标头包含可缓存性中列出的某个值时,系统才会缓存含有该标头的响应。

过期时间和验证请求

Cloud CDN 缓存中每个缓存条目的到期时间都是依据 RFC 7234Cache-Control: s-maxageCache-Control: max-age 和/或 Expires 标头定义的。如果存在多个标头,则 Cache-Control: s-maxage 优先于 Cache-Control: max-ageCache-Control: max-age 优先于 Expires

Cloud CDN 收到请求时,它会查询相应的缓存条目并检查该条目的存在时间。如果该缓存条目存在且足以满足最新要求,则可以从缓存中传送响应。但是,如果当前时间晚于过期时间,则 Cloud CDN 无法在未事先联系您后端的情况下传送响应。

如果先前缓存的响应具有 Last-Modified 和/或 ETag 标头,则 Cloud CDN 可以尝试使用这些标头中的信息来验证具有后端的缓存条目。Cloud CDN 执行此验证的方式略有不同,具体取决于响应是否使用字节范围请求进行缓存:

  • 如果使用字节范围请求缓存响应,则 Cloud CDN 会启动单独的验证请求,其中包括 If-Modified-Since 和/或 If-None-Match 标头。
  • 否则,Cloud CDN 会将 If-Modified-Since 和/或 If-None-Match 标头添加到客户端请求,并将修改后的请求转发给后端。

如果缓存副本仍处于最新状态,后端可以通过发送 304 Not Modified 响应来验证现有缓存条目。在这种情况下,后端只发送响应标头,而不发送响应正文。Cloud CDN 将新的响应标头插入缓存,更新过期时间,并将新的响应标头和缓存的响应正文传送到客户端。

如果先前缓存的响应没有 Last-ModifiedETag 标头,则 Cloud CDN 会忽略过期的缓存条目,并将客户端请求转发给未经修改的后端。

请注意,缓存条目的过期时间代表了一个上限,它决定了缓存条目保持有效的时长。我们无法保证缓存条目在过期之前一直保留在缓存中。您可以逐出非热门内容的缓存条目,以便为新内容腾出空间。无论指定的过期时间是多久,系统都将自动移除 30 天内未被访问的缓存条目。

如需了解详情,请参阅驱逐和到期

为字节范围请求提供的支持

如果响应满足以下条件,则表明源服务器支持字节范围请求:

  • 该响应的状态代码是 200 OK206 Partial Content
  • 该响应具有 Accept-Ranges: bytes 标头。
  • 该响应具有 Content-Length 和/或 Content-Range 标头。
  • 该响应具有 ETag 标头(带有强验证器)和/或 Last-Modified 标头。

Google Cloud Storage 支持大多数对象的字节范围请求。但是,除非客户端请求包含 Accept-Encoding: gzip 标头,否则 Cloud Storage 不支持带有 Content-Encoding: gzip 元数据的对象的字节范围请求。如果您的 Cloud Storage 对象大小超过 10 MB,请确保它们没有 Content-Encoding: gzip 元数据。如需了解如何修改对象元数据,请参阅查看和修改对象元数据

常见的网络服务器软件也支持字节范围请求。如需详细了解如何启用支持功能,请参阅网络服务器软件的文档。如需详细了解字节范围请求,请参阅 HTTP 规范

当源服务器支持字节范围请求时,如果满足以下任一条件,则 Cloud CDN 缓存会在第一次收到请求时拒绝存储其他情况下允许缓存的响应:

  • 响应正文不完整,因为客户端只请求了部分内容
  • 响应正文的大小大于1 MB(1,048,576 字节)。

如果发生这种情况,并且响应在其他情况下可以满足正常的可缓存性要求,缓存会记录源服务器支持该缓存键的字节范围请求,并将源服务器的响应转发给客户端。

在缓存未命中时,缓存会检查是否已知源服务器支持字节范围请求。如果已知该缓存键支持字节范围请求,则缓存不会将客户端请求转发到 HTTP(S) 负载平衡器。实际上,缓存将为内容的缺失部分发起自己的字节范围缓存填充请求。如果源服务器在 206 Partial Content 响应中返回请求的字节范围,则缓存可以存储该范围,以便用于未来的请求。

只有当收到的 206 Partial Content 响应是对缓存发起的字节范围请求作出的响应时,缓存才会存储该响应。除非先前有记录表明源服务器支持该缓存键的字节范围请求,否则缓存不会发起字节范围请求,因此,对于大于 1 MB 的内容,只有在该内容被第二次访问之后,给定的缓存才会存储该内容。

Cloud CDN 发起的请求

当您的源服务器支字节范围请求时,Cloud CDN 可以将多个请求发送到您的源服务器,以便响应单个客户端请求。如下所述,Cloud CDN 可以发起两种请求:验证请求和字节范围请求。

如果某个响应表明源服务器支持特定缓存键的字节范围请求,且该响应已过期,则 Cloud CDN 会发起验证请求以确认内容未被更改,并且您的源服务器仍然支持该内容的范围请求。如果您的源服务器给出了 304 Not Modified 响应,则 Cloud CDN 将继续使用字节范围传送内容。否则,Cloud CDN 会将源服务器的响应转发到客户端。您可以使用 Cache-Control 和 Expires 响应标头控制过期时间。

在缓存未命中时,Cloud CDN 会为与客户端请求重叠的一组字节范围发起缓存填充请求。如果客户端所请求内容的某些范围包含在缓存中,而其他范围不在缓存中,则 Cloud CDN 将从缓存传送尽可能多的内容,并且仅将缺失范围的字节范围请求发送到您的源服务器。

Cloud CDN 发起的每个字节范围请求都指定了一个范围,该范围在开始时设置了一个偏移量(2,097,136 字节的倍数)。每个范围的大小同样为 2,097,136 字节(也许最终范围除外);如果内容的大小不是该大小的倍数,则最终范围会更小。字节范围请求中使用的大小和偏移量将来可能会发生变化。

例如,假设存在一个客户端请求,该请求对应了大小为 1,000,000 至 3,999,999 字节的内容(缓存中不包含该内容)。在此示例中,Cloud CDN 可以发起两个 GET 请求,一个用于内容的第一部分(2,097,136 字节),另一个用于第二部分(2,097,136 字节)。这会导致出现 4,194,272 字节的缓存填充(即使客户端只请求了 3,000,000 字节)。

当您使用 Cloud Storage 存储分区作为来源时,我们会将每个 GET 请求视为单独的 B 类操作进行计费。您需要为 Cloud Storage 处理的所有 GET 请求付费,其中包括由 Cloud CDN 发起的所有请求。当您完全从 Cloud CDN 缓存传送响应时,系统不会向 Cloud Storage 发送 GET 请求,因此您不需要为任何 Cloud Storage 操作付费。

当 Cloud CDN 发起验证请求或字节范围请求时,它不包含特定于客户端的标头,比如 CookieUser-Agent

防止缓存

要防止不公开信息缓存在 Cloud CDN 缓存中,请执行以下操作:

  1. 在不应存储在 Cloud CDN 缓存的响应中包括 Cache-Control: private 标头,或在不应存储在任何缓存(甚至是网络浏览器缓存)的响应中包括 Cache-Control: no-store 标头。
  2. 签署可访问不公开信息的网址。使用签名网址访问内容时,响应中无论是否有任何 Cache-Control 指令,都有可能被缓存。

后续步骤

此页内容是否有用?请给出您的反馈和评价:

发送以下问题的反馈:

此网页
Cloud CDN 文档