CDN 分发系统的架构
为了使得用户访问可以更加快速,可以采用 CDN 的方式将资源缓存到连用户更近的服务器或者数据中心上,这样用户可以就近访问到相应的资源。
在 CDN 中,分布在各个地方的各个数据中心的节点,就称为边缘节点。由于边缘节点数目比较多,但是每个集群规模比较小,不可能缓存下来所有东西,因而可能无法命中。这样就会在边缘节点之上,有区域节点。区域节点规模更大,缓存的数据更多,命中的概率也就更大。在区域节点之上是中心节点,规模更大,缓存数据更多。如果还不命中,就只好回源网站访问了。
上述就是 CDN 分发系统的架构,CDN 系统的缓存,也是一层一层的,能不访问后端真正的源,就不会去访问它。
使用 CDN 之后如何访问
那么有了 CDN 这个分发系统之后,怎么让用户(客户端)找到相应的边缘节点进行访问呢?CDN 分发网络也是一个分布在多个区域、多个运营商的分布式系统。这样也可以用基于 DNS 的全局负载均衡,选择一个就近的边缘节点进行访问。
下面以采用了 CDN 方式之后,访问 www.web.com 为例。
在没有 CDN 的情况下,用户向浏览器输入 www.web.com 这个域名,客户端访问本地 DNS 服务器的时候,如果本地 DNS 服务器有缓存,则返回网站的地址;如果没有,递归查询到网站的权威 DNS 服务器,这个权威 DNS 服务器是负责 web.com 的,它会返回网站的 IP 地址。本地 DNS 服务器缓存下 IP 地址,将 IP 地址返回,然后客户端直接访问这个 IP 地址,就访问到了这个网站。
在 web.com 这个权威 DNS 服务器上,会设置一个 CNAME 别名,指向另外一个域名 www.web.cdn.com,返回给本地 DNS 服务器。当本地 DNS 服务器拿到这个新的域名时,需要继续解析这个新的域名。这个时候,需要访问 web.cdn.com 的权威 DNS 服务器进行解析。在这个权威 DNS 服务器上,还是会设置一个 CNAME,指向另外一个域名,也即 CDN 网络的全局负载均衡器。
接下来,本地 DNS 服务器去请求 CDN 的全局负载均衡器解析域名,全局负载均衡器会为用户选择一台合适的缓存服务器提供服务,选择的依据包括:
- 根据用户 IP 地址,判断哪一台服务器距用户最近;
- 用户所处的运营商;
- 根据用户所请求的 URL 中携带的内容名称,判断哪一台服务器上有用户所需的内容;
- 查询各个服务器当前的负载情况,判断哪一台服务器尚有服务能力。
基于以上这些条件,进行综合分析之后,全局负载均衡器会返回一台缓存服务器的 IP 地址。本地 DNS 服务器缓存这个 IP 地址,然后将 IP 返回给客户端,客户端去访问这个边缘节点,下载资源。缓存服务器响应用户请求,将用户所需内容传送到用户终端。如果这台缓存服务器上并没有用户想要的内容,那么这台服务器就要向它的上一级缓存服务器请求内容,直至追溯到网站的源服务器将内容拉到本地。
CDN 可缓存的内容
CDN 可缓存静态数据比如静态页面、流媒体数据(缓存静态数据是 CDN 擅长的)。
-
对于静态页面来讲,内容的分发往往采取拉取的方式,也即当发现未命中的时候,再去上一级进行拉取。
-
而对于流媒体数据来讲,流媒体数据量大,如果出现回源,压力会比较大,所以往往采取主动推送的模式,将热点数据主动推送到边缘节点。很多 CDN 提供了预处理服务,也就是在文件在分发之前,先经过将数据处理好,这样可以直接拉取不同类型的数据。例如将视频转换为不同的码流,以适应不同的网络带宽的用户需求;再如对视频进行分片,降低存储压力,这样客户端可以选择使用不同的码率直接加载不同的分片。这就是我们常见的,“我要看超清、标清、流畅等”。
对于流媒体 CDN 来讲,有个关键的问题是防盗链问题。因为视频是要花大价钱买版权的,为了挣点钱,收点广告费,如果流媒体被其他的网站盗走,在人家的网站播放,那损失可就大了。最常用也最简单的方法就是 HTTP 头的 referer 字段, 当浏览器发送请求的时候,一般会带上 referer,告诉服务器是从哪个页面链接过来的,服务器基于此可以获得一些信息用于处理。如果 refer 信息不是来自本站,就阻止访问或者跳到其它链接。
这里可以将流媒体理解成前端,那么请求这个流媒体的前端会将这个请求发给后端。那么后端可以判断这个请求是不是来自自己的网站。
referer 的机制相对比较容易破解,所以还需要配合其他的机制。一种常用的机制是时间戳防盗链。使用 CDN 的管理员可以在配置界面上,和 CDN 厂商约定一个加密字符串。客户端取出当前的时间戳,要访问的资源及其路径,连同加密字符串进行签名算法得到一个字符串,然后生成一个下载链接,带上这个签名字符串和截止时间戳去访问 CDN。在 CDN 服务端,根据取出过期时间,和当前 CDN 节点时间进行比较,确认请求是否过期。然后 CDN 服务端有了资源及路径,时间戳,以及约定的加密字符串,根据相同的签名算法计算签名,如果匹配则一致,访问合法,才会将资源返回给客户。
之外,CDN 还可以缓存动态数据,这个时候需要用到动态 CDN。主要有两种模式(这里获取动态数据的时候还是先访问边缘节点):
-
边缘计算的模式。既然数据是动态生成的,所以数据的逻辑计算和存储,也相应的放在边缘的节点。其中定时从源数据那里同步存储的数据,然后在边缘进行计算得到结果。
-
路径优化的模式。数据不是在边缘计算生成的,而是在源站生成的,但是数据下发的时候可以对路径进行优化。因为 CDN 节点较多,能够找到离源站很近的边缘节点,也能找到离用户很近的边缘节点。中间的链路完全由 CDN 来规划,选择一个更加可靠的路径,使用类似专线的方式进行访问。这里就相当于用户访问边缘节点时,边缘节点让源站生成数据,源站通过优化的路径将数据下发到边缘节点,从而使得用户可以快速获得动态的数据。
对于常用的 TCP 连接,在公网上传输的时候经常会丢数据,导致 TCP 的窗口始终很小,发送速度上不去。根据前面的 TCP 流量控制和拥塞控制的原理,在 CDN 加速网络中可以调整 TCP 的参数,使得 TCP 可以更加激进地传输数据。也可以通过多个请求复用一个连接,保证每次动态请求到达时。连接都已经建立了,不必临时三次握手或者建立过多的连接,增加服务器的压力。另外,可以通过对传输数据进行压缩,增加传输效率。