Post

CDN缓存是什么

CDN缓存是什么

背景

Content Delivery Network

CDN缓存一般是由网站管理员自己部署,为了让他们的网站更容易扩展并获得更好的性能。通常情况下,浏览器先向CDN网关发起Web请求,网关服务器后面对应着一台或多台负载均衡源服务器,会根据它们的负载请求,动态将请求转发到合适的源服务器上。从浏览器角度来看,整个CDN就是一个源服务器,从这个层面来说,浏览器和服务器之间的缓存机制,在这种架构下同样适用。

用户web访问流程

  • 用户向浏览器输入www.web.com这个域名,浏览器第一次发现本地没有dns缓存,则向网站的DNS服务器请求;

  • 网站的DNS域名解析器设置了CNAME,指向了www.web.51cdn.com,请求指向了CDN网络中的智能DNS负载均衡系统;

  • 智能DNS负载均衡系统解析域名,把对用户响应速度最快的IP节点返回给用户;

  • 用户向该IP节点(CDN服务器)发出请求;

  • 由于是第一次访问,CDN服务器会向原web站点请求,并缓存内容;

  • 请求结果发给用户。

CDN的缓存机制

CDN边缘节点缓存策略因服务商不同而不同,但一般都会遵循http标准协议。

通过http响应头中的Cache-control: max-age的字段来设置CDN边缘节点数据缓存时间。

当客户端向CDN节点请求数据时,CDN节点会判断缓存数据是否过期,若缓存数据并没有过期,则直接将缓存数据返回给客户端;否则,CDN节点就会向源站发出回源请求,从源站拉取最新数据,更新本地缓存,并将最新数据返回给客户端。所以,如果我们修改了内容,最好加个版本号,让CDN重新获取资源,从而减少不必要的麻烦。

CDN服务商一般会提供基于文件后缀、目录多个维度来指定CDN缓存时间,为用户提供更精细化的缓存管理。CDN缓存时间会对“回源率”产生直接的影响。若CDN缓存时间较短,CDN边缘节点上的数据会经常失效,导致频繁回源,增加了源站的负载,同时也增大的访问延时;若CDN缓存时间太长,会带来数据更新时间慢的问题。开发者需要增对特定的业务,来做特定的数据缓存时间管理。

CDN的问题

CDN的分流作用不仅减少了用户的访问延时,也减少了源站的负载。但其缺点主要是缓存的同步问题:当网站更新时,如果CDN节点上数据没有及时更新,即便用户再浏览器使用Ctrl +F5的方式使浏览器端的缓存失效,也会因为CDN边缘节点没有同步最新数据而导致用户访问异常。

如何解决CDN的问题

CDN的主要问题是由于缓存同步不及时带来的,缓存更新有两种方式:

  • 定制缓存策略静态文件在返回时由源服务器控制expires、cache-control等属性来定义CDN的缓存策略。

  • 源服务器资源更新时,主动刷新CDN缓存CDN边缘节点对开发者是透明的,相比于浏览器Ctrl+F5的强制刷新来使浏览器本地缓存失效,开发者可以通过CDN服务商提供的“刷新缓存”接口来达到清理CDN边缘节点缓存的目的。这样开发者在更新数据后,可以使用“刷新缓存”功能来强制CDN节点上的数据缓存过期,保证客户端在访问时,拉取到最新的数据。

cdn缓存相关设置

  • http.Cache-Control:

    • 在 HTTP 1.1 中引入,用于为 Web 发布者提供对其内容的更多控制权,并解决 Expires 标头的局限性。

    • 如果同时定义了 Expires 和 Cache-Control 标头,则将替代前一个标头。

  • Expires:

    • HTTP 1.0 中引入的旧标头支持向后兼容性。

    • 使用基于日期的过期时间,精确到秒。

    • 类似于 Cache-Control: max-age

    • 当 Cache-Control 不存在时使用。

  • Pragma:

    • Azure CDN 默认情况下未采用。

    • HTTP 1.0 中引入的旧标头支持向后兼容性。

    • 用作具有以下指令的客户端请求标头:no-cache。 此指令指示服务器提供新的资源版本。

    • Pragma: no-cache 等效于 Cache-Control: no-cache

验证

当缓存过时时,使用 HTTP 缓存验证程序将文件的缓存版本与源服务器上的版本进行比较。

  • ETag:

    • ETag 为每个文件和文件版本定义唯一字符串。 例如,ETag: "17f0ddd99ed5bbe4edffdd6496d7131f"

    • 在 HTTP 1.1 中引入,并且比 Last-Modified 更新。 当很难确定上次修改日期时,会非常有用。

    • 支持强验证和弱验证,不过,Azure CDN 仅支持强验证。 对于强验证,两种资源表示形式的每个字节都必须相同。

    • 缓存通过在请求中发送带有一个或多个 ETag 验证程序的 If-None-Match 标头来验证使用 ETag 的文件。 例如,If-None-Match: "17f0ddd99ed5bbe4edffdd6496d7131f"。 如果服务器的版本与列表中的 ETag 验证程序相匹配,则在其响应中发送状态代码 304(未修改)。 如果版本不同,则服务器响应状态代码 200(确定)和更新后的资源。

  • Last-Modified:

    • 如果 ETag 不是 HTTP 响应的一部分,则使用 Last-Modified

    • 指定源服务器已确定上次修改资源的日期和时间。 例如,Last-Modified: Thu, 19 Oct 2017 09:28:00 GMT

    • 缓存通过在请求中发送带有日期和时间的 If-Modified-Since 标头来验证使用 Last-Modified 的文件。 源服务器将该日期与最新资源的 Last-Modified 标头进行比较。 如果自指定时间以来未修改该资源,则服务器在其响应中返回状态代码 304(未修改)。 如果已修改该资源,则服务器返回状态代码 200(确定)和更新后的资源。

This post is licensed under CC BY 4.0 by the author.