六、永无止境:网站的伸缩性架构

蹲街弑〆低调 提交于 2019-12-07 21:46:27

(1)网站架构的伸缩性设计

1.不同功能进行物理分离实现伸缩。纵向分离和横向分离,不同的服务器部署不同的业务。

2.单一功能通过集群规模实现伸缩。集群内的多台服务器部署相同的服务,提供相同的功能。


(2)应用服务器集群的伸缩性设计

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

  实现负载均衡的技术,以下几种:
1.HTTP重定向负载均衡。
  HTTP重定向服务器是一台普通的应用服务器,其唯一的功能就是根据用户的HTTP请求一台真实的Web服务器地址,并将该Web服务器地址写入HTTP重定向响应中(响应状态码为302)返回给用户浏览器。在图6.5中,浏览器请求访问域名 www.mysite.com 。DNS服务器解析得到IP地址是114.100.80.10,即HTTP重定向服务器的IP地址。然后浏览器通过IP地址 114.100.80.10访问HTTP重定向负载均衡服务器后,服务器根据某种负载均衡算法计算获得一台实际物理服务器的地址(114.100.80.3),构造一个包含该实际物理服务器地址的重定向响应返回给浏览器,浏览器自动重新请求实际物理服务器的IP地址(114.100.80.3),完成访问。
  这种负载均衡方案的优点是比较简单。缺点是浏览器需要两次请求才能完成一次访问,性能较差;重定向服务器自身的处理能力有可能成为瓶颈,整个集群的伸缩性规模有限;使用HTTP302响应码重定向,有可能使搜索引擎判断为SEO作弊,降低搜索排名。因此实践中使用这种方案进行均衡负载的案例并不多见。

2.DNS域名解析负载均衡 

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

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

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服务器的响应会再回到负载均衡服务器;另一种方案是将负载均衡服务器同时作为真实物理服务器集群的网关服务器,这样所有响应数据都会到达负载均衡服务器。

5.数据链路层负载均衡
  数据链路层负载均衡是指在通信协议的数据链路层修改mac地址进行负载均衡。这种数据传输方式又称作三角传输模式,负载均衡数据分发过程中不修改IP地址,只修改目的mac地址,通过配置真实物理服务器集群所在机器虚拟IP和负载均衡服务器IP地址一致,从而达到不修改数据包的源地址和目的地址就可以进行数据分发的目的,由于实际处理请求的真实物理服务器IP和数据请求目的IP一致,不需要通过负载均衡服务器进行地址转换,可将响应数据包直接返回给用户浏览器,避免负载均衡服务器网卡带宽成为瓶颈。这种负载均衡方式又称作直接路由方式(DR)。
  使用三角传输模式的链路层负载均衡是目前大型网站使用最广的一种负载均衡手段。在Linux平台上最好的链路层负载均衡开源产品是LVS(Linux Virtual Server)。

6.负载均衡算法
  负载均衡服务器的实现分成两个部分:1.根据负载均衡算法和Web服务器列表计算得到集群中一台Web服务器的地址。2.将请求数据发送到该地址对应的Web服务器上。

  a.轮询(Round Robin, RR)。所有请求被依次分发到每台应用服务器上,即每台服务器需要处理的请求数目都相同,适用于所有服务器硬件都相同的场景。
  b.加权轮询(Weighted Round Robin, WRR)。根据应用服务器硬件性能的情况,在轮询的基础上,按照配置的权重将请求分发到每个服务器,高性能的服务器能分配更多请求。
  c.随机(Random)。请求被随机分配到各个应用服务器,在许多场合下,这种方案都很简单实用,因为好的随机数本身就很均衡。即使应用服务器硬件配置不同,也可以使用加权随机算法。
  d.最少连接(Least Connections)。记录每个应用服务器正在处理的连接数(请求数),将新到的请求分发到最少连接的服务器上,这是符合负载均衡定义的算法。同样,最少连接算法也可以实现加权最少连接。
  e.源地址散列(Source Hashing)。根据请求来源的IP地址进行Hash计算,得到应用服务器,这样来自同一个IP地址的请求总在同一个服务器上处理,该请求的上下文信息可以存储在这台服务器上,在一个会话周期内重复使用,从而实现会话黏滞。


