CDN技术诞生于二十多年前,随着网络的逐渐普及,以及数据长传的需求逐渐增多,骨干网的压力越来越大,而且网络压力越大,导致丢包越来越严重,长传的质量也越来越差。于是1995年,MIT的应用数学教授 Tom Leighton 带领着研究生 Danny Lewin 和其他几位研究人员一起尝试使用数学的方法来解决网络拥塞的问题。
他们使用数学算法,处理内容的动态路由安排,并最终解决了困扰 Internet 使用者的难题。后台,史隆管理学院的 MBA 学生 Jonathan Seelig 加入了他们的队伍,从那以后他们开始实施自己的商业计划,最终于 1988 年 8 月 20 号正式成立公司,命名为 Akamai (Akamai 至今仍是全球 CDN 布点最多,技术最成熟的公司)
划重点:
CDN 的全称为 Content Delivery Network ,中文翻译为内容分发网络。举个下图的例子:
这里需要了解几个基础的概念:
在 CDN 中还有 3 个 “一英里” 的概念,如下:
我们来举个场景,假如有一个用户要从西班牙访问在美国的服务器数据,直线距离大概在 6000 km 左右,按照光速 30w km/s 的传输速度,一束光从西班牙射到美国也至少需要 20 ms 的时间,一个往返就需要 40 ms。这还只是理想的情况,如果是光纤传输数据,加上传输损耗、传输设备引起的时延等,可能上百毫秒就过去了,即使用浏览器访问一个小图片,也需要等个上百毫秒,如果是访问一个大型网站,那估计用户就爆炸了。
那如果我们在欧洲大陆(比如英国)部署一个 CDN 服务器呢,让用户从西班牙直接先访问位于英国的 CDN 服务器,而 CDN 本身有缓存的功能,除了第一次请求的时候,CDN 得从源站拉一次数据(也可以预先取好),然后把那些比较不长变化的数据,比如:图片、音乐、视频等,分发并缓存到各个 CDN 节点上,这样后续的网民就不必从西班牙访问到纽约,而是访问距离自己比较近的 CDN 节点即可,从而可以节省 80% 的时间,并且还能减小骨干网的压力。
通过上面的描述,最直观的了解,可以知道 CDN 是用来做数据缓存的,让用户访问就近节点,从而提高网站响应时间,进而提升用户体验。但是这里引出来一个问题:如何知道哪个 CDN 节点离用户最近?
在 CDN 技术中,调度是重中之重,流量接入、流量牵引、选择合适的 CDN 节点服务器等工作,都是在调度环节完成的。首先来了解一下基本的 DNS 调度方法。
这里先来梳理一下 DNS 的工作原理,如下图:
日常使用的电脑中,都会配置(手动或自动)一个 DNS 服务器地址,称为 Local DNS (本地DNS服务器),简称为 LDNS 。在解析一个域名的时候,实际访问的不是域名而是 IP 地址,而 LDNS 服务器的用途就是负责将域名翻译成 Internet 可以识别的 IP 地址。
在请求某个域名时,LDNS 一般有两个情况:
“递归” 的执行过程是这样(用上面的例子举例):
那么基于 LDNS 如果做 CDN 的调度呢 (即找到最近的机器)?
假设网名是一个广东电信的用户,那他所使用的的 DNS 服务器去做递归的时候会访问到某一个 CDN 厂商的 GLB (Global Load Balance),它可以拿到获取域名信息的请求来自哪一个 LDNS,根据正常用户的使用习惯,网民所在位置和 LDNS 所在位置是一样的,因此 GLB 可以间接知道网民来自哪个位置。
在上面的例子中,假如网民是一个广东电信的用户,它使用的 LDNS 地址也是广东电信的,而 LDNS 访问 GLB 也是广东电信的,则 GLB 会认为网民的位置在广东电信,那么会分配一个广东电信的 CDN 服务器地址给 LDNS,LDNS 将 www.qq.com 解析出来的 IP 地址返回给最终网民,那么在以后网民浏览器发起请求时,都会直接与广东电信的 CDN 节点进行流量通信,从而达到加速的目的。
但是如果网民是广东电信的用户,却手动将机器 LDNS 配置指向北京联通的 LDNS,LDNS 出口也同样是北京联通,那么 GLB 会误以为网民在北京联通,则分配一个北京联通的 CDN 服务器给到客户端,后续请求将从广东电信访问到北京联通,反而降低了速度。
关键点:
通过上面的描述,不难看出,如果 client 端的 LDNS 配置不正确,则可能会分配错误的 CDN 服务器节点 ip 给到客户端,反而可能降低请求的速度。问题的根源在于,我们依赖的是请求的 LDNS 地址来判断用户所在区域,如果我们能够到 client 请求 CDN 时,根据具体请求的 ip 地址去判断客户端所在区域是不是更准确呢?所以就有了基于 HTTP 302 调度的方式;
简单来讲,就是无论客户端一开始拿到的 IP 地址是否是正确的,当它与具体的 CDN 服务节点通信时,拿到请求的 IP 所在的具体区域,然后通过 HTTP 302 响应码,携带 Location 响应头重定向到对于请求 IP 地址最优的 CDN 服务节点 IP 地址,这样就可以做到重新调度了。
说一说 HTTP DNS 出现的契机
因为随着网络逐步发展和普及,网络攻击手段变得越来越多,比如:劫持。当客户端的 LDNS 被劫持之后,网民通过域名解析出来的 IP 地址可能并不是真实的服务器,即使是真实的服务器,其中返回的数据也有可能遭到篡改。
HTTP DNS,是一种使用 HTTP 协议进行 DNS 调度的策略。原理是通过 HTTP 报文传输 DNS 请求和应答信息。但这种方式并没有任何的 RFC 的支持,所以没有任何现成的操作系统直接支持,必须得有自己的 HTTP DNS 客户端,来与 HTTP DNS 服务端进行通信,需要双端的支持,这种做法常见于 APP 。
上面讲了三种 CDN 调度方法,主要是讲客户端获得就近 CDN 服务节点的方式,那么如何将用户流量引入 CDN 网络中呢?
在讲接入之前,先来简单介绍一个 Linux 中的 dig 命令和常见的 DNS 记录类型。
dig 命令是用来从 DNS 域名服务器查询主机的地址信息的,举个简单的例子:
此处通过 dig 命令查询了百度的域名解析结果,返回结果中,从上往下我们只需要关注四个部分:
在第三部分中,可以看到响应结果中可以看到有多条 DNS 记录,其中有 CNAME 记录也有 A 记录,每条 DNS 记录都有其类型,常见的类型如下:
DNS 记录类型 | 作用 |
---|---|
A | 地址记录,用来指向 IPv4 地址,如果需要将域名指向一个 IP 地址,就需要添加一条 A 记录 |
AAAA | 用来指定域名对应的 IPv6 地址记录 |
CNAME | 如果需要将域名重定向到另一个域名,并由另一个域名提供 ip 地址就需要添加 CNAME 记录 |
MX | 如果需要设置邮箱,让邮箱能够收到邮件,则需要 MX 记录 |
NS | 域名服务器记录,如果需要把子域名交给其他 DNS 服务器解析就需要添加 NS 记录 |
SOA | 这种记录是所有区域性文件中的强制性记录,它必须是文件中的第一个记录 |
TXT | 可以写任何东西,长度限制为 255。绝大多数的 TXT 记录是用来做 SPF 记录(反垃圾邮件) |
在没有接入 CDN 的时候,我们访问某个域名,直接拿到的是服务器真实的 IP 地址,这个显示的 IP 地址的 DNS 记录信息叫做 A 记录。而当我们需要接入 CDN 时,我们只需要调整自己的 DNS 配置信息(提供 DNS 域名解析服务的云厂商),讲 A 记录改为 CNAME 记录,将重定向的域名指向 CDN 厂商所提供的接入域名即可。后续请求到真实服务器域名的流量,通过 DNS 域名解析都会重定向到 CDN 服务节点上,这样我们就完成了 CDN 的接入了。