云端应用架构高可用:云计算是否伤得起

云计算是一种新型的计算模式。其显著优势之一是云计算用户可以随时随地的使用来自互联网的服务,并且按使用量付费。在需要增加(或减少)计算能力时,可立即获得(或释放)资源,而在传统数据中心(非私有云环境)中,用户却需要采购硬件,安装配置操作系统和中间件软件,再部署应用。两种方式在运维工作上的差异一目了然,这正是云计算能够受到业界热捧和追逐的主要原因之一。那么,云计算是完美无缺的么?不尽然如此。在云计算的世界里,运维工作不再由云计算用户承担,转而交给虚拟化和自动化技术以及云计算提供商来承担。

同时,云计算用户在享受弹性资源扩张或收缩的同时,也在一定程度上失去了对其使用资源的控制权,而如果云服务供应商的服务出现故障,或者云服务供应商由于商业运作的失败或其他原因而关门倒闭时,云计算用户就可能会面临巨大的风险。

2011年4月21日至22日是值得云计算从业者纪念的日子。Amazon的IaaS服务出现故障,导致许多商业网站的服务中断,影响非常严重。据Amazon官方网站称,受影响最严重的网站中有Reddit, Foursquare和Quora等。此事件发生后,人们一时陷入慌乱,对云计算可用性的担心骤然升温。同时,也有人乘机夸大云计算的弊端,并宣称“云计算已死”(这让笔者想起当年关于“SOA已死”的论战)。炒作行为是可以理解的,我们自然不用去理会。但是,作为云计算用户,我们需要思考的是,如何保证即便在云服务不可用的情况,我们的应用架构仍然能够屹立不倒?本文正是站在云计算用户的角度试图探讨这一问题。

“4- 21”事故分析

Amazon将其基础设施划分为“区域(Region)”,这些区域好比一个个数据中心。例如,US-East-1是Amazon位于北弗吉尼亚的数据中心,而US-West-1则是位于硅谷的数据中心。每个数据中心又被划分成多个可用分区(后简称为AZ),AZ就好比资源池,它由一组物理和逻辑资源组成。

Amazon的提供的虚拟机是EC2(Elastic Compute Cloud)。而其存储服务是EBS(Elastic Block Storage)。EBS是基于网络高性能且高可用的块(block)级别的持久化存储服务。EBS可以挂接到某一个EC2实例上作为其文件系统使用。

当用户获得一个EC2分区实例时,同时会得到一块存储区。不过,该存取区是透明的,而且其生存周期与EC2实例是同步的。当EC2实例销毁时,该存储区也一同销毁,基于此,需要持久化的用户数据是不应该放在该存储上。

一般而言,运行网站和产品的云计算用户至少需要申请一个EC2实例和一个EBS存储。在EC2上运行应用和数据库,而数据则存储在EBS中。但是,若要将EBS存储挂接到EC2实例上,二者必须在同一AZ中(如图1.a所示)。用户也可以直接使用Amazon提供的RDS(Relational Database Service),它是一个运行着MySQL的EC2实例,此时应用和数据就可分别位于不同的AZ中(如图1.b所示)。当然,将应用和存储分开还有其他方法,本文不再赘述。

“4-21”事故中,位于US-East-1区域的EBS存储和Amazon RDS服务都出现了问题。表现出来的现象是:不在US-East-1区域的用户未受影响,未使用EBS和RDS的用户不受影响。一般情况下,使用EBS或RDS是非常普遍的现象,因为大多数软件或网站都依赖于数据存储,所以,即便运行应用的EC2未受影响,也会由于应用需要访问已出现问题的ESB或RDS上的数据,仍然会导致服务不可用或服务变慢的问题。

Amazon事故的的发生加速了人们对云可用性的思考,也进一步凸显了好的应用架构的优势,多家企业纷纷通过博客分享了他们使用Amaozon AWS的经验,对云计算用户端架构的建议。接下来,我们看看他们是怎么做的。

来自一线的经验

早在2010年12月,在线影片租赁提供商NetFlix的技术博客上就发表了文章《使用AWS的5大经验》。在这篇文章中,他们给出了以下5条建议:

云环境和传统数据中心不同,需改变思考问题的方法

许多传统数据中心的应用部署和运维经验在云中不再适用,所以不能用传统的解决方法去解决云中出现的问题。比如,在自己的数据中心里,使用基于内存的session管理就是很好的方法,因为每个硬件实例出现故障的可能性微乎其微。然而,AWS实例的出错率却高很多,所以需要不同高可用方案。

共租是难以实现的

在云环境中设计面向用户的软件时,主要工作是降低整体上响应的延时。由于AWS是基于资源(硬件、网络、存储等)共享模式构建的,共租会引起各个层次上吞吐量的波动。或者你放弃任何特殊的操作,或者在AWS里管理好资源,这等于放弃了共租。

避免失败的最好方法是不停地出错

Netflix的技术人员喜欢将自己的软件架构称之为兰博架构,不论在何种情况下,每个系统必须靠自己存活。他们在设计分布式系统时考虑了其所依赖的其他系统的故障并且能够容忍故障。

