到现在为止,我们基本上已经了解了网络协议中的大部分常用协议,对于整个 HTTP 请求流程也较为熟悉了。从无到有后,我们就要考虑如何优化“有”这个过程,也就是我们常见的请求优化。而现在的技术栈中,CDN 是最常用的一种方式。
在了解 CDN 前,我们可以先了解下现代社会的物流配置。
例如我们去电商网站下单买东西,这个东西一定要从电商总部的中心仓库送过来吗?在电商刚兴起的时候,所有的配送都是从中心仓库发货,所以买家可能要很久才能收到货。但是后来电商网站的物流系统学聪明了,他们在全国各地建立了很多仓库,而不是只有总部的中心仓库才可以发货。
电商网站根据统计大概知道,北京、上海、广州、深圳、杭州等地,每天能够卖出去多少书籍、纸巾、包、电器等存放期较长的商品,就将这些商品分布存放在各地仓库中,客户一下单,就从临近的仓库发货,大大减少了运输时间,提高了用户体验。
同样的,互联网也借鉴了“就近配送”这个思路。
CDN 就近配送
全球有那么多的数据中心,无论在哪里上网,临近不远的地方基本上都有数据中心。可以在每个数据中心里部署几台机器,形成一个缓存集群来缓存部分热数据,这样用户访问数据的是,就可以就近访问了。
这些分布在各个地方的各个数据中心的节点,我们一般称为边缘节点。
由于边缘节点数目比较多,但是每个集群规模比较小,不可能缓存下来所有东西,因而可能无法命中,这样就会在边缘节点之上,形成了区域节点。
区域节点规模较大,缓存的数据也较多,命中的概率也就更大。而在区域节点之上是中心节点,规模更大,缓存数据更多。
就这样,在这样一层层的节点中缓存数据,提高响应速度。但是所有的节点都没有缓存数据,就只有进行回源网站访问了。
如上图,就是 CDN 的分发系统的架构。CDN 系统的缓存,是一层层的,能不访问源数据,就不访问。这也是电商网站物流系统的思路,广州找不到,找华南局,华南局找不到,再找南方局。
有了这个分发系统之后,客户端如何找到相应的边缘节点进行访问呢?
还记得咱们之前了解的基于 DNS 的全局负载均衡吗?这个负载均衡主要用来选择一个就近的相同运营商的服务器进行访问。
同样的,CDN 分发网络也可以用相同的思路选择最合适的边缘节点。
如上图,CDN 的负载均衡流程图。
1)没有 CDN 的情况(图中虚线部分)。用户向浏览器输入 www.web.com 这个域名,客户端访问本地 DNS 服务器的时候,如果本地 DNS 服务器有缓存,则返回网站的地址。如果没有,递归查询到网站的权威 DNS 服务器,这个权威 DNS 服务器是负责 web.com 的,它会返回网站的 IP 地址。本地 DNS 服务器缓存下 IP 地址,将 IP 地址返回,然后客户端直接访问这个 IP 地址,就访问到了网站。
2)有 CDN 的情况(图中实线部分)。此时,在 web.com 这个权威 DNS 服务器上,会设置一个 CNAME 别名,指向另外一个域名 www.web.cdn.com,返回给本地 DNS 服务器。
当本地 DNS 服务器拿到这个新的域名时,需要继续解析这个新的域名。这个时候,再访问的就不是 web.com 这个权威 DNS 服务器了,而是 web.cdn.com 的权威 DNS 服务器,这是 CDN 自己的权威 DNS 服务器,在这个服务器上,还是会设置一个 CNAME,指向另外一个域名,也就是 CDN 网络的全局负载均衡器。
接下来,本地 DNS 服务器去请求 CDN 的全局负载均衡器解析域名。全局负载均衡器会为用户选择一台合适的缓存服务器提供服务,选择的依据包括:
- 根据用户 IP 地址,判断哪一台服务器距用户最近;
- 用户所处的运营商;
- 根据用户所请求的 URL 中携带的内容名词,判断哪一台服务器上有用户所需的内容;
- 查询各个服务器当前的负载情况,判断哪一台服务器尚有服务能力。
基于以上这些条件,进行综合分析之后,全局负载均衡器会返回一台缓存服务器的 IP 地址。
本地 DNS 服务器缓存这个 IP 地址,然后将 IP 返回给客户端,客户端去访问这个边缘节点,下载资源。
缓存服务器响应用户请求,将用户所需内容传送给用户。如果这台缓存服务器上没有用户想要的内容,那么这台服务器就要向它的上一级缓存服务器请求内容,直至追溯到网站的源服务器,将内容拉到本地。
CDN 缓存内容
保质期长的日用品因为不容易过期,因此比较容易缓存。同样的,互联网中的静态页面、图片等,几乎不怎么改变,所以也适合缓存。而像生鲜之类的保存时间较短的,对应互联网中的动态资源,就需要用到动态 CDN 。
静态资源缓存
还记得上图这个接入层缓存的架构吗?在进入数据中心的时候,我们希望通过最外层接入层的缓存,将大部分静态资源的访问拦在边缘。而 CDN 则更进一步,将这些静态资源缓存到离用户更近的数据中心外。总体来说,就是缩短用户的“访问距离”。离客户越近,客户访问性能越好,时延越低。
流媒体 CDN
在静态内容中,流媒体也大量使用了 CDN。
CDN 支持流媒体协议。例如前面讲过的 RTMP 协议。在很多情况下,这相当于一个代理,从上一级缓存读取内容,转发给用户。由于流媒体往往是连续的,因而可以进行预先缓存的策略,也可以预先推送到用户的客户端。
对于静态页面来讲,内容的分发往往采取拉取的方式。也即,当发现缓存未命中的是,再去上一级进行拉取。
这个方式对于流媒体就不合适了。流媒体数据量大,如果出现回源,压力会比较大,所以往往采取主动推送的模式,将热点数据主动推送到边缘节点。
对于流媒体来讲,很多 CDN 还提供预处理服务。也就是在文件分发之前,进行一定的处理。例如将视频转换成不同的码流,以适应不同的网络带宽的用户需求。再如对视频进行分片,降低存储压力,也使得客户端可以选择使用不同的码率加载不同的分片。这就是我们常见的,超清、标清、流畅等。
除此之外,流媒体 CDN 还有个关键的防盗链问题。因为视频要花大价钱买版权,如果流媒体被其他网站盗走,在其他网站的播放,那损失就大了。
对于防盗链问题,最常用也最简单的方法就是利用 HTTP 头的 refer 字段。当浏览器发送请求的时候,一般会带上 refer。告诉服务器是从哪个页面链接过来的,服务器基于此可以获得一些信息用于处理。如果 refer 信息不是来自本站,就阻止访问或者跳到其它链接。
refer 的机制相对比较容易破解,所以还需要其它的机制配合。
一种常用的机制是时间戳防盗链。使用 CDN 的管理员可以在配置界面上,和 CDN 厂商约定一个加密字符串。
客户端访问时,取出当前的时间戳、要访问的资源极其路径,联通加密字符串进行前面算法得到一个字符串,然后生成一个下载链接,带上这个前面字符串和截止时间戳去访问 CDN。
在服务端,取出过期时间,和当前 CDN 节点时间进行比较,确认请求是否过期。然后 CDN 服务端根据请求的资源及路径、时间戳、和约定的加密字符串进行签名。只有签名和客户端发送的一致,才会将资源返回给客户。
动态资源缓存
对于动态资源,用到动态 CDN。动态 CDN 主要有两种模式:
1)“生鲜超市模式”,也就是边缘计算模式。
既然数据是动态生成的,所以数据的逻辑计算和存储,也相应的放在边缘的节点。其中定时从源数据那里同步存储的数据,然后在边缘节点进行计算得到结果。
这种方式很像现在的生鲜超市。新鲜的海鲜大餐是动态的,很难事先做好缓存,因而将生鲜超市放在你家旁边,既能够送货上门,也能够现场烹饪。这就是边缘计算的一种体现。
2)“冷链运输模式”,也就是路径优化模式。数据不是在边缘计算生成的,而是在源站生成的,但是数据的下发则可以通过 CDN 的网络,对路径进行优化。
因为 CDN 节点较多,能够找到离源站很近的边缘节点,也能找到离用户很近的边缘节点。中间的链路完全由 CDN 来规划,选择一个更加可靠的路径,使用类似专线的方式进行访问。
除此之外,这些资源进行传输的时候,由于 TCP 的流量控制和拥塞控制,可以在 CDN 加速网络中调整 TCP 的参数,使得 TC 可以更加激进的传输数据。
所有这些手段就像冷链传输,优化整个物流运输,全程冷冻高速运输。不管是生鲜从你家旁边超市送过去,还是从产地运送,保证到你家是新鲜的。
小结
- CDN 和电商系统的分布式仓储系统一样,分为中心节点、区域节点、边缘节点,从而将数据缓存在离用户最近的位置。
- CDN 最擅长的缓存是缓存静态数据。除此之外还可以缓存流媒体数据。这时候要注意防盗链问题。它也支持动态数据的缓存,一种是边缘计算,另一种是链路优化。
参考:
- What is a CDN?;
- 维基百科 - Content delivery network;
- 刘超 - 趣谈网络协议系列课;