高可靠性的构建依赖于以下几方面,首先是实际的业务需求和支撑的理论,可靠性需要量化的指标和实施模型;其次是可靠性的设计作为手段;最后是常用的实践模式,包括负载均衡、集群、双机热备及异地容灾。
一般来说,对服务系统考察的是系统总体的可用性,即系统不间断地持续提供服务的能力,而对终端系统,一般采用可靠性来评估系统稳定提供功能、不出现错误的能力。如前所述,对于云服务系统,系统可用性要求比传统软件要高,业界要求的最高水平是99.99%的可用性。
由于系统可用性计算的是正常系统提供服务时间占系统服务时间的比例,对于99.99%的可用性指标,即一个月中断服务时间要少于5min,中断服务时间包含维护、升级时间,对于一个6个月维护一次的云服务系统,如果维护需要中断服务,系统完成维护周期为1h,那么系统可用性指标就降低到了99.97%,如果系统升级也要中断服务,那么系统可用性指标将不会超过99.9%,因此在云服务架构时,根据可用性指标要求,要考虑到系统维护、升级等对系统可用性的影响,要考虑升级与扩展,甚至维护都能不间断服务。
在系统架构时,首先要建立可靠性模型,要区分串联和并联因素。假设系统 V 有两个子系统,其可用性分别是 V 1 和 V 2 ,并且 V 1 = V 2 =99.99%。
如果系统中的两个子系统,无论哪个子系统失败都导致系统失败,在可靠性模型中就是串联的。系统可用性
V = V 1 × V 2 =99.98%
如果系统中两个子系统,其中一个失败并不导致系统失败,只有两个同时失败,才导致系统失败,在可靠性模型中是并联。系统可用性
V =1-(1- V 1 )×(1- V 2 )=99.999 999%
因此,在实际部署中,一般使用并联方式,如备份、集群等方式,以提升系统可用性。
以一个传统Web服务系统为例,在可靠性模型中(见图3-1),互联网接入、路由器、交换机、前端Apache服务器、应用服务器和数据库服务器,是一个串联系统,一般来讲,路由器、交换机有99.9996%以上的可用性,互联网单接入网络的可用性为99.9%,而Web、App、DataBase服务器可用性可达到99.9%,系统可用性是
V =99.9%×99.9996%×99.9996%×99.9%×99.9%×99.9%=99.6%
如果以99.99%可用性为目标,直接建立一个备份系统,系统可靠度:
V =1-(1-99.6%)×(1-99.6%)=99.9984%
可见系统可用性指标可达99.998%,就能达到系统的可用性指标,其方式表示如图3-2所示。
这使得服务系统达到要求,但确实不是一个很经济的模型。同时,这种模式也引入了不少问题,如数据库同步,用户如何同时接入,等等。因此在常见系统中,采用混合(meshed)接入方式,让接入有备份,而且用户看到的地址是统一地址,路由和交换有备用系统,能够随时切换,Apache采用HA热备,AppServer在Apache作用下采用双机集群,而数据库采用HA热备模型,系统模型就变成了如图3-3所示的模式。
图3-1 云服务可靠性模型图(1)
图3-2 云服务可靠性模型图(2)
其计算相对复杂一些:
V =[1-(1-99.9%)×(1-99.9%)]×99.9996%×99.9996%× [1-(1-99.9%)×(1-99.9%)]×[1-(1-99.9%)×(1-99.9%)]× [1-(1-99.9%)×(1-99.9%)] =99.998%
这个模式也达到可用性指标,但更实用。
在构建高可用度云服务系统时,首先考虑各个实现环节的关系,一般在架构设计时,根据可靠性指标,综合考虑系统可靠性、成本等诸多因素,先要从理论上保障可靠性指标在各个环节分配合理性,主要考虑关键节点,通过多冗余保障系统可靠性,设计时还要考虑在升级与维护时,系统仍然可以提供服务。
图3-3 云服务可靠性模型图(3)
系统设计时,对可靠性首先要建立相应的可靠性模型,在模型层面,将指标分配到各子系统,再考虑各子系统能否完成可靠性指标。要按照每个环节的实际能力来分配可用性指标。
比如一个单机程序,持续一个月不停止服务的概率是很低的,假如其一个月需要维护一次,比如服务重启,需要停止2~3min,而半年需要服务器重启,需要4~5min,这样一来,光是因为维护,服务的可用性就降低到99.99%的水平。再加上各种故障时间,包括软硬件故障、网络故障、电源故障等,单机系统能够到99.9%就已经非常高了。
在分配指标时,由于仅仅有一个总体可用性指标,而系统环节很多,变量很多,例如上面的Web服务,有互联网接入、路由、交换、Apache、应用服务器、数据库6个环节,仅仅知道要达到99.99%,根据可用性模型,还是计算不出每个环节的可用性数据,对最后一个模型,可以知道方程式是
99.99%=[1-(1- V 互联网接入 )×(1- V 互联网接入 )]× V 路由 × V 交换 × [1-(1- V Apache )×(1- V Apache )]× [1-(1- V App )×(1- V App )]× [1-(1- V Database )×(1- V Database )]
首先排除技术运营积累因素,比如路由和交换环节,公司使用路由服务累积数据时为99.996%,而Apache和数据库是公用服务,可靠性也是累积的,比如单机是99.9%,这样代入以后,剩余的因素可以求出: V App 至少要达到99.6%。
但如果一个系统的开发环节不止一个,问题就再度复杂,要判断这些系统的可靠性,就需要有合理模型,常见方式包括:
· 经验模型:例如对使用Tomcat或JBoss服务器作为底层的应用服务,根据积累的经验值,例如单机在同等规模时,可以达到99.8%。
· 规模比例:预估开发规模,其可用性与规模成反比。
· 等值法:假设开发系统可用性值相等,算出相应值,对于实际不能达到的,通过将可能的值代入,再求解其他值,直到每个值都能满足要求。
建立可靠性模型,在建立过程中可能需要多次调整,如果计算出,可靠性无法实现,则需按照前面提到的增加并联,降低节点可靠性指标的方法,重新调整模型,再进行计算,直到系统需求得到满足,各个节点的可靠性指标合理、可实现。
云服务平台可用性设计要考虑到以下因素,才能完成高可用系统指标。
(1)任何一个环节中的任意一台服务器的故障,仅仅影响系统容量,不会引起系统故障。这就要求在系统设计中不能出现单故障点(Single Point of Failure,SPOF),所有环节都有备份或冗余。
(2)当一个服务器出现故障,用户能够被其他服务器接管,保障系统服务能够持续。
(3)在维护时,对每个服务分别按照时间计划维护,如同一台服务器出现故障一样,不会引起系统故障,确保系统维护时间内服务仍能照常提供。
(4)在升级时,应考虑逐个升级,避免服务中断,因此新旧版本之间的兼容性要能很好地解决,保证两个版本之间的兼容性。
(5)容灾考虑,如果有容灾备份,在升级时,系统先转向灾备系统,先对服务系统升级,再升级灾备。同样,在升级灾备系统前,切换到实际系统。这样能实现在系统升级过程中不间断服务。同样的方式可以在生产线出故障时使用。
提升系统可用性,使用较多的方案是集群和负载均衡,该方案一方面可以消除系统中的单故障点,另一方面可以提高系统的扩展能力。通过将服务部署到多台机器上,每台机器都能对外提供相同的功能,这样多台机器就组成一个集群(cluster)对外提供服务,如图3-4所示。
图3-4 系统负载均衡示意
集群环境通常会引入负载均衡技术,用户的请求不直接发送到集群中,而是由负载均衡机器接收,并根据一定的策略转发到集群中的业务机器上,其优势在于:
· 用户请求不直接和业务机器交互,系统的伸缩性通过在服务集群中加入和删除一个节点来达到,理论上可以无限扩展。
· 负载均衡器可以将请求动态分配到业务机器上,整个集群结构对用户透明,技术运营人员可以对节点进行实时监控并及时进行故障处理,使系统达到高可用。
负载均衡实现可以分为硬件方式和软件方式。
(1)硬件方式:通常称为负载均衡器,安装在服务器和外部网络之间,具有以下特点。
· 性能好。
· 负载均衡策略多样化。
· 流量管理智能化。
· 价格昂贵。
在硬件产品领域,有一些知名的产品可以选择,如Alteon、F5等,能够提供非常优秀的性能和灵活的管理能力。
(2)软件方式:通过软件来实现负载均衡,具有以下特点。
· 成本低廉,多为开源产品,如LVS。
· 成熟稳定、配置简单、使用灵活。
· 效率较硬件方式低,消耗部分系统资源。
双机热备(hot-standby)从概念上来讲,属于集群的一种。为了保障业务的连续性,不允许服务存在单点,但建立集群又太复杂,这时候可采用双机热备技术。
双机热备技术(见图3-5)是一种软硬件结合的服务容错方案,通常由两台服务器系统和一个外接共享磁盘队列柜及相应的软件组成。“故障隔离”是双机热备的工作原理,通过主动转移故障点来保障业务的连续性,双机热备本身不具有修复故障的功能,只是将服务转移到备用服务器上。“故障检测”是双机热备的一项任务,采用“心跳”方法来保证主系统和备用系统的联系。
图3-5 系统层的双机热备技术
双机热备的工作模式主要有主备模式、双机互备模式和双机双工模式。
双机热备的数据共享的实现方式主要有基于共享存储(磁盘阵列)和基于数据复制。
容灾系统(Disaster Recovery,DR)是指在相隔较远的异地,建立两套或多套功能相同的系统,相互之间可以进行健康状态监视和功能切换,当一处系统因意外(如火灾、地震等)停止工作时,整个应用系统可以切换到另一处,使得该系统可以继续正常工作。如图3-6所示。其中的GSLB(Global Server Load Balance,全局负载均衡)是一个网络层的异地高可用技术。
图3-6 数据中心级别的灾备系统示意
IDC即数据中心,比如IDC 1表示北京数据中心,IDC 2表示上海数据中心。如图3-6所示,各IDC之间互为备份。
容灾系统从实现的层次来分,可以分为数据级容灾和业务级(也称应用级)容灾。
(1)数据级容灾的关注点在于数据本身,在灾难发生后要确保原有的数据不会丢失或者遭到破坏,但是数据级容灾发生灾难时应用是会中断的,数据级容灾在技术上、流程上还不能保证应用、业务的高可用性。
(2)业务级容灾是在数据级容灾的基础上,在备份站点同样构建一套相同的应用系统,这样可以保证应用在允许的时间范围内恢复运行,尽可能减少灾难带来的损失,让用户基本感受不到灾难的发生。
容灾除了需要成熟的软、硬件解决方案外,关键在于容灾与业务的紧密结合,这对投入和管理能力要求都比较高。下面进行具体讲述。
RPO(Recovery Point Objective,复原时间目标)是指灾难发生后,容灾系统能够把数据恢复到灾难发生前的时间点的数据,它是衡量租户在灾难发生后会丢失多少生产数据的指标。
RTO(Recovery Time Objective,恢复时间目标)是指灾难发生后,从系统宕机导致业务停顿之刻开始,到系统恢复至可以支持业务部门运作,业务恢复运营之时,此两点之间的时间。
RPO可简单地描述为用户能容忍的最大数据丢失量,RTO可简单地描述为用户能容忍的恢复时间。理想状态下,希望RTO=0,RPO=0,即灾难发生对用户毫无影响,既不会导致生产停顿,也不会导致生产数据丢失。但显然这很难,能做到的是尽量减少灾难造成的损失。
数据级容灾主要是指数据同步,如文件、数据库数据、内存状态等。数据同步实现的程度,决定了容灾方案最后的效果和能够实现的程度。
对于文件资源,实时地将主站(Active)的数据同步到备用站点(Standby),如图3-7所示。
图3-7 系统层的数据同步系统
数据库同步是将一个正在运行的数据库系统中的数据实时或准实时地同步到另外的一个或者多个数据库上,相对于数据库备份,它的实时性更强,如图3-8所示。
复制监控包括两部分:站点内部DB-HA的MySQL服务器状态监控,自动进行故障切换(维护虚拟IP(VIP)和真实IP的对应关系);站点之间MySQL复制状态监控和维护。每个DB cluster可以有一个或者多个MySQL服务器之间的数据同步通过循环复制实现。应用通过虚拟IP来访问数据库,虚拟IP和真实IP所对应的物理数据库的对应关系是1∶1或者1∶ n 的关系。通过维护虚拟IP和真实IP的对应关系来实现自动的故障切换,对应用透明。负载均衡通过不同的应用连接不同的虚拟IP来实现,对应用不透明。
应用级容灾是在数据级容灾的基础上,在异地建立一套完整的与本地生产系统相当的备份应用系统(可以是互为备份或者全局负载均衡模式)。图3-9所示为硬件GSLB的实现示意图。
图3-8 数据库层(Database Level)数据同步系统
图3-9 应用层容灾架构(Application Level Disaster Recovery Structure)
GSLB的目的是实现在广域网(包括互联网)上不同地域的服务器间的流量调配,保证用户的请求能被可用的或离用户最近,或服务质量最好的服务器来处理,从而确保访问质量。
能通过服务器的运行状况(例如是否宕机)和负载情况(如CPU占用、带宽占用)等数据,判定服务器的可用性,也能同时判断用户(访问者)与服务器间的链路状况,选择链路状况最好的服务器。因此GSLB是对服务器和链路进行综合判断来决定由哪个地点的服务器来提供服务,实现异地服务器群服务质量的保证。
图3-9中圆圈内的数字代表一个HTTP请求的访问流程顺序,从第1步客户端访问本地域名解析服务器(DNS)到第6步授权DNS服务器返回授权认证请求,最后第7步返回给客户端应答,客户端可以拿到最新的备份服务器的地址以支撑服务,各步骤如下。
①用户(Client)向本级配置的本地DNS服务器发出查询请求,如果本地DNS服务器有该域名的缓存记录,则返回给用户,否则进行第②步。
②本地DNS服务器进行递归查询,最终会查询到域名注册商处的授权DNS服务器。
③授权DNS服务器返回一条NS记录给本地的DNS服务器。根据授权DNS服务器上的不同设置,这条NS记录可能是指向一个随机GSLB设备的接口地址或者是所有GSLB设备的接口地址。
④本地DNS服务器向其中一个GSLB地址发出域名查询请求,如果请求超时会向其他地址发出查询。
⑤GSLB设备选出最优的解析结果,返回一条A记录给本地DNS服务器。根据全局负载均衡策略设定的不同可能返回一个或多个虚拟IP地址。
⑥本地服务器将查询结果通过一条A记录返回给用户,并缓存这条记录。
在高可用设计中,授权DNS服务器一般直接绑定在GSLB的设备上,而GSLB会实施监控所管辖的服务和网络集群,以便及时更新IDC的运行状态。