六、永无止境:网站的伸缩性架构(大型网站技术架构原理)

  6.1 网站架构的伸缩性设计

  一般来说,网站的伸缩性设计可分为两类,一类是根据功能进行物理分离实现伸缩,一类是单一功能通过集群实现伸缩。前者是不同的服务器部署不同的服务,提供不同的功能;后者是集群内的多台服务器部署相同的服务,提供相同的功能。

    6.1.1 不同功能进行物理分离实现伸缩

  网站发展早期---通过增加服务器提高网站处理能力时,新增服务器总是从现有服务器中分离出部分功能和服务。如下图

  

 

 ·  每次分离都会有更多的服务器加入网站,使用新增的服务器处理某种特定服务。通过物理上分离不同的网站功能,实现网站伸缩性的手段,不仅可以用在网站发展早期,而且可以在网站发展的任何阶段使用。

   具体分为:

    纵向分离(分层后分离):将业务处理流程上的不同部分分离部署,实现系统伸缩性。

    横向分离(业务分割后分离):将不同的业务模块分离部署,实现系统伸缩性。

  

 

   横向分离的粒度可以非常小,甚至可以一个关键网页部署一个独立服务,比如对于电商网站非常重要的产品详情页面,商铺页面,搜索列表页面,每个页面都可以独立部署,专门维护。

    6.1.2 单一功能通过集群规模实现伸缩

   将不同功能分离部署可以实现一定程度的伸缩性,随着网站访问量的逐步增加,即使分离到最小粒度的独立部署,单一的服务器也不能满足业务规模的要求。因此必须使用服务器集群,即将相同服务部署在多台服务器上构成一个集群整体对外提供服务。

   以搜索服务器为例,如果一台服务器可以提供每秒 1000 次的请求服务,即 QPS(Query Per Second) 为 1000。那么如果网站高峰时每秒搜索访问量为 10000,就需要部署 10 台服务器构成一个集群。若以缓存服务器为例,如果每台服务器可缓存 40GB 数据,那么要缓存 100GB 数据,就需要部署 3 台服务器构成一个集群。计算一个服务的集群规模,需要同时考虑其对可用性、性能的影响及关联服务集群的影响。

  具体来说,集群伸缩性又可分为应用服务器集群伸缩性和数据服务器集群伸缩性。这两种集群由于对数据状态管理的不同,技术实现也有非常大的区别。

  数据服务器集群也可分为缓存数据服务器集群和存储数据服务器集群,这两种集群的伸缩性设计也不大相同。

  6.2 应用服务器集群的伸缩性设计

  应用服务器应该设计成无状态的,即应用服务器不存储请求上下文信息,如果将部署有相同应用的服务器组成一个集群,每次用户请求都可以发送到集群中任意一个服务器上去处理,任何一台服务器的处理结果都是相同的。这样只要能将用户请求按照某种规则分发到集群的不同服务器上,就可以构成一个应用服务器集群,每个用户的每个请求都可能落在不同的服务器上。如下

   如果 HTTP 请求分发装置可以感知或者可以配置集群的服务器数量,可以及时发现集群中新上线或下线的服务器,并能向新上线的服务器分发请求,停止向已下线的服务器分发请求,那么就实现了应用服务器集群的伸缩性。

  HTTP请求分发装置被称为负载均衡服务器。

  负载均衡是网站必不可少的基础技术手段,不但可以实现网站的伸缩性,同时还改善网站的可用性。负载均衡的基础技术不外以下几种:

  HTTP重定向负载均衡、DNS域名解析负载均衡、反向代理负载均衡、IP负载均衡、数据链路层负载均衡、负载均衡算法

    6.2.1 http 重定向负载均衡

  

 

 

  HTTP重定向服务器是一台普通的应用服务器,其唯一的功能就是根据用户的HTTP请求计算一台真实的Web服务器地址,并将该 Web 服务器地址写入 HTTP 重定向响应中(响应状态码302)返回给用户浏览器。上图浏览器请求访问域名 www.mysite.com, DNS服务器解析得到 IP 地址是 114.100.80.10,即 HTTP 重定向服务器的 IP 地址 114.100.80.10 访问 HTTP 重定向负载均衡服务器后,服务器根据某种负载均衡算法计算获得一台实际物理服务器的地址(114.100.80.3),构造一个包含该实际物理服务器地址的重定向响应返回给浏览器,浏览器自动重新请求实际物理服务器的 IP 地址 114.100.80.3,完成访问。

  这种负载均衡方案的有点是比较简单。缺点是浏览器需要两次请求服务器才能完成一次访问,性能较差;重定向服务器自身的处理能力有可能成为瓶颈,整个集群的伸缩性规模有限;使用HTTP302响应码重定向,有可能使搜索引擎判断为 SEO 作弊,降低搜索排名。实践中使用这种方案进行负载均衡的案例并不多见。

    6.2.2 DNS 域名解析负载均衡

  

  在 DNS 服务器中配置多个 A 记录,如:www.mysite.com IN A 144.100.80.1、www.mysite.com IN A 144.100.80.2、www.mysite.com IN A 144.100.80.3。

  每次域名解析请求都会根据负载均衡算法计算一个不同的 IP 地址返回,这样 A 记录中配置的多个服务器就构成一个集群,并可以实现负载均衡。图 6.6 中的浏览器请求解析域名 www.mysite.com, DNS 根据 A 记录和负载均衡算法计算得到一个 IP 地址 144.100.80.3,并返回给浏览器;浏览器根据该 IP地址,访问真实物理服务器 144.100.80.3。

  DNS 域名解析负载均衡的有点是将负载均衡的工作转交给 DNS,省掉了网站管理维护负载均衡服务器的麻烦,同时许多 DNS 还支持基于地理位置的域名解析,即会将域名解析成距离用户地理最近的一个服务器地址,这样可加快用户访问速度,改善性能。但是 DNS 域名解析负载均衡也有缺点,就是目前的 DNS 是多级解析,每一级 DNS 都可能缓存 A 记录,当下线某台服务器后,即使修改了 DNS 的 A 记录,要使其生效也需要较长时间,这段时间, DNS 依然会将域名解析到已经下线的服务器,导致用户访问失败;而且 DNS负载均衡的控制权在域名服务商那里,网站无法对其做更多改善和更强大的管理。

  大型网站总是部分使用 DNS 域名解析,利用域名解析作为第一级负载均衡手段,即域名解析得到的一组服务器并不是实际提供 Web 服务的物理服务器,而是同样提供负载均衡服务的内部服务器,这组内部负载均衡服务器再进行负载均衡,将请求分发到真实的 Web 服务器上。

    6.2.3 反向代理负载均衡

  

   前面提到利用反向代理缓存资源,以改善网站性能。实际上,在部署位置上,反向代理服务器处于 Web 服务器前面(这样才可能缓存 Web 响应,加速访问),这个位置也正好是负载均衡服务器的位置,所以大多数反向代理服务器同时提供负载均衡的功能,管理一组 Web 服务器,将请求根据负载均衡算法转发到不同 Web 服务器上。Web服务器处理完成的响应也需要通过反向代理服务器返回给用户。由于 Web服务器不直接对外提供访问,因此 Web 服务器不需要使用外部 IP地址,而反向代理服务器则需要配置双网卡和内部外部两套 IP地址。

  图6.7中,浏览器访问请求的地址是反向代理服务器的地址 114.100.80.10,反向代理服务器收到请求后,根据负载均衡算法计算得到一台真实物理服务器的地址 10.0.0.3,并将请求转发给服务器。10.0.0.3 处理完请求后将响应返回给反向代理服务器,反向代理服务器再将该响应返回给用户。

  由于反向代理服务器转发请求在 HTTP 协议层面,因此也叫应用层负载均衡。其优点是和反向代理服务器功能集成在一起,部署简单。缺点是反向代理服务器是所有请求和响应的中转站,其性能可能会成为瓶颈。

    6.2.4 ip负载均衡

  

 

  用户请求数据包到达负载均衡服务器 114.100.80.10 后,负载均衡服务器在操作系统内核进程获取网络数据包,根据负载均衡算法计算得到一台真实 Web 服务器 10.0.0.1,然后将数据目的 IP 地址修改为 10.0.0.1,不需要通过用户进程处理。真实 Web 应用服务器处理完成后,响应数据包回到负载均衡服务器,负载均衡服务器再将数据包源地址修改为自身的 IP 地址(114.100.80.10)发送给用户浏览器。

 

  这里的关键在于真实物理 Web 服务器响应数据包如何返回给负载均衡服务器。一种方案是负载均衡服务器在修改目的 IP 地址的同时修改源地址,将数据包源地址设为自身IP,即源地址转换(SNAT),这样 Web服务器的响应会再回到负载均衡服务器;另一种方案是将负载均衡服务器同时作为真实物理服务器集群的网关服务器,这样所有响应数据都会到达负载均衡服务器。

  IP负载均衡在内核进程完成数据分发,较反向代理负载均衡(在应用程序中分发数据)有更好的处理性能。但是由于所有请求响应都需要经过负载均衡服务器,集群的最大响应数据吞吐量不得不受制于负载均衡服务器网卡带宽。对于提供下载服务或者视频服务等需要传输大量数据的网站而言,难以满足需求。能不能让负载均衡服务器只分发请求,而使响应数据从真实物理服务器直接返回给用户?

    6.2.5 数据链路层负载均衡

  

   这种数据传输当时又称为 三角传输模式,负载均衡数据分发过程中不修改 IP地址,只修改目的 mac 地址,通过配置真实物理服务器集群所有机器虚拟 IP 和负载均衡服务器 IP 地址一致,从而达到不修改数据包的源地址和目的地址就可以进行数据分发的目的,由于实际处理请求的真实物理服务器 IP 和数据请求目的 IP 一致,不需要通过负载均衡服务器进行地址转换,可将响应数据包直接返回给用户浏览器,避免负载均衡服务器网卡带宽成为瓶颈。这种负载均衡方式又称作直接路由方式(DR)。

  图6.9中,用户请求到达负载均衡服务器 114.100.80.10 后,负载均衡服务器将请求数据的目的 mac 地址修改为 00:0c:29:d2 对应的服务器,该服务器处理完成后发送响应数据到网站的网关服务器,网关服务器直接将该数据包发送到用户浏览器(通过互联网),响应数据不需要通过负载均衡服务器。

  使用三角传输模式的链路层负载均衡是目前大型网站使用最广的一种负载均衡手段。在Linux平台上最好的链路层负载均衡开源产品是 LVS(Linux Virtual Server)

    6.2.6 负载均衡算法

  负载均衡服务器的实现可以分成两个部分:

  1.根据负载均衡算法和 Web 服务器列表计算得到集群中一台 Web 服务器的地址。

  2.将请求数据发送到该地址对应的 Web 服务器上。

  前面描述了如何将请求数据发送到 Web 服务器,而具体的负载均衡算法通常有以下几种。

  轮询(Round Robin,RR)

  所有请求被依次分发到每台应用服务器上,即每台服务器需要处理的请求数目都相同,适合于所有服务器硬件都相同的场景。

  加权轮询(Weighted Round Robin,WRR)

  根据应用服务器硬件性能的情况,在轮询的基础上,按照配置的权重将请求分发到每个服务器,高性能的服务器能分配更多请求。

  随机(Random)

  请求被随机分配到各个应用服务器,在许多场合下,这种方案都很简单实用,因为好的随机数本身就很均衡。即使应用服务器硬件配置不同,也可以使用加权随机算法。

  最少连接(Least Connections)

  记录每个应用服务器正在处理的连接数(请求数),将新到的请求分发到最少连接的服务器上,应该说,这是最符合负载均衡定义的算法。同样,最少连接算法也可以实现加权最少连接。

  源地址散列(Source Hashing)

  根据请求来源的 IP 地址进行 Hash 计算,得到应用服务器,这样来自同一个 IP地址的请求总在同一个服务器上处理,该请求的上下文信息可以存储在这台服务器上,在一个会话周期内重复使用,从而实现会话黏滞。

  6.3 分布式缓存集群的伸缩性设计

    第4章讨论了分布式缓存,不同于应用服务器集群的伸缩性设计,分布式缓存集群的伸缩性不能使用简单的负载均衡手段来实现。

    和所有服务器都部署相同应用的应用服务器集群不同,分布式缓存服务器集群中不同服务器中缓存的数据各不相同,缓存访问请求不可以在缓存服务器集群中的任意一台处理,必须先找到缓存有需要数据的服务器,然后才能访问。这个特点会严重制约分布式缓存集群的伸缩性设计,因为新上线的缓存服务器没有缓存任何数据,而已下线的缓存服务器还缓存着网站的许多热点数据。

    必须让新上线的缓存服务器对整个分布式缓存集群影响最小,也就是说新加入缓存服务器后应使整个缓存服务器集群中已经缓存的数据尽可能还被访问到,这是分布式缓存集群伸缩性设计的最重要目标。

    6.3.1 Memcached 分布式缓存集群的访问模型

  应用程序通过 Memcached 客户端访问Memcached

 

 

    6.3.2 memcached 分布式缓存集群的伸缩性挑战

    6.3.3 分布式缓存的一致性 Hash 算法

  6.4 数据存储服务器集群的伸缩性设计

    6.4.1 关系数据库集群的伸缩性设计

    6.4.2 nosql 数据库的伸缩性设计

  6.5 小结

posted @ 2021-03-22 14:27  veggiegfei  阅读(181)  评论(0编辑  收藏  举报