CDN是将源站内容分发至全国所有的节点,从而缩短用户查看对象的延迟,提高用户访问网站的响应速度与网站的可用性的技术。它能够有效解决网络带宽小、用户访问量大、网点分布不均等问题。
为了让大家更全面的了解CDN的原理、调度、缓存和安全等关键技术点,阿里云高级技术专家白金将自己从事 CDN 相关领域工作 8 年来的一些经验、收获和个人认知撰写成《CDN之我见》系列文章,分享给大家。
《CDN 之我见》共分成多个部分,分为原理篇、详解篇和陨坑篇,因为篇幅问题这里先讲第一部分。本篇章适合那些从未接触过、或仅了解一些 CDN 专业术语,想深入了解和感受 CDN 究竟是什么的同学。下面我们进入分享正文:
这个篇章,主要分成 4 个小部分来和大家做一下简单的介绍和分享。
CDN的起源
CDN 诞生于二十多年前,随着骨干网压力的逐渐增大,以及长传需求的逐渐增多,使得骨干网的压力越来越大,长传效果越来越差。于是在 1995 年,MIT 的应用数学教授 Tom Leighton 带领着研究生 Danny Lewin 和其他几位顶级研究人员一起尝试用数学问题解决网络拥堵问题。
他们使用数学算法,处理内容的动态路由安排,并最终解决了困扰 Internet 使用者的难题。后来,史隆管理学院的 MBA 学生 Jonathan Seelig 加入了 Leighton 的队伍中,从那以后他们开始实施自己的商业计划,最终于 1998 年 8 月 20 日正式成立公司,命名为 Akamai。
同年 1998 年,中国第一家 CDN 公司 ChinaCache 成立。
在接下来的20年中,CDN行业历经变革和持续发展,行业也涌现出很多云CDN厂商。阿里云CDN是2008年从淘宝CDN起家,在2014年正式发展成为阿里云CDN的,它不仅为阿里巴巴集团所有子公司提供服务,同时也将自身的资源、技术以云计算的方式输出。
那什么是 CDN 呢?
CDN 其实是 Content Delivery Network 的缩写,即“内容分发网络”。
上图是一个做过 CDN 之后的拓扑图,里面有几个概念需要明确一下:
- Origin Server:源站,也就是做 CDN 之前的客户真正的服务器。
- User:访问者,也就是问网站的网民。
- Edge Server:CDN 的服务器,不单指“边缘服务器”,这个之后细说。
在 CDN 中,还有 3 个”一英里“的概念,即 First Mile、Middle Mile 和 Last Mile。
- First Mile:和 CDN 客户的服务器越近越好的 CDN 设备,即第一英里。
- Last Mile:访问者(网民)到离他最近的 CDN 服务器,即最后一英里。
- Middle Mile:数据从进入 CDN 网络,到出 CDN 网络之前的所有环节,即中间一英里。
为什么要用 CDN 呢?
从上图可以看到,左图是未做 CDN 之前跨洋跨国的长传业务,用户从西班牙访问到美国纽约要经过北大西洋,直线距离6,000km 左右,按照光速300,000km/s 的传输速度,一束光从西班牙到纽约也至少需要 20ms 时间,一个往返就需要 40ms。如果是光纤传输数据,加上传输损耗、传输设备延时引入等,可能上百毫秒就出去了,即使用浏览器访问一个再小不过的图片,也会等个上百毫秒,积少成多,访问一个美国购物网站会让用户无法接受。
右侧这张图是做过 CDN 之后的示意图。从图上可以看出,网民实际访问到的服务器不是位于美国的真实服务器,而是位于英国的 CDN 服务器。而 CDN 本身有缓存功能,把那些网页里一成不变的内容,例如图片、音乐、视频等,都分发并缓存到了各个 CDN 服务节点上,这样网民就不必从西班牙访问到纽约,而是访问距离自己较近的英国节点即可,从而节省了 80% 以上的时间。
当然,这是一个西班牙访问英国 CDN 节点的例子,如果 CDN 节点也位于西班牙本地,则效果会更加明显,具体细节后续会有更详细的说明。
接下来说一下调度。调度是 CDN 中的重中之重,流量接入、流量牵引、选择合适的 CDN 节点服务器等工作,都是在调度环节完成的。
要理解调度策略和原理,必须先了解 DNS 协议及其工作原理。
我们平时所工作的电脑里,都会配置(人为或自动)一个 DNS 服务器地址,我们称之为”本地 DNS“,也叫 Local DNS,简称 LDNS。在解析一个域名的时候,实际访问的不是”域名“而是 IP 地址,则 LDNS 服务器的用途就是负责将域名翻译成 Internet 可以识别的 IP 地址。
在请求某个域名时,LDNS 一般有两个情况:一种是域名在 LDNS 上有记录,另一种情况是没有记录,两种情况的处理流程不一样。
- 假设当访问 163 这个域名时,如果 LDNS 上有缓存记录,那它会直接将 IP 地址吐出来。
- 如果没有缓存记录,它将会一步步向后面的服务器做请求,然后将所有数据进行汇总后交给最终的客户,这个环节术语叫”递归“。
在完全不命中情况,LDNS 首先会向全球13个根域服务器发起请求,询问 .com 域名在哪里,然后根域服务器作出回答,然后去向 .com 的服务器询问 .163.com 在哪里,一步步往下,最后拿到 www.163.com 这个域名所对应的 IP 地址。这个过程较复杂,如果大家感兴趣可去查相关资料,在这就不一一赘述。
肯定很多人好奇是如何进行调度和进行定位的?其实也是通过 LDNS 的具体地址来进行的,如上图所示。
假设网民是一个北京客户,那他所使用的 DNS 服务器去做递归的时会访问到CDN厂商的 GLB(Global Load Balance),它可以看到所访问的域名请求是来自于哪个 LDNS,根据一般人的使用习惯,网民所在位置和 LDNS 所在位置是一样的,因此 GLB 可以间接知道网民来自什么位置。
以上图为例,假如网民是一个北京联通的用户,它使用的 LDNS 地址也是北京联通的,而 LDNS 访问 GLB 也是北京联通的,则 GLB 则认为网民的位置在北京联通,那么会分配一个北京联通的 CDN 服务器地址给 LDNS,LDNS 将http:www.a.com解析出的 IP 地址返回给最终网民,那么在以后网民浏览器发起请求的时候,都会直接与北京联通的 CDN 节点进行流量通信,从而达到了加速的目的。
从这个调度理论上看,我们可以不难发现一个问题,就是重点标注出的“根据一般人的使用习惯”。假设网民所使用的 LDNS 地址和他自己在同一个区域,调度才有可能是准确的(后续篇章会重点描述为什么是“有可能”)。
但是举个例子来说,如果网民是北京联通的用户,但他却偏要使用深圳电信的 LDNS,LDNS 出口也同样是深圳电信的 IP 地址,那么 GLB 会误判网民位于深圳电信,分配给网民的 CDN 服务器也都是深圳电信的,后续网民会从北京联通访问到深圳电信,不但没加速,可能反而降速了。
如前文所述,由于用户使用习惯或一些其他原因,通过 LDNS 调度有可能是不准确的,因此又出现了另一种调度方式,HTTP 302 调度。
原理很简单,无论网民最初拿到的 IP 地址是否是正确的,但最终都是要和这个 IP 地址的 CDN 服务器通信的,因此 CDN 服务器可以在这时知道网民的真实地址(DNS 调度时只能间接知道网民地址,虽然 EDNS-Client-Subnet 技术可以解决问题,但尚未大规模使用)。
HTTP 协议中有一个特殊的返回状态:302。在 HTTP 服务器返回 302 状态码时,可以携带一个新的 URL(使用的是正确 IP),浏览器在拿到 302 返回状态码时,会提取其中新的 URL 地址发起请求,这样就可以做到重新调度了。
除了 DNS 调度、HTTP 302 调度,还有一种使用 HTTP 进行的 DNS 调度策略。
随着网络日新月异的发展和演进,也逐渐出现了很多鲜为人知的技术和设备,例如劫持(具体在后面的篇章里会单独阐述)。劫持后,网民所访问的目标有可能不再是真实服务器,即使是真实服务器,内容也有可能是虚假的、被替换过的,这对业务安全来说是十分危险的,这种劫持现象多出现在移动互联网(手机上网)。
为了规避这种问题,出现了一种 HTTP DNS 的调度方式,原理是通过 HTTP 报文传输 DNS 请求和应答信息。但这种方式没有任何 RFC 的支持,所以没有任何现成的操作系统直接支持,必须有自己的 HTTP DNS 客户端,来与 HTTP DNS 服务端进行通信,需要双端支持。这种做法在 APP 中使用较多。
那 CDN 是如何将用户的流量引入到 CDN 网络中的呢?
在未做 CDN 时,我们访问某个域名,直接拿到的是一个真实的服务器 IP 地址,这个显示 IP 地址的 DNS 记录信息叫 A 记录,一般是下图这个样子。
当业务需要接入到 CDN 时,用户只需调整自己的 DNS 配置信息,将 A 记录改为 CNAME 记录,将内容改为 CDN 厂商所提供的接入域名即可。
由于篇幅的关系,系列一先把 CDN 的历史由来,以及调度相关的知识和大家分享。在“系列二”中白金将会和大家分享 CDN 的缓存及安全。