他们在AWS中创建了一个被称为“捣乱猴”的系统。该“捣乱猴”的任务就是随意杀死软件架构中的任意实例和服务。他们的原则是,即便局部出错了,他们的系统和架构仍然要整体上保持正确,只有这样,才能躲过预料之外的故障。

测试就要做真实情况的模拟,不能儿戏!

在完全依靠AWS之前,他们就使用真实数据对AWS上的系统做测试。他们模拟所有发往数据中心的请求,然后发送到AWS做实测。

测试能够发现架构的瓶颈,有些架构决定和设计决定,在图纸上看似完美,但是一旦应用到大规模的实际情形,就不那么奏效了。

坚韧与信念,永不言弃

你会碰到许多问题!毕竟云计算的发展也没有几年,许多方面仍在不断完善之中。用户需要改变过去的观念,放弃过去的固定模式。关键是要保持坚忍不拔地战胜一切困难的意志力,坚定对胜利的信念。

Coding Horror博主Jeff Atwood非常赞同“捣乱猴”的思路。他在博文中分享了他的团队花好几个月解决一个诡异问题的经历。为了跟踪该问题,他们分析和尝试了可能导致该问题的所有原因,但是仍然未找到其根本原因。每隔几天,就会有服务器(不知道是那台)从网络中脱离,他们称此现象为“捣乱猴”又发怒了。他们被此问题困扰数月之久,团队曾陷入崩溃,但是即便在最困难的时期,他们仍然采取了积极的行动:

但凡某关键功能现在由一台服务器负责,就切换成两台。

但凡发现哪里缺乏可靠性,就建立其可靠性。

消除所有的依赖,一步一步,直到依赖减到不能再少。

设计替代方案,使我们的服务始终保持运行,即便我们先前认为关键的服务突然失效。

SmugMug也分享了他们的经验,他们网站未受影响的原因在于以下四点:

部署在AWS中的服务分布在多个AZ中。所以,一个AZ出问题,就可以切换到另一个AZ。

其架构从设计之初就考虑了故障。他们的每个实例,或一个AZ中的任意一组实例,可以瞬间倒下,系统会很快恢复。

在这次事故中,他们没有使用EBS。因为他们一直不放心EBS的性能和持久性,所以一直没有使用它。基于同样的原因,他们也没有使用RDS。

他们尚未达到100%的云计算。

此外,对于100%纯度的云应用,作者给出以下建议:

分散到多个AZ。

分散到多个区域(Region)。

分散到多个云计算供应商。

意识到分散带来的附加工作和复杂度,始终保持清醒认识。

从架构上考虑故障。

熟知应用的哪些地方可能会出现故障。

系统组件化。

对组件进行测试。

保持放松的心态——故障是常有的事情,泰然处之。

Twilio也针对AWS给出了自己的云架构原则,如下:

将故障单元限定在单台主机上。

设定较短超时时间,快速重试。

保持服务接口的幂等性。

服务细粒度,无状态。

宽松的一致性要求。

云端应用架构设计的建议

结合上文对Amazon事件的分析以及众多来自一线工作人员的经验和分享。我们不难看出,对于云计算用户来说,单纯地祈祷云计算供应商提供100%可靠的云服务不是解决问题的根本所在。相反,云计算用户应该从其应用和架构本身寻找解决问题的根本方法。简单总结如下:

充分理解云计算供应商的服务可用性,在条件允许的情况下准备相应的对策。

以AWS服务为例,若用户对Amazon的EC2,EBS,RDS等服务的可用性及其依赖关系有充分的了解,就可以根据自己的实际需要为自己的服务架构不同级别的可用性。在多个区域(Region),AZ(可用分区),和EC2上分别实施的高可用方案的可用性级别是不同的,在不同区域上建立的高可用方案的可用性级别最高,基于AZ的次之,EC2上的最低。但是,高可用性越高,其复杂度和成本越高,反之亦然。用户可根据不同的业务需求为系统中的不同功能提供不同级别的高可用性方案。

在架构设计中考虑故障的可能性。

不论在传统的数据中心还是在云环境中,设计软件架构师都需要考虑到故障。不同的是,传统方式下,从软件到硬件,架构师都是可控的,而在云计算环境中,使用的云中服务确实是不可控的。这就需要在做架构设计,或采用云服务时,充分了解云服务的可用性,并将此知识作为架构设计的输入之一。

应用系统的组件化和服务化。

使用SOA架构方法构建应用系统,将应用功能划分成细粒度、无状态的组件,并将组件封装成服务,将同一服务的不同实例分散到多个实例中运行,从而提高服务整体的可用性。

在条件允许的情况下,使用多个云服务提供商。

在云计算标准尚未成熟的大环境下,实现这一理想是困难的。但是,随着云计算标准逐渐成熟,在设计云端应用软件的架构时,就可考虑在多个云服务供应商之间实现高可用性,但是就目前而言,由于各个云计算供应商的服务的功能和接口缺乏一致性和标准型,完成可用性的设计和实现是需要付出代价的。路漫漫其修远兮,但希望总在前方。

相关推荐