大型网站技术架构笔记2.docx
《大型网站技术架构笔记2.docx》由会员分享,可在线阅读,更多相关《大型网站技术架构笔记2.docx(16页珍藏版)》请在冰豆网上搜索。
![大型网站技术架构笔记2.docx](https://file1.bdocx.com/fileroot1/2023-2/25/d6b1f20f-dad5-45c7-93f4-1a1e943a32a6/d6b1f20f-dad5-45c7-93f4-1a1e943a32a61.gif)
大型网站技术架构笔记2
四、网站的高可用架构-万无一失
故障分是指对网站故障进行分类加权计算故障责任的方法。
如下是个案例:
分类
描述
权重
事故级故障
严重故障,网站整体不可用
100
A类故障
网站访问不顺畅或核心功能不可用
20
B类故障
非核心功能不可用,或核心功能少数用户不能访问
5
C类故障
其他故障
1
故障分的计算公式为:
故障分=故障时间(分钟)*故障权重
1.高可用的网站架构
实现高可用架构的主要手段是数据和服务的冗余备份及失效转移,一旦某些服务器宕机,就将服务切换到其他可用的服务器上,如果磁盘损坏,则从备份的磁盘读取数据。
(1)对于应用层的服务器通常为了应对高并发的访问请求,会通过负载均衡设备将一组服务器组成一个集群共同对外提供服务,当负载均衡设备通过心跳检测到某台服务器不可用时,就将其从集群列表中剔出,并将请求分发到集群中其他可用的服务器上,是整个集群保存可用,从而实现应用高可用。
(2)位于服务层的服务器情况和应用层类似,也是通过集群方式实现高可用,只是这些服务器被应用层通过分布式服务调用框架访问, 分布式服务调度框架会在应用层客户端中实现负载均衡功能。
(3)位于数据层的服务器情况比较特殊,数据服务器上存储着数据,为了保证数据不丢失,数据访问服务不中断,需要在数据写入时进行数据同步复制,将数据写入多台服务器上,实现数据冗余备份。
宕机时直接切换到备份服务器上。
网站升级的频率一般都非常高,每次网站发布都需要关闭服务,重新启动系统,相当于服务器宕机。
因此网站的可用性架构还需要考虑到网站升级发布引起的宕机。
2.高可用的应用
(1)通过负载均衡进行无状态服务的失效转移
(2)应用服务器集群的Session管理
Web应用中将这些多次请求的上下文称为会话(Session),在单机情况下,session可部署在服务器上的Web容器上管理。
在使用负载均衡的集群环境中,由于负载均衡服务器可能会将请求分发到集群任何一台应用服务器上,所以保证每次请求依然能够获得正确的session比单机时要复杂的多。
在集群环境下,session管理主要有以下手段。
Session复制:
Session复制是早期企业应用系统使用较多的一种服务器集群Session管理机制。
应用服务器开启Web容器的Session复制功能,在集群中几台服务器之间同步Session对象,是每台服务器上都保存所有用户的Session信息。
这种方案虽然简单,从本机读取Session信息也很快,但当集群规模比较大的时候会占用服务器和网站的大量资源,在大量用户访问的情况下,甚至会出现内存不够Session使用的情况。
Session绑定:
Session绑定可以利用负载均衡的源地址Hash算法实现,负载均衡服务器总是将来源于同一IP的请求分发到同一台服务器上。
这样在整个回话期间,用户所有的请求都在同一台服务器上处理,即Session绑定到某台特定的服务器上,保证Session总能在这台服务器上获取,这种方法有成为会话粘滞。
利用Cookie记录Session:
一种管理Session的方式是将Session记录在客户端,每次请求服务器的时候,将Session放在请求中发送给服务器,服务器处理完请求后再将修改后的Session响应给客户端。
但是Cookie大小受限,每次请求都需要传送Cookie,影响性能。
如果用户关闭Cookie,访问就会不正常。
Session服务器:
Session服务器(集群),即把session的管理独立部署在某一台机器上,Web服务器不保存用户Session信息,每次都去Session服务器取数据。
这种解决方案事实上是将应用服务器的状态分离,分为无状态的应用服务器和有状态的Session服务器。
对于有状态的Session服务器,一种比较简单的方式是利用分布式缓存、数据库等。
3.高可用的服务
(1)分级管理,核心应用和服务优先使用更好的硬件。
(2)超时设置,及时将请求转移到其它服务器上。
(3)异步调用,通过消息队列等异步方式完成。
(4)服务降级,网站高峰期间,可以关闭一些不重要的服务或拒绝部分服务,如评论。
(5)幂等性设计,保证重复调用和调用一次产生的结果相同。
4.高可用的数据
保证数据存储高可用的手段主要是数据备份和失效转移机制。
(1)CAP原理:
一个提供数据服务的存储系统无法同时满足数据持久性、数据可用性、分区耐受性(伸缩性)。
在大型网站中,通常会选择强化分布式存储系统的可用性(A)和伸缩性(P),而在某种程度上放弃一致性(C)。
数据强一致:
数据在物理存储总是一致的。
数据用户一致:
数据在各个副本的数据可能不一致,但是终端用户访问时,通过纠错和校验机制,可以确定一个一致的且正确的数据返回给用户。
数据最终一致:
物理存储和终端用户访问的都有可能数据不一致,但系统经过一段时间的自我恢复和修正最终会达到一致。
(2)数据备份
异步热备方式:
先同步的写主库,然后异步的写从库。
同步热备方式(Master-Slave同步机制):
为了提高性能,可并发的写多份数据库,等待所有存储服务器都返回写成功后通知应用程序操作成功。
读写分离:
写操作只访问Master库,读操作只访问Slave库。
(3)失效转移
失效确认:
通过心跳检测和应用程序访问失败报告确定失效。
访问转移
数据恢复
5.高可用的网站质量保证
(1)网站发布
(2)自动化测试
(3)预发布验证,与生产唯一的不同就是没有配置在负载均衡服务器上。
谨慎修改生产数据。
(4)快速失败,如果系统在启动时发现问题就立刻抛出异常,停止启动让工程师介入排查错误,而不是启动后执行错误的操作。
(5)代码控制(Git正逐步取代SVN的地位)
主干开发、分支发布,发布需要注释掉未完成的功能。
分支开发、主干发布
(6)自动化发布
(7)灰度发布,将集群服务器分成若干部分,每天只发布一部分服务器,观察运行稳定没有故障时接着发布其它
6.网站运行监控(Ganglia监控工具)
不允许没有监控的系统上线。
(1)监控数据采集
用户行为日志收集(服务器端和浏览器端)
服务器性能监控(CPU、内存、磁盘IO、网络IO等)
运行数据报告(缓存命中率、平均响应延迟时间、每分钟发送邮件数目、待处理的任务总数等)
(2)监控管理
监控数据采集后,除了用作系统性能评估、集群规模伸缩性预测等,还可以根据实时监控数据进行风险预警,并对服务器进行失效转移,自动负载调整,最大化利用集群所有机器的资源。
五、网站的伸缩性架构-永无止境
网站的伸缩性是指不需要改变网站的软硬件设计,仅仅通过改变部署的服务器数量就可以扩大或者缩小网站的服务处理能力。
活动期间向服务器集群中加入更多服务器,及向网络服务商租借更多的网络带宽,以满足用户访问,活动结束后又将这些服务器下线以节约成本。
1.网站架构的伸缩性设计
(1)不同功能进行物理分离实现伸缩
横向分离:
即分层后分离,将业务处理流程上的不同部分分离部署,实现系统伸缩性。
纵向分离:
即分割业务后分离,将不同的业务模块分离部署,实现系统伸缩性。
(2)单一功能通过你集群规模实现伸缩
当一头牛拉不动车的时候,不要去寻找一头更强壮的牛,而是用更多的牛。
集群伸缩性又分为应用服务器集群伸缩性和数据服务器集群伸缩性。
2.应用服务器集群的伸缩性设计
应用服务器应该设计成无状态的,任何一台服务器处理请求的结果都应该是相同的。
如果HTTP请求分发装置可以感知或者可以配置集群的服务器数量,可以及时发现集群中新上线或下线的服务器,并能向新上线的服务器分发请求 ,停止向已下线的服务器分发请求,那么就实现了应用服务器集群的伸缩性。
这个HTTP请求分发装置被称为负载均衡服务器。
(1)HTTP重定向负载均衡
HTTP重定向服务器是一台普通的应用服务器,其唯一的功能就是根据用户的HTTP请求计算一台真实的服务器地址,并将真实的服务器地址写入HTTP重定向响应中(响应状态吗302)返回给浏览器,然后浏览器再自动请求真实的服务器地址。
这种负载均衡方案的优点是比较简单。
缺点是浏览器需要每次请求两次服务器才能完成一次访问,性能较差;使用HTTP302响应吗重定向,可能是搜索引擎判断为SEO作弊,降低搜索排名。
重定向服务器自身的处理能力有可能成为瓶颈。
因此这种方案在实际使用中并不见多。
(2)DNS域名解析负载均衡
利用DNS处理域名解析请求的同时进行负载均衡。
在DNS服务器中配置多个A记录,如:
INA114.100.80.1、 INA114.100.80.2、 INA114.100.80.3。
每次域名解析请求都会根据负载均衡算法计算一个不同的IP地址返回,这样A记录中配置的多个服务器就构成一个集群,并可以实现负载均衡。
DNS域名解析负载均衡的优点是将负载均衡工作交给DNS,省略掉了网络管理维护负载均衡服务器的麻烦,同时许多DNS服务还支持基于地理位置的域名解析。
缺点是,目前的DNS是多级解析,每一级DNS都可能缓存A记录,当下线某台服务器后,即使修改了DNS的A记录,要使其生效也需要较长时间,这段时间,DNS依然会将域名解析到已经下线的服务器,导致用户访问失败,而且DNS负载均衡的控制权在域名服务商那里,网站无法对其做更多改善和更强大的管理。
事实上,大型网站总是部分使用DNS域名解析,利用域名解析作为第一级负载均衡手段,即域名解析得到一组服务器并不是实际提供的Web服务的物理服务器,而是同样提供负载均衡服务的内部服务器,这组内部负载均衡服务器再进行负载均衡,将请求分发到真实的服务器。
(3)反向代理负载均衡
反向代理服务器处于Web服务器前面,这个位置也正好是负载均衡服务器的位置,所以大多数反向代理服务器同时提供负载均衡的功能,管理一组Web服务器,将请求根据负载均衡算法转发到不同的Web服务器。
Web服务器处理完成的响应也需要通过反向代理服务器返回给用户。
由于Web服务器不直接对外提供访问,因此Web服务器不需要使用外部IP地址,而反向代理服务器则需要配置双网卡和内部外部两套IP地址。
优点是部署简单,缺点是可能成功系统的瓶颈。
(4)IP负载均衡
IP负载均衡,即在网络层通过修改请求目标地址进行负载均衡。
用户请求数据包到达负载均衡服务器后,负载均衡服务器在操作系统内核进行获取网络数据包,根据负载均衡算法计算得到一台真实的WEB服务器地址,然后将数据包的IP地址修改为真实的WEB服务器地址,不需要通过用户进程处理。
真实的WEB服务器处理完毕后,相应数据包回到负载均衡服务器,负载均衡服务器再将数据包源地址修改为自身的IP地址发送给用户浏览器。
这里的关键在于真实WEB服务器相应数据包如何返回给负载均衡服务器,一种是负载均衡服务器在修改目的IP地址的同时修改源地址,将数据包源地址改为自身的IP,即源地址转换(SNAT),另一种方案是将负载均衡服务器同时作为真实物理服务器的网关服务器,这样所有的数据都会到达负载均衡服务器。
IP负载均衡在内核进程完成数据分发,较反向代理均衡有更好的处理性能。
但由于所有请求响应的数据包都需要经过负载均衡服务器,因此负载均衡的网卡带宽成为系统的瓶颈。
(5)数据链路层负载均衡
顾名思义:
数据链路层负载均衡是指在通信协议的数据链路层修改mac地址进行负载均衡,如下图:
这种数据传输方式又称作三角传输模式,负载均衡数据分发过程中不修改IP地址,只修改目的的mac地址,通过配置真实物理服务器集群所有机器虚拟IP和负载均衡服务器IP地址一致,从而达到负载均衡,这种负载均衡方式又称为直接路由方式(DR).
用户请求到达负载均衡服务器后,负载均衡服务器将请求数据的目的mac地址修改为真是WEB服务器的mac地址,并不修改数据包目标IP地址,因此数据可以正常到达目标WEB服务器,该服务器在处理完数据后可以经过网管服务器而不是负载均衡服务器直接到达用户浏览器。
使用三角传输模式的链路层负载均衡是目前大型网站所使用的最广的一种负载均衡手段。
在linux平台上最好的链路层负载均衡开源产品是LVS(linuxvirtualserver)。
(6)负载均衡算法
负载均衡服务器的实现可以分成两个部分:
(1)根据负载均衡算法和WEB服务器列表计算得到集群中一台WEB服务器的地址;
(2)将请求数据发送到改地址对应的WEB服务器上。
常用的负载均衡算法如下几种:
(1)轮询:
即将请求依次分发到每台应用服务器上,每台服务器需要处理的请求数目都相同,适合于所有服务器硬件都相同的场景。
(2)加权轮询:
根据应用服务器硬件性能情况,在轮询的基础上,安装配置的权重将请求分发到每个服务器。
(3)随机:
将请求随机分配到各个应用服务器,好的随机数本身就很均衡。
(4)最少连接:
记录每个服务器正在处理的连接数,将新到的请求分发到最少连接的服务器上。
同时可以实现加权。
(5)原地址散列:
根据请求来源的IP地址进行Hash计算,得到应用服务器,这样来自同一个IP地址请求总在同一个服务器上处理。
3.分布式缓存集群的伸缩性设计
分布式缓存集群伸缩性设计的最主要目标即:
必须让新上线的缓存服务器对整个分布式缓存集群影响最小,也就是说新加入缓存服务器后应使整个缓存服务器集群中已经缓存的数据尽可能还被访问到。
(1)余数Hash
余数Hash可以保证缓存数据在整个缓存服务器集群中比较均衡地分布。
如果不需要考虑缓存服务器集群伸缩性,余数Hash乎能满足绝大多数的缓存路由需求。
余数Hash伸缩时改变机器数量(除数)使缓存节点几乎不能命中。
一种解决办法是在网站访问量最小的时候扩容缓存服务器集群,这时候对数据库的负载冲击最小。
然后通过模拟请求的方法逐渐预热缓存,使缓存中的数据重新分布,但需要技术团队通宵加班。
(2)分布式缓存的一致性Hash算法
一致性hash算法通过一个叫做一致性hash环的数据结构实现KEY到缓存服务器的Hash映射。
具体算法过程为:
先构造一个长度为二的32次方的整数环,根据节点名称的Hash值(0~2的31次方)将缓存服务器节点放置在这个Hash环上。
然后根据需要缓存的数据的KEY值计算得到其Hash值,然后在Hash环上顺时针查找距离这个KEY的Hash值最近的缓存服务器节点,完成KEY到服务器的Hash映射查找。
由于KEY是顺时针查找距离其最近的节点,因此伸缩时新加入一个节点只影响整个环中的一小段。
如果使用直接查找节点,那么当新添加一台缓存服务器时,只是影响到了其中一台缓存服务器,其他两头缓存服务器的压力并没有得到缓解,因此此方案还是存在问题。
一种替代的方案就是增加一个虚拟层,即把每台缓存服务器虚拟为一组服务器平均放到上面的环里面。
这样当新增加缓存服务器时,把新增加的虚拟节点平均分配到环中,这样就能缓解每台缓存服务器,达到分布式缓存集群高伸缩性。
一般,一台物理服务器虚拟为150个虚拟服务器合适。
计算机的任何问题都可以通过增加一个虚礼层来解决。
4.数据存储服务器集群的伸缩性设计
和缓存服务器集群的伸缩性设计不同,数据存储服务器集群的伸缩性对数据的持久性和可用性提出了更高的要求。
(1)关系数据库集群的伸缩性设计
主要的关系数据库都支持数据复制功能,使用这个功能可以对数据库进行简单伸缩。
数据库主从读写分离外;
利用业务分隔模式使不同业务的数据表部署在不同的数据库集群上,即俗称的数据分库。
但是这种方式的制约条件时跨库不能进行join操作。
对一些单表数据任然很大的表还需要进行分片,将一张表拆开分别存储在多个数据库中。
目前支持分布式数据分片的关系数据库产品主要有开源的Amoeba和Cobar(阿里巴巴),下图为Cobar部署模型。
Cobar是一个分布式关系数据库访问代理,介于应用服务器和数据库服务器之间。
应用程序通过JDBC驱动访问Cobar集群,Cobar服务器根据SQL和分库规则分解SQL,分发到MySQL集群不同的数据库实例上执行(每个MySQL实例都部署为主/从结构,保证数据高可用)。
前端通信模块负责和应用程序通信,接搜到SQL请求(select*fromuserswhereuseridin(12,22,23))后转交给SQL解析模块,SQL解析模块解析获得SQL中的路由规则查询条件(useridin(12,22,23))再转交给 SQL路由模块,SQL路由模块根据路由规则配置(userid为偶数路由至数据库A,奇数则路由至数据库B)将应用程序提交的SQL分解成两条SQL(select*fromuserswhereuseridin(12,22);select*fromuserswhereuseridin(23))转交给SQL执行代理模块,发送至数据库A和数据库B分别执行。
数据库A和数据库B的执行结果返回至SQL执行模块,通过结果合并模块将两个返回结果集合并成一个结果集,最终返回该应用程序,完成在分布式关系数据库中的一次访问请求。
Cobar的伸缩有两点:
Cobar服务器集群的伸缩和MySQL服务器集群的伸缩。
Cobar服务器可以看做是无状态的应用服务器,因此其集群伸缩可以简单实用负载均衡的手段实现。
而MySQL中存储着数据,要保证集群扩容后数据一致负载均衡,必须要做数据迁移,如下图(利用数据同步功能进行数据迁移)。
(2)NoSQL数据库的伸缩设计
NoSQL主要是指非关系的、分布式的数据库设计模式。
一般而言,NoSQL数据库产品都放弃了关系数据库的两大重要基础:
以关系代数为基础的结构化查询语言(SQL)和事物一致性保证(ACID),而强化了高可用性和可伸缩性。
目前应用最广泛的是ApacheHBase。
HBase的伸缩性主要依赖其可分裂的HRegion及可伸缩的分布式文件系统HDFS实现。
HBase中,数据以HRegion为单位进行管理,应用程序如果想要访问一个数据,必须先找到HRegion,然后将数据读写操作提交给HRegion,由HRegion完成存储层面的数据操作。
每个HRegion中存储一段Key值区间(k1~k2)的数据,HRegionServer是物理服务器,每个HRegionServer上可以启动多个HRegion实例,当一个HRegion中写入的数据太多,达到配置的阈值时,HRegion会分裂成两个HRegion,并将HRegion在整个集群中进行迁移,以使HRegionServer负载均衡。
所有的HRegion的信息都记录在HMaser服务上,为了保证高可用性,HBase启动多个HMaser,并通过Zookeeper选举一个Master,应用程序通过Zookeeper获得主HMaser的地址,输入Key值获得这个Key所在的HRegionServer地址,然后请求HRegionServer上的HRegion,获得需要的数据。
六、网站的可扩展架构-随需应变
扩展性是指对现有系统影响最小的情况下,系统功能可持续扩展或提升的能力。
表现在系统基础设施不需要经常变更,应用之间较少依赖和耦合,对需求变更可以敏捷响应。
它是系统架构设计层面的开闭原则(对扩展开放,对修改关闭),架构设计考虑未来功能扩展,当系统增加新功能时,不需要对现有系统的结构和代码进行修改。
软件架构师最大的价值不在于掌握多少先进的技术,而在于具有将一个大系统切分成N个低耦合的子模块的能力,这些子模块包含横向的业务模块,也包含纵向的基础技术模块。
设计网站可扩展架构的核心思想是模块化,并在此基础上,降低模块间的耦合性,提供模块的复用性。
模块通过分布式部署,独立的模块部署在独立的服务器上(集群)从物理上分离模块之间的耦合关系。
1.利用分布式消息队列降低系统耦合性
事件驱动框架:
通过在低耦合的模块之间传输事件消息,以保持模块的松散耦合,并借助事件消息的通信完成模块间合作,典型的架构就是生产者消费者模式。
在大型网站架构中,具体实现手段很多,最常用的就是分布式消息队列。
消息队列利用发布-订阅模式工作,消息发送者发布消息,一个或者多个消息接收者订阅消息。
由于消息发送者不需要等待消息接受者处理数据就可以返回,系统具有更好的响应延迟;同时,在网站访问高峰,消息可以暂时存储在消息队列中等待处理,减轻数据库等后端存储的负载压力。
目前开源的和商业的分布式消息队列产品有很多,比较著名的有ApacheActiveMQ等。
2.利用分布式服务打造可复用的业务平台
分布式服务则通过接口分解系统耦合性,不同子系统通过相同的接口描述进行服务调用。
巨无霸应用存在的问题:
编译、部署困难,代码分支管理困难,数据库连接耗尽,新增业务困难。
解决方案就是拆分,将模块独立部署,降低系统耦合性。
(1)WebService
WebService用以整合异构系统及构建分布式系统。
服务提供者通过WSDL(Web服务描述语言)向注册中心描述自身提供的服务接口属性,注册中心使用UDDI(统一描述、发现和集成)发布服务提供者提供的服务,服务请求者从注册中心检索到服务信息后,通过SOAP(简单对象协议)和服务提供者通信,使用相关服务。
缺点是注册与发现机制臃肿,低效的XML序列化手段,开销相对较高的HTTP远程通信,复杂的部署与维护手段。
(2)大型网站分布式服务的需求与特点
负载均衡
失效转移
高效的远程通信
整合异构系统
对应用最小入侵
版本管理,同时部署新老版本
实时监控
(3)分布式服务框架设计
目前国内有较多成功实施案例的开源分布式服务框架是阿里巴巴的Dubbo。
服务框架客户端模块通过服务注册中心加载服务提供者列表(服务提供者启动后主动向服务注册中心注册自己可提供的服务接口列表),查找需要的服务接口,并根据配置的负载均衡策略将服务调用请求发送到某台服务提供者服务器。
如果服务调用失败,客户端模块会自动从服务提供者列表选择一个可提供同样服务的另一台服务器重新请求服务,实现服务的自动失效转移,保证高可用服务。
3.可扩展的数据结构
NoSQL数据库的ColumnFamily(列族)设计就是一个解决方案。
在创建表的时候,只需要指定ColumnFamily的名字,无需指定字段Column,可以在数据写入时指定,这种结构使得应用程序的数据结构可以随意扩展。
4.利用开放平台建设网站生态圈
网站必须提供更多的增值服务才能赚钱。
大型网站为了更好的服务自己的用户,开放更多的增值服务,会把网站内部的服务封装成一些调用接口开放出去,供外部的第三方开发者使用,这个提供开放接口平台被称作开放平台。
网站、用户、第三方开发者互相依赖,形成一个网站的生态圈。
具体可包含