前面我们介绍了 HTTP 缓存的原理,以及基于浏览器缓存和网关缓存来实现 HTTP 缓存,浏览器缓存由于其局限性并不是主流的缓存实现方案,而网关缓存虽然解决了浏览器缓存的问题,但是所有请求仍然要发送到服务器部署的数据中心,而我们的用户是分散在天南海北的,距离数据中心越远网络延迟越大,能不能有一种缓存方案可以让用户可以就近获取缓存资源呢,这就引入了我们今天要介绍的主题 —— CDN 缓存。
CDN 的英文全称是 Content Delivery Network,即内容分发网络。CDN 缓存其实是应用服务提供商与网络服务提供商签约,将应用指定的静态资源保存到网络服务提供商的边缘节点,因为用户接入互联网都是通过网络服务商实现的,不同用户使用的网络服务商(如电信、联通、移动)不尽相同,用户通过自己所在网络服务商的边缘节点、区域节点、中心节点最终接入应用所在的数据中心,才能访问到应用服务端资源,其中边缘节点是离用户最近的运营商服务器节点,应用服务商与网络服务商签约后,就可以将静态资源缓存到这些边缘节点,这样,不同区域的用户就可以就近从边缘节点获取缓存资源,从而极大提高访问速度,所以 CDN 主要解决的是下面两个问题:
CDN 实现原理
那么 CDN 缓存具体是怎么实现的呢?
在没有 CDN 的情况下,用户向浏览器输入 www.web.com 这个域名,客户端会根据 DNS 服务获取到域名对应的 IP 地址(具体实现原理可参考 DNS 服务这篇分享),并将 IP 地址返回,然后客户端通过这个 IP 地址和默认的 HTTP 应用端口号,就可以访问到服务器端的这个网站应用。
有了 CDN 之后,情况会发生变化。在 web.com 对应的权威 DNS 服务器上,会设置一个 CNAME 别名(这可以通过在域名服务商那里通过设置 CNAME 域名解析实现),指向另外一个域名,假设这个域名是 www.web.cdn.com,并将其返回给本地 DNS 服务器。当本地 DNS 服务器拿到这个新的域名时,需要继续解析这个新的域名。这个时候,再访问的就不是 web.com 的权威 DNS 服务器了,而是 web.cdn.com 的权威 DNS 服务器,这是 CDN 自己的权威 DNS 服务器。在这个服务器上,还是会设置一个 CNAME,指向另外一个域名,也即 CDN 网络的全局负载均衡器。
接下来,本地 DNS 服务器去请求 CDN 的全局负载均衡器解析域名,全局负载均衡器会为用户选择一台合适的缓存服务器提供服务,选择的依据包括:
基于以上这些条件,进行综合分析之后,全局负载均衡器会返回一台缓存服务器的 IP 地址。
本地 DNS 服务器缓存这个 IP 地址,然后将其返回给客户端,客户端再根据这个 IP 地址去访问对应的边缘节点,下载资源。如果该边缘节点上并没有用户想要的内容,那么这台服务器就要向它的上一级节点请求内容,直至追溯到网站的源服务器将内容拉取到本地。
完整的实现流程可以通过下面这张图来描述:
CDN 常用于缓存变动很小的静态资源,比如静态页面、图片、资源文件等。如果用一张图来描述不同缓存实现方案的架构关系,可以这样来体现:
静态内容中,有一种特殊的内容,也大量使用了 CDN,这个就是流媒体。CDN 支持流媒体协议,例如 RTMP 协议。在很多情况下,这相当于一个代理,从上一级缓存读取内容,转发给用户。由于流媒体往往是连续的,因而可以进行预先缓存的策略,也可以预先推送到用户的客户端。对于一般静态页面而言,内容的分发往往采取拉取的方式,也即当发现未命中的时候,再去上一级进行拉取。但是,流媒体数据量大,如果出现回源,压力会比较大,所以往往采取主动推送的模式,将热点数据主动推送到边缘节点。关于流媒体的 CDN 缓存实现细节,后面介绍完流媒体协议及其实现后会继续介绍。