(3)分布式缓存集群的伸缩性设计

1.Memcached分布式缓存集群的访问模型。
  应用程序通过Memcached客户端访问Memcached服务器集群,Memcached客户端主要由一组API、Memcached服务器集群路由算法、Memcached服务器集群列表及通信模块构成。
  其中路由算法负责根据应用程序输入的缓存数据KEY 计算得到应该将数据写入到Memcache的哪台服务器(写缓存)或者应该从哪台服务器读数据(读缓存)。

2.Memcached分布式缓存集群的伸缩性挑战
  简单的路由算法可以使用余数Hash,用服务器数目除缓存数据KEY的Hash值,余数为服务器列表下标编号。假设"BEIJING"的Hash值是490806430(Java中HashCode返回值),用服务器数目3除该值,得到余数1,对应节点NODE1。由于HashCode具有随机性,因此使用余数Hash路由算法可保证缓存数据在整个Memcached服务集群中比较均衡地分布。
  假如业务发展,需要从3台扩容到4台,本来路由算法是除以3,现在除以4,导致很多数据缓存都不会命中,不能命中的概率为3/4(N/(N+1))。
  缓存不能命中的话将会给数据库带来巨大压力。所以我们可以在网站访问量最少的时候扩容缓存服务器集群,这时候对数据库的负载冲击最小,然后通过模拟请求的方法逐渐预热缓存,使缓存服务器中的数据重新分布。

3.分布式缓存的一致性Hash算法
  一致性Hash算法通过一个叫作一致性Hash环的数据结构实现KEY到缓存服务器的Hash映射。
  具体算法过程为:先构造一个长度为0-2的32次方的整数环(这个环被称作一致性Hash环),根据节点名称的Hash值(其分布范围同样为0到2的32次方)将缓存服务器节点放置在这个Hash环上。然后根据需要缓存的数据的KEY值计算得到其Hash值(其分布范围也同样为0~2的32次方),然后在Hash环上顺时针查找距离这个KEY的Hash值最近的缓存服务器节点,完成KEY到服务器的Hash映射查找。
  假设NODE1的Hash值为3,594,963,423,NODE2的Hash值为1,845,328,979,而KEY0的Hash值为2,534,256,785,那么KEY0在环上顺时针查找,找到的最近的节点就是NODE1。
  当缓存服务器集群需要扩容的时候,只需要将新加入的节点名称(NODE3)的Hash值放入一致性Hash环中,由于KEY是顺时针查找距离其最近的节点,因此新加入的节点只影响整个环中的一小段。
  具体应用中,这个长度为2的32次方的一致性Hash环通常使用二叉查找树实现,Hash查找过程实际上是在二叉查找树中查找不小于查找树的最小数值。当然这个二叉树的最右边叶子节点和最左边的叶子节点相连接,构成环。

4.数据存储服务器集群的伸缩性设计
  与缓存服务器集群的伸缩性设计不同,数据存储服务器集群的伸缩性对数据的持久性和可用性提出了更高的要求。
  缓存的目的是加速数据读取的速度并减轻数据存储服务器的负载压力,因此部分缓存数据的丢失不影响业务的正常处理,因为数据还可以从数据库等存储服务器上获取。
  而数据存储服务器必须保证数据的可靠存储,任何情况下都必须保证数据的可用性和正确性。因此缓存服务器集群的伸缩性架构方案不能直接适用于数据库等存储服务器。存储服务器集群的伸缩性设计相对更复杂一些,具体来说,又可分为关系数据库集群的伸缩性设计和NoSQL数据库的伸缩性设计。

  a.关系数据库集群的伸缩性设计。读写分离、数据分库(不同业务数据表部署在不同的数据库集群上)
  b.NoSQL数据库的伸缩性设计。NoSQL数据库产品都放弃了关系数据库的两大重要基础:以关系代数为基础的结构化查询语言(SQL)和事务一致性保证(ACID)。而强化其他一些大型网站更关注的特性:高可用性和可伸缩性。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!