1.5 CDN工作机制

CDN也就是内容分布网络(Content Delivery Network),它是构筑在现有Internet上的一种先进的流量分配网络。其目的是通过在现有的Internet中增加一层新的网络架构,将网站的内容发布到最接近用户的网络“边缘”,使用户可以就近取得所需的内容,提高用户访问网站的响应速度。有别于镜像,它比镜像更智能,可以做这样一个比喻:CDN =镜像(Mirror)+ 缓存(Cache)+ 整体负载均衡(GSLB)。因而,CDN可以明显提高Internet中信息流动的效率。

目前CDN都以缓存网站中的静态数据为主,如CSS、JS、图片和静态页面等数据。用户在从主站服务器请求到动态内容后再从CDN上下载这些静态数据,从而加速网页数据内容的下载速度,如淘宝有90%以上的数据都是由CDN来提供的。

通常来说CDN要达到以下几个目标。

◎ 可扩展(Scalability)。性能可扩展性:应对新增的大量数据、用户和事务的扩展能力;成本可扩展性:用低廉的运营成本提供动态的服务能力和高质量的内容分发。

◎ 安全性(Security)。强调提供物理设备、网络、软件、数据和服务过程的安全性,(趋势)减少因为DDoS攻击或者其他恶意行为造成商业网站的业务中断。

◎ 可靠性、响应和执行(Reliability、Responsiveness和Performance)。服务可用性,能够处理可能的故障和用户体验的下降,通过负载均衡及时提供网络的容错机制。

1.5.1 CDN架构

通常的CDN架构如图1-16所示。

图1-16 CDN架构

如图1-16所示,一个用户访问某个静态文件(如CSS文件),这个静态文件的域名假如是cdn.taobao.com,那么首先要向Local DNS服务器发起请求,一般经过迭代解析后回到这个域名的注册服务器去解析,一般每个公司都会有一个DNS解析服务器。这时这个DNS解析服务器通常会把它重新CNAME解析到另外一个域名,而这个域名最终会被指向CDN全局中的DNS负载均衡服务器,再由这个GTM来最终分配是哪个地方的访问用户,返回给离这个访问用户最近的CDN节点。

拿到DNS解析结果,用户就直接去这个CDN节点访问这个静态文件了,如果这个节点中所请求的文件不存在,就会再回到源站去获取这个文件,然后再返回给用户。

1.5.2 负载均衡

负载均衡(Load Balance)就是对工作任务进行平衡、分摊到多个操作单元上执行,如图片服务器、应用服务器等,共同完成工作任务。它可以提高服务器响应速度及利用效率,避免软件或者硬件模块出现单点失效,解决网络拥塞问题,实现地理位置无关性,为用户提供较一致的访问质量。

通常有三种负载均衡架构,分别是链路负载均衡、集群负载均衡和操作系统负载均衡。所谓链路负载均衡也就是前面提到的通过DNS解析成不同的IP,然后用户根据这个IP来访问不同的目标服务器,如图1-17所示。

图1-17 链路负载均衡

负载均衡是由DNS的解析来完成的,用户最终访问哪个Web Server是由DNS Server来控制的,在这里就是由Global DNS Server来动态解析域名服务。这种DNS解析的优点是用户会直接访问目标服务器,而不需要经过其他的代理服务器,通常访问速度会更快。但是也有缺点,由于DNS在用户本地和Local DNS Server都有缓存,一旦某台Web Server挂掉,那么很难及时更新用户的域名解析结构。如果用户的域名没有及时更新,那么用户将无法访问这个域名,带来的后果非常严重。

集群负载均衡是另外一种常见的负载均衡方式,它一般分为硬件负载均衡和软件负载均衡。硬件负载均衡一般使用一台专门硬件设备来转发请求,如图1-18所示。

图1-18 硬件负载均衡

硬件负载均衡的关键就是这台价格非常昂贵的设备,如F5,通常为了安全需要一主一备。它的优点很显然就是性能非常好,缺点就是非常贵,一般公司是用不起的,还有就是当访问量陡然增大超出服务极限时,不能进行动态扩容。

软件负载均衡是使用最普遍的一种负载方式,它的特点是使用成本非常低,直接使用廉价的PC就可以搭建。缺点就是一般一次访问请求要经过多次代理服务器,会增加网络延时。它的架构通常如图1-19所示。

图1-19 软件负载均衡

图1-19中上面两台是LVS,使用四层负载均衡,也就是在网络层利用IP地址进行地址转发。下面三台使用HAProxy进行七层负载,也就是可以根据访问用户的HTTP请求头来进行负载均衡,如可以根据不同的URL来将请求转发到特定机器或者根据用户的Cookie信息来指定访问的机器。

最后一种是操作系统负载均衡,就是利用操作系统级别的软中断或者硬件中断来达到负载均衡,如可以设置多队列网卡等来实现。

这几种负载均衡不仅在CDN的集群中能使用,而且在Web服务或者分布式数据集群中同样也能使用,但是在这些地方后两种使用得要多一点。