4 瞬时响应:网站的高性能架构
网站性能是客观的指标,可以具体体现到响应时间、吞吐量等技术指标,
同时也是主观的感受,而感受则是一种与具体参与者相关的微妙的东西,用户的感受和工程师的感受不同,不同的用户感受也不同。
网站性能测试
不同视角下的网站
- 用户视角
网站性能就是用户在浏览器上直观感受到的网站响应速度快还是慢。用户感受到的时间,包括用户计算机和网站服务器通信的时间、网站服务器处理的时间、用户计算机浏览器构造请求解析响应数据的时间 - 开发人员视角
开发人员关注的主要是应用程序本身及其相关子系统的性能,包括响应延迟、系统吞吐量、并发处理能力、系统稳定性等技术指标。
主要的优化手段有使用缓存加速数据读取,使用集群提高吞吐能力,使用异步消息加快请求响应及实现削峰,使用代码优化手段改善程序性能。 - 运维人员视角
运维人员更关注基础设施性能和资源利用率,如网络运营商的带宽能力、服务器硬件的配置、数据中心网络架构、服务器和网络带宽的资源利用率等。主要优化手段有建设优化骨干网、使用高性价比定制服务器、利用虚拟化技术优化资源利用等。
性能测试指标
开发和测试人员角度
- 响应时间
应用执行一个操作需要的时间,包括从发出请求开始到收到最后响应数据所需要的时间。 - 并发数
系统能够同时处理请求的数目,这个数字也反映了系统的负载特性。
测试程序通过多线程模拟并发用户的办法来测试系统的并发处理能力,为了真实模拟用户行为,测试程序并不是启动多线程然后不停地发送请求,而是在两次请求之间加入一个随机等待时间,这个时间被称作思考时间。
- 吞吐量
指单位时间内系统处理的请求数量,体现系统的整体处理能力。
常见的量化指标
TPS:每秒事务数
HPS:每秒HTTP请求数
QPS:每秒查询数
在系统并发数由小逐渐增大的过程中(这个过程也伴随着服务器系统资源消耗逐渐增大)
系统吞吐量先是逐渐增加,达到一个极限后,随着并发数的增加反而下降,达到系统崩溃点后,系统资源耗尽,吞吐量为零。而这个过程中,响应时间则是先保持小幅上升,到达吞吐量极限后,快速上升,到达系统崩溃点后,系统失去响应。
- 性能计数器
它是描述服务器或操作系统性能的一些数据指标。包括System Load、对象与线程数、内存使用、CPU使用、磁盘与网络I/O等指标。
System Load即系统负载,指当前正在被CPU执行和等待被CPU执行的进程数目总和,是反映系统忙闲程度的重要指标
- 性能测试方法
性能测试:以系统设计初期规划的性能指标为预期目标,对系统不断施加压力,验证系统在资源可接受范围内,是否能达到性能预期。
负载测试:对系统不断地增加并发请求以增加系统压力,直到系统的某项或多项性能指标达到安全临界值
压力测试:超过安全负载的情况下,对系统继续施加压力,直到系统崩溃或不能再处理任何请求,以此获得系统最大压力承受能力。
稳定性测试:被测试系统在特定硬件、软件、网络环境条件下,给系统加载一定业务压力,使系统运行一段较长时间,以此检测系统是否稳定。
在开始阶段,随着并发请求数目的增加,系统使用较少的资源就达到较好的处理能力(a~b段),这一段是网站的日常运行区间,网站的绝大部分访问负载压力都集中在这一段区间,被称作性能测试,测试目标是评估系统性能是否符合需求及设计目标;
随着压力的持续增加,系统处理能力增加变缓,直到达到一个最大值(c点),这是系统的最大负载点,这一段被称作负载测试。测试目标是评估当系统因为突发事件超出日常访问压力的情况下,保证系统正常运行情况下能够承受的最大访问负载压力;
超过这个点后,再增加压力,系统的处理能力反而下降,而资源消耗却更多,直到资源消耗达到极限(d点),这个点可以看作是系统的崩溃点,超过这个点继续加大并发请求数目,系统不能再处理任何请求,这一段被称作压力测试,测试目标是评估可能导致系统崩溃的最大访问负载压力。
性能测试反应的是系统在实际生产环境中使用时,随着用户并发访问数量的增加,系统的处理能力。与性能曲线相对应的是用户访问的等待时间(系统响应时间)
在日常运行区间,可以获得最好的用户响应时间,随着并发用户数的增加,响应延迟越来越大,直到系统崩溃,用户失去响应。
性能优化策略
- 性能分析
大型网站结构复杂,用户从浏览器发出请求直到数据库完成操作事务,中间需要经过很多环节,如果测试或者用户报告网站响应缓慢,存在性能问题,必须对请求经历的各个环节进行分析,排查可能出现性能瓶颈的地方,定位问题。
排查一个网站的性能瓶颈和排查一个程序的性能瓶颈的手法基本相同:
- 检查请求处理的各个环节的日志,分析哪个环节响应时间不合理、超过预期;
- 然后检查监控数据,分析影响性能的主要因素是内存、磁盘、网络、还是CPU,是代码问题还是架构设计不合理,或者系统资源确实不足。
- 性能优化
根据网站分层架构性能优化可以分为3大类:
Web前端性能优化、应用服务器性能优化、存储服务器性能优化
Web前端性能优化
浏览器访问优化
CDN加速
反向代理
应用服务器性能优化
应用服务器就是处理网站业务的服务器,网站的业务代码都部署在这里,是网站开发最复杂,变化最多的地方,优化手段主要有缓存、集群、异步等。
分布式缓存
合理使用缓存
分布式缓存架构
异步操作
使用集群
代码优化
存储性能优化
机械硬盘vs. 固态硬盘
B+树vs.LSM树
RAID vs.HDFS
5 网站的高可用架构
高可用的网站架构
网站的高可用架构设计的主要目的就是保证服务器硬件故障时服务依然可用、数据依然保存并能够被访问。
实现上述高可用架构的主要手段是数据和服务的冗余备份及失效转移
一旦某些服务器宕机,就将服务切换到其他可用的服务器上,如果磁盘损坏,则从备份的磁盘读取数据。
典型的分层模型是三层,即应用层、服务层、数据层;各层之间具有相对独立性,应用层主要负责具体业务逻辑处理;服务层负责提供可复用的服务;数据层负责数据的存储与访问。
位于应用层的服务器通常为了应对高并发的访问请求,会通过负载均衡设备将一组服务器组成一个集群共同对外提供服务,当负载均衡设备通过心跳检测等手段监控到某台应用服务器不可用时,就将其从集群列表中剔除,并将请求分发到集群中其他可用的服务器上,使整个集群保持可用,从而实现应用高可用。
位于服务层的服务器情况和应用层的服务器类似,也是通过集群方式实现高可用,只是这些服务器被应用层通过分布式服务调用框架访问,分布式服务调用框架会在应用层客户端程序中实现软件负载均衡,并通过服务注册中心对提供服务的服务器进行心跳检测,发现有服务不可用,立即通知客户端程序修改服务访问列表,剔除不可用的服务器。
位于数据层的服务器情况比较特殊,数据服务器上存储着数据,为了保证服务器宕机时数据不丢失,数据访问服务不中断,需要在数据写入时进行数据同步复制,将数据写入多台服务器上,实现数据冗余备份。当数据服务器宕机时,应用程序将访问切换到有备份数据的服务器上。
高可用的应用
- 通过负载均衡进行无状态服务的失效转移
负载均衡,顾名思义,主要使用在业务量和数据量较高的情况下,当单台服务器不足以承担所有的负载压力时,通过负载均衡手段,将流量和数据分摊到一个集群组成的多台服务器上,以提高整体的负载处理能力 - 应用服务器集群的Session管理
应用服务器的高可用架构设计主要基于服务无状态这一特性,但是事实上,业务总是有状态的
Web应用中将这些多次请求修改使用的上下文对象称作会话(Session),单机情况下,Session可由部署在服务器上的Web容器(如JBoss)管理。
在使用负载均衡的集群环境中,由于负载均衡服务器可能会将请求分发到集群任何一台应用服务器上,所以保证每次请求依然能够获得正确的Session比单机时要复杂很多。
集群环境下,Session管理主要有以下几种手段:
- Session复制
应用服务器开启Web容器的Session复制功能,在集群中的几台服务器之间同步Session对象,使得每台服务器上都保存所有用户的Session信息,这样任何一台机器宕机都不会导致Session数据的丢失,而服务器使用Session时,也只需要在本机获取即可。
当集群规模较大时,集群服务器间需要大量的通信进行Session复制,占用服务器和网络的大量资源,系统不堪负担。而且由于所有用户的Session信息在每台服务器上都有备份,在大量用户访问的情况下,甚至会出现服务器内存不够Session使用的情况。 - Session绑定
Session绑定可以利用负载均衡的源地址Hash算法实现,负载均衡服务器总是将来源于同一IP的请求分发到同一台服务器上
Session绑定的方案显然不符合我们对系统高可用的需求,因为一旦某台服务器宕机,那么该机器上的Session也就不复存在了,用户请求切换到其他机器后因为没有Session而无法完成业务处理。 - 利用Cookie记录Session
将Session记录在客户端,每次请求服务器的时候,将Session放在请求中发送给服务器,服务器处理完请求后再将修改过的Session响应给客户端。网站没有客户端,但是可以利用浏览器支持的Cookie记录Session
受Cookie大小限制,能记录的信息有限;每次请求响应都需要传输Cookie,影响性能;如果用户关闭Cookie,访问就会不正常。
但是由于Cookie的简单易用,可用性高,支持应用服务器的线性伸缩,而大部分应用需要记录的Session信息又比较小。因此事实上,许多网站都或多或少地使用Cookie记录Session。 - Session服务器
利用独立部署的Session服务器(集群)统一管理Session,应用服务器每次读写Session时,都访问Session服务器
高可用的服务
可复用的服务模块为业务产品提供基础公共服务,大型网站中这些服务通常都独立分布式部署,被具体应用远程调用。可复用的服务和应用一样,也是无状态的服务,因此可以使用类似负载均衡的失效转移策略实现高可用的服务。
除此之外,具体实践中,还有以下几点高可用的服务策略。
- 分级管理
运维上将服务器进行分级管理,核心应用和服务优先使用更好的硬件,在运维响应速度上也格外迅速。 - 超时设置
由于服务端宕机、线程死锁等原因,可能导致应用程序对服务端的调用失去响应,进而导致用户请求长时间得不到响应,同时还占用应用程序的资源,不利于及时将访问请求转移到正常的服务器上。
在应用程序中设置服务调用的超时时间,一旦超时,通信框架就抛出异常,应用程序根据服务调度策略,可选择继续重试或将请求转移到提供相同服务的其他服务器上。 - 异步调用
- 服务降级
- 幂等性设计
服务重复调用是无法避免的,应用层也不需要关心服务是否真的失败,只要没有收到调用成功的响应,就可以认为调用失败,并重试服务调用。因此必须在服务层保证服务重复调用和调用一次产生的结果相同,即服务具有幂等性。
高可用的数据
不同于高可用的应用和服务,由于数据存储服务器上保存的数据不同,当某台服务器宕机的时候,数据访问请求不能任意切换到集群中其他的机器上。
保证数据存储高可用的手段主要是数据备份和失效转移机制。
- CAP原理
- 数据持久性
保证数据可持久存储,在各种情况下都不会出现数据丢失的问题。为了实现数据的持久性,不但在写入数据时需要写入持久性存储,还需要将数据备份一个或多个副本,存放在不同的物理存储设备上,在某个存储故障或灾害发生时,数据不会丢失。 - 数据可访问性
在多份数据副本分别存放在不同存储设备的情况下,如果一个数据存储设备损坏,就需要将数据访问切换到另一个数据存储设备上,如果这个过程不能很快完成(终端用户几乎没有感知),或者在完成过程中需要停止终端用户访问数据,那么这段时间数据是不可访问的。 - 数据一致性
在数据有多份副本的情况下,如果网络、服务器或者软件出现故障,会导致部分副本写入成功,部分副本写入失败。这就会造成各个副本之间的数据不一致,数据内容冲突。实践中,导致数据不一致的情形有很多种,表现形式也多种多样,比如数据更新返回操作失败,事实上数据在存储服务器已经更新成功。
CAP原理认为,一个提供数据服务的存储系统无法同时满足数据一致性(Consistency)、数据可用性(Availibility)、分区耐受性(PatitionTolerance,系统具有跨网络分区的伸缩性)这三个条件
在大型网站应用中,数据规模总是快速扩张的,因此可伸缩性即分区耐受性必不可少,规模变大以后,机器数量也会变得庞大,这时网络和服务器故障会频繁出现,要想保证应用可用,就必须保证分布式处理系统的高可用性。
所以在大型网站中,通常会选择强化分布式存储系统的可用性(A)和伸缩性(P),而在某种程度上放弃一致性(C)
数据一致性又可分为如下几点。
- 数据强一致
各个副本的数据在物理存储中总是一致的;数据更新操作结果和操作响应总是一致的,即操作响应通知更新失败,那么数据一定没有被更新,而不是处于不确定状态。 - 数据用户一致
即数据在物理存储中的各个副本的数据可能是不一致的,但是终端用户访问时,通过纠错和校验机制,可以确定一个一致的且正确的数据返回给用户。 - 数据最终一致
这是数据一致性中较弱的一种,即物理存储的数据可能是不一致的,终端用户访问到的数据可能也是不一致的(同一用户连续访问,结果不同;或者不同用户同时访问,结果不同),但系统经过一段时间(通常是一个比较短的时间段)的自我恢复和修正,数据最终会达到一致。
因为难以满足数据强一致性,网站通常会综合成本、技术、业务场景等条件,结合应用服务和其他的数据监控与纠错功能,使存储系统达到用户一致,保证最终用户访问数据的正确性。
- 数据备份
-
数据冷备----即定期将数据复制到某种存储介质
冷备的优点是简单和廉价,成本和技术难度都较低。
缺点是不能保证数据最终一致,由于数据是定期复制,因此备份设备中的数据比系统中的数据陈旧,如果系统数据丢失,那么从上个备份点开始后更新的数据就会永久丢失,不能从备份中恢复。
同时也不能保证数据可用性,从冷备存储中恢复数据需要较长的时间,而这段时间无法访问数据,系统也不可用。 -
数据热备可分为两种:异步热备方式和同步热备方式。
异步方式是指多份数据副本的写入操作异步完成,应用程序收到数据服务系统的写操作成功响应时,只写成功了一份,存储系统将会异步地写其他副本(这个过程有可能会失败)
同步方式是指多份数据副本的写入操作同步完成,即应用程序收到数据服务系统的写成功响应时,多份数据都已经写操作成功。但是当应用程序收到数据写操作失败的响应时,可能有部分副本或者全部副本都已经写成功了(因为网络或者系统故障,无法返回操作成功的响应)
- 失效转移
失效转移操作由三部分组成:失效确认、访问转移、数据恢复。
- 失效确认
判断服务器宕机是系统进行失效转移的第一步,系统确认一台服务器是否宕机的手段有两种:心跳检测和应用程序访问失败报告
对于应用程序的访问失败报告,控制中心还需要再一次发送心跳检测进行确认,以免错误判断服务器宕机,因为一旦进行数据访问的失效转移,就意味着数据存储多份副本不一致,需要进行后续一系列复杂的操作。 - 访问转移
确认某台数据存储服务器宕机后,就需要将数据读写访问重新路由到其他服务器上。 - 数据恢复
数据恢复因为某台服务器宕机,所以数据存储的副本数目会减少,必须将副本的数目恢复到系统设定的值,否则,再有服务器宕机时,就可能出现无法访问转移(所有副本的服务器都宕机了),数据永久丢失的情况。因此系统需要从健康的服务器复制数据,将数据副本数目恢复到设定值。