| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> Java知识库 -> 七、系统架构 - 伸缩性架构设计 -> 正文阅读 |
|
[Java知识库]七、系统架构 - 伸缩性架构设计 |
?目录 伸缩性伸缩性的定义是指通过不断向集群中加入服务器的手段来缓解不断上升的用户并发访问压力和不断增长的数据存储需求。 伸缩性的衡量标准是否可以使用多台服务器构成集群 是否容易向集群中加入新服务器 加入新服务器是否可以提供和原来服务器一样无差别的服务 集群中可容纳的总服务器数量是否有限制 网站架构的伸缩性设计一般来说,网站的伸缩性设计可以分为两类:
不同功能进行物理分离实现伸缩网站发展初期,一台服务器中涵盖了所有的功能:数据库、应用、存储服务等。 在其后的发展中,就会出现各个功能分离的情况,出现数据库服务器、应用服务器、存储服务器等。每次分离,都会加入更多的服务器。 具体可分为两种情况:
单一功能通过集群实现伸缩将不同功能分离部署可以实现一定程度的伸缩性,但是随着网站访问量的逐步增加,即使分离到最小粒度的独立部署,单一的服务器也不能满足业务需求。因此,必须使用服务器集群,即相同服务部署在多台服务器上构成一个集群整体对外提供服务。 应用服务器集群的伸缩性设计多台服务器组成集群后,还需要使用负载均衡服务器。其主要功能在于及时发现集群中新上线或下线的服务器,并能够向新上线的服务器分发请求,停止向已下线的服务器分发请求。这样就实现了应用服务器集群的伸缩性。 实现负载均衡的技术HTTP重定向负载均衡(不常用) 利用HTTP重定向协议实现负载均衡,用户访问HTTP重定向服务器,然后其会返回302状态码并携带重定向的地址,用户就会访问到实际的应用服务器。 优点:简单 缺点:
DNS域名解析负载均衡(部分使用) 利用DNS处理域名解析的时候,根据负载均衡算法返回一个IP地址实现负载均衡。 优点:
缺点:
大型网站一般是部分使用DNS域名解析: 用户请求 -> DNS域名解析 -> 第一级负载均衡服务器地址 -> 再由第一级负载均衡服务器分发 反向代理负载均衡 前面提到可以使用反向代理服务器进行缓存,以改善网站性能。实际上,反向代理服务器大多数也提供负载均衡功能。其包含两个IP地址,一个公网IP地址,用于外部用户访问;一个内网IP地址,用于请求转发到真实的Web服务器上。 优点:与反向代理服务器在一起,部署简单 缺点:反向代理服务器可能为成为瓶颈 IP负载均衡(四层负载) 在网络层修改请求目标地址进行负载均衡,这种情况的关键在于真实Web服务器响应数据包如何返回给负载均衡服务器:
优点:相较于反向代理负载均衡,有更好的性能 缺点:
数据链路层负载均衡(直接路由方式,DR) 在通信协议的数据链路层修改mac地址进行负载均衡,这种称为三角传输模式。负载均衡服务器在分发过程中不修改IP地址,只修改目的mac地址,通过配置真实物理服务器集群所有机器虚拟IP和负载均衡服务器IP地址,从而达到不修改数据包的源地址和目的地址就可以进行数据分发的目的,且不需要进行地址转换就能把数据返回给用户,避免负载均衡服务器网卡带宽称为瓶颈。 使用三角传输模式的数据链路层负载均衡是当前大型网站使用最广泛的负载均衡手段,典型的是Linux平台上的LVS(Linux Virtual Server)。 负载均衡算法负载均衡服务器究竟将请求分发给集群中的哪一个服务器呢?这就需要负载均衡算法来决定。 轮询(Round Robin,RR) 所有请求被依次分发到每台应用服务器上,适合于所有服务器硬件都相同的情况。 加权轮询(Weighted Round Robin, WRR) 根据应用服务器的硬件性能情况,在轮询的基础上,配置权重,这样高性能的服务器处理更多的请求。 随机(Random) 请求被随机分配到各个应用服务器上。 最少连接(Least Connections) 记录每个应用服务器正在处理的连接数(请求数),将请求分发到最少连接的服务器上。 源地址散列(Source Hashing,IP Hash) 根据请求IP地址进行Hash计算,得到应用服务器,这样来自同一个IP的请求总会在同一个服务器上处理,从而实现会话粘滞。 分布式缓存集群的伸缩性设计和应用服务器集群的伸缩性设计的不同点:
分布式缓存集群的伸缩性设计的主要目标:必须让新上线的缓存服务器对整个分布式缓存影响最小,也就是说新加入缓存服务器后使整个缓存服务器集群中已经缓存的数据尽可能还被访问到。 加入新缓存服务器可能导致缓存路由失效;如果重新加载缓存且网站严重依赖缓存,则可能会导致网站崩溃;需要改进缓存路由算法保证缓存数据的可访问性。 Memcached分布式缓存集群的访问模型应用程序通过Memcached客户端程序访问Memcached服务器集群,Memcached客户端程序中包括Memcached API、通信模块、路由算法以及Memcached服务器集群列表。其中路由算法负责根据应用程序输入的缓存数据KEY计算出数据应该写入到哪台Memcached服务器中或者应该从哪台Memcached服务器中读取数据。 典型缓存写操作: 1、应用程序写入数据,KEY='BEIJING' 2、API使用路由算法,对KEY进行计算,得到服务器编号(Nodes1),进而得到服务器的IP地址和端口(10.0.0.1:91000) 3、API调用通信模块与10.0.0.1:91000通信,并将数据写入 4、读操作和写操作基本流程是一样的 Memchached分布式缓存集群的伸缩性挑战(路由算法)对于应用服务器集群的访问来说,使用负载均衡算法。而针对分布式缓存系统,则关键的是路由算法,其决定这究竟访问集群中的哪一台服务器。 最简单的路由算法:余数Hash路由算法 即拿服务器数目除以数据KEY的Hash值,余数为服务器列表的下标值。比如'BEIJING'的Hash值是490806430(按Java的hashCode()计算),除以服务器数目3,得到余数1,则对于节点Node1。 优点:由于HashCode具有随机性,因此余数Hash路由算法可以保证缓存数据在整个集群中比较均匀的分布。 为硬件配置做的改进:加权余数Hash算法 鉴于各个缓存服务器硬件配置可能不同,可以像负载均衡中的加权轮询算法一样,改造出一个加权余数Hash算法。 余数Hash算法的问题:集群扩容后,缓存无法命中 假设现在网站业务发展,需要添加缓存服务器。按照余数Hash路由算法,则如果现在是4台,则原来的'BEIJING'的HashCode对4取余后,得到的是Node2,那么访问Node2,就会导致缓存没有命中(指读操作)。 缓存不能命令概率 = (N / N + 1)* 100%,即原来3台,则添加1台后,有3/4的数据不能命中。那么当N趋向于无穷大时,缓存将接近于100%无法命中。 缓存无法命中导致的问题:大量请求达到数据库,对数据库冲击较大。 临时解决办法:模拟请求进行缓存预热,使缓存服务器中的数据重新分布。 分布式缓存的一致性Hash算法一致性Hash算法 通过一个叫一致性Hash环的数据结构实现KEY到缓存服务器的Hash映射。具体算法过程: 1、构造一个长度为0 - 2^32的整数环(这个环被称作一致性Hash环) 2、根据节点名称的Hash值(其分布范围同样是0 - 2^32),将缓存服务器节点放在这个Hash上 3、根据需要缓存的KEY计算得到其Hash值(其分布范围也是0 - 2^32) 4、然后在Hash环上顺时针找到距离这个KEY的Hash值最近的缓存服务器节点 5、然后在这个缓存服务器上进行读写操作 比如上图中的KEY3,按照顺时针去找,找到的就是Node1。 一致性Hash算法:对集群扩容的支持 当缓存服务器集群需要扩容时,只需要将新加入的节点名称(Node3)的Hash值放入一致性Hash环中,由于KEY是顺时针查找其距离最近的节点,因此新加入的节点只影响整个环中的一小段。 加入Node3后,可以看到KEY3和KEY0都会找到Node3,而KEY4依然找到的是Node1。3台服务器扩容到4台后,可以想继续命中原来缓存数据的概率是74%,远高于余数Hash的25%。随着集群规模扩大,继续命中的概率也越大,比如100台加1台,则命中率是99%。 具体应用中,这个长度为2^32的一致性Hash环通常使用二叉查找树实现,Hash查找过程实际上是在二叉查找树中查找不小于查找数的最小数值。当然这个二叉树的最右边叶子节点也最左边叶子节点相连接,构成环。 一致性Hash算法:负载不均衡问题及解决办法(虚拟层) 上面的算法有点小问题,新加入了Node3只影响了原来的Node1,也就是说,原来访问Node1的,现在需要访问Node3(概率上是50%),但是原来的Node0和Node2不受影响。这就意味着Node0和Node2缓存俩和负载压力是Node1和Node3的两倍。如果4台机器性能是一样的,那么这就是负载不均衡的问题。【想想一定会有这样的问题,极端的想一下,比如Node0,Node1,Node2,Node3的Hash值非常接近,假设分别是0,1,2,3,那么KEY的Hash值如果一直都大于3,那么数据就会都缓存到Node0节点上去了】 解决办法:计算机的任何问题都可以通过添加一个虚拟层来解决。
解决一致性Hash算法带来的负载不均衡问题:将每台物理缓存服务器虚拟为一组虚拟缓存服务器,将虚拟缓存服务器的Hash值放置在Hash换上,KEY先在环上找到虚拟服务器节点,再得到物理服务器信息。 这样新加入服务器节点的流程变成这样:将一组虚拟节点加入环中,如果虚拟节点的数目足够多,这组虚拟节点将会影响同样多数目的已经在环上存在的虚拟节点,这些已经存在的虚拟节点又对应不用的物理节点。最终的结果是:新加入一台缓存服务器,将会较为均匀地影响原来集群中已经存在的所有服务器,也就说分摊原有缓存服务器集群中所有服务器的一小部分负载。 在下图中,新加入节点Node3对应的虚拟节点是V30、V31、V32,加入到一致性Hash环上后,影响V01,V12,V22三个虚拟节点,而这三个节点分别对应Node0、Node1、Node2三个物理节点。最终在集群中添加一个节点,但是同时影响到集群中已存的三个物理节点。在理想情况下,每个节点受影响的数据量(还在缓存中,但不能被访问的数据)为其节点缓存数据量的1/4(X/(X+N),N为原有物理节点数,X为新增物理节点数),也就是集群中已经被缓存的数据有75%的概率命中,和未使用虚拟节点的一致性Hash算法结果相同。 每个物理节点对应的虚拟节点越多,各个物理节点之间负载越均衡,新加入物理服务器对原有物理服务器的影响越保持一致(这就是一致性Hash这个名称的由来)。一般来说,一台物理服务器设置150个虚拟服务器节点(具体根据集群规模和负载均衡精度来考量)。 数据存储服务器集群的伸缩性设计和缓存服务器集群的伸缩性设计的不同点:
关系数据库集群的伸缩性设计虽然支持数据复制、主从热备等机制,但是很难做到大规模集群的可伸缩性。因此关系型数据库的集群伸缩性方案必须在数据库之外实现,通过路由分区等手段将部署有多个数据库的服务器组成一个集群。 主从复制(读写分离)的MySQL集群伸缩方案 在这种架构中,部署多台MySQL实例,一台主服务器,多台从服务器,所有写操作都在主服务器,由主服务器同步复制到从服务器,然后在从服务器上进行读的相关操作。 数据分库 不同的业务数据表可以部署在不同的数据库集群上,但这种方式下跨库的表无法进行JOIN操作。 数据分片 大型网站中,即使使用了数据分库和主从复制,对于一些单表数据量很大的表(比如淘宝的商品表),也还需要进行分片,将一张表拆分存储到多个数据库中。 常见的支持数据分片的有Amoeba、Cobar(阿里巴巴,很久不更了)、MyCat(取代Cobar)、ShardingSphere的。 |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/24 2:28:32- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |