前言

本文翻译自AWS官方白皮书《AWS Cloud Best Practice》,仅为学习之用,如有版权方面问题,请与我联系。原文档请点击AWS CLoud Best Practice


摘要

本白皮书是为了那些把应用部署在AWS之上的解决方案架构师或开发人员所作。本文提供了一些架构模式和建议,以帮助人们设计出安全、可靠、高效而又成本低廉的系统。其中讨论了如何利用云计算的动态特性(弹性计算、基础设施自动化),以及一些在云环境中应用这些特性的通用模式。

简介

公司或组织不需要做出很大改变,就可以把应用迁移到AWS安全又低廉的基础设施之上。但如果想充分利用云计算弹性和敏捷的特性,工程师需要将架构融入AWS的服务之上。
对于新应用,AWS用户已经发明许多高效可扩展的云上架构模式。这些架构可以从不可预知的数据洪流以及数以千计的IoT和移动设备中获取数据,并为应用提供任意的实时数据。
本文将会重点标注一些原则,帮助人们决定是否迁移原系统到云上或重新设计一个适于云环境的新系统。
本文假设读者已对AWS服务有基础理解,如果读者尚未了解AWS服务及解决方案,请先参见AWS网站。

云计算的特性

这部分展示了云环境与传统环境的区别,并解释了那些最佳实践的由来。

IT设施变为可编程资源

在非云环境中,人们常常需要基于经验预测流量洪峰,并以此准备充足的系统资源。这将导致在一段时间内,昂贵的资源处于空闲状态或者准备不足。在云环境中,你可以根据你的需求,尽量多或尽量少地使用资源,同时可以动态调整来应对真实的需求,当然你只需要为你使用的部分付费。
在AWS,数据库、存储介质和高阶组件都可以在几秒内生成。你可以把它们当作临时性的一次性资源,这比那些受限又不灵活的固定IT基础设施要自由得多。这将改变你对于需求变更、测试、可用性以及容量的计划。

全球化、可用性以及无尽的容量

使用AWS的全球设施,你可以将应用部署到最符合你需求(例如用户分布、数据存储区和成本)的区域(Region)。对于全球化的应用,你可以使用CloudFront CDN来减少终端用户的延迟。同样,建立多数据中心以获得高可用性也变得非常容易。在近乎无尽的虚拟资源之上,你可以用另外一种方式考虑未来的发展。

高端可控的服务

除了Amazon EC2(弹性计算)资源,AWS用户同样可以使用各种各样的存储、数据库、分析、应用、以及部署服务。因为这些服务对开发人员来说都是立等可用的,它们可以减少人们对于传统机房运维技能的依赖,使得公司组织可以更快地发布他们的解决方案。这些服务由AWS负责管理,这样一来可以减少运维的复杂度和成本。这些由AWS托管的服务从设计之初就考虑了扩展性及可用性,因此可以减少使用者的风险。

内置安全性

对于传统IT设施,往往需要定期手动进行安全审计。而AWS云服务提供的治理功能,可以持续监控你IT资源的配置。由于AWS资源都是可编程的,你的安全策略可以规范化地嵌入到你的基础设施架构中。拥有了部署临时环境的能力,安全测试可以成为持续发布的一部分。总之,在你的解决方案中,可以使用多种AWS安全服务来保护你的数据。

设计原则

在本节中,我们将介绍一系列的设计模式以及架构类型,这些架构可以应用到多种场景中。

可扩展性

随着时间的推移,系统需要建立在一个可扩展的架构之上。这样的架构,可以支持增长的用户量、流量以及数据量而又没有性能损失。它应该提供一种线性扩展的方式,即通过增加资源来成比例地提升处理能力。资源的增减应该依据业务量,同时成本多少应该和系统资源用量相匹配。在架构设计的时候就应该考虑到如何无缝利用云计算提供的无尽的虚拟资源。通常来说,IT架构有以下两种扩展方式:垂直扩展和水平扩展。

垂直扩展

垂直扩展通常应用在某种单一资源的增长上(比如升级服务器的硬盘容量和CPU性能)。Amazon EC2可以简单地通过停机扩展来获取更多的RAM、CPU、IO或网络资源。这种方式最终会达到一个临界而且通常不是最经济又高可用的方式,不过这种方式实现起来非常容易,短期之内可以满足很多场景。

水平扩展

水平扩展意味着某种资源在数量上的增长(比如给存储阵列增加硬盘或者为应用增加服务器)。应用云计算的弹性来创建互联网扩展应用是一种非常好的方式。当然不是所有架构都要设计为并行处理业务,下面列出了几种可能的场景。

无状态应用

当用户使用一个应用时,通常表现为一个包含多个交互的session。无服务应用是一种无需知道之前交互状态且无需储存session的应用。比如,用户给出一个相同的输入,一定会获得相同的输出。由于任何可用的计算资源(比如EC2和Lambda函数)都可以处理任意请求,一个无状态应用可以使用水平扩展。对于无需存储session信息,你可以根据需要简单地添加计算资源即可。当这些资源不再需要的时候,可以很安全地释放掉,无需担心它们现有的状态。唯一要考虑的就是如何将工作负载引导到它们之上。

如何将流量引导到不同节点

推模型:使用如ELB这种负载均衡解决方案是一个常用方法。ELB会将访问流量路由到不同的EC2实例上。另外一个替代方案是实现一个DNS分发(例如Amazon Route 53)。使用这种方案,DNS会从可用列表中返回一个IP。虽然这种方式很容易实现,但是在弹性云环境中并不是个很好的负载方案。原因是即使你设置了一个很短的失效时间(TTL),缓存的DNS并不受Amazon Route 53的控制并且不是总能读取到你的设置。

拉模型:由于你可以自己实现一个拉模型,异步事件驱动的业务并不需要负载均衡解决方案。在一个拉模型中,待处理的任务或数据会以消息的形式存储在消息队列中(比如用Amazon SQS或流处理方案Kinesis)。多计算节点可以拉取并消费这些消息,以此实现分布式处理。

无状态组件

在实践中,大部分应用都需要储存一些状态。比如,网站应用跟踪用户的登录行为或者上一步的操作结果。一个自动化的多步处理过程同样需要知道上一步操作结果,来决定下一步该如何处理。当然你仍然可以通过不在本地存储任何信息,来将你的架构的一部分设计为无状态的。
比如,网站应用可以用cookies技术在浏览器里存储session信息(例如购物车里的商品)。浏览器每次请求都会将这个信息传给服务器,从而无需服务器端来存储。但是这种方式有两个缺点。其一,cookies的内容是由客户端来存储的,因此服务端应该永远要验证发来的信息。另外,cookies信息每次都会随请求发送过来,因此需要尽量减小它们的体积来避免无用的延迟。
另外一个场景是需要大文件存储(例如,用户上传、批处理的中间结果)。通过共享存储层(比如S3或EFS),你将无需处理有状态组件。另外一个例子是复杂工作流,你需要追踪每个处理的当前状态。你可以用Amazon Simple Workflow来中心化存储执行历史,使得你的应用无状态化。

有状态组件

在架构中,有些部分难免是有状态的。首先,根据定义,数据库是有状态的(不同区域的数据库)。此外,许多遗留系统都是跑在一个独立服务器上。另外,有些应用场景就需要客户端长时间连接在某一个特定服务器上,例如大型多人在线游戏,就需要以很低的延迟给大量用户提供一个一致的场景。如果这些连接都在某个特定服务器上,实现起来会非常容易。
当然你仍然可以用会话保持(session affinity),来实现多节点横向扩展及负载均衡。在这个模型中,你需要将连接绑定在某个特定服务器上。在这个模型中有个缺点是需要注意的,即已生成的会话,是无法从增加的计算资源中获益的,更重要的是,会话保持不是可靠的,例如某个服务器停机了,那么连接到这个服务器的用户都会处于断开状态并有可能丢失会话数据。

如何实现会话保持

对于HTTP/S请求,可以通过ELB的会话粘连(session sticky)特性来实现。ELB会尽量用同一个服务器来处理一次会话。

如果你可以控制客户端代码,利用客户端来负载均衡也是一个可行方案。这个方案相对难以实现,但当负载均衡器无法满足你的需求时,这个方案相当有效。比如当你使用了一个ELB不支持的协议或是需要完全掌控用户连接的服务器(比如在游戏场景中,也许需要确保用户匹配连接到特定的服务器上。)在这个模型中,客户端需要一种发现特定可用服务器的方式。你可以用DNS或者创建特定的API来给客户端提供上述信息。在不使用负载均衡器的情况下,客户端也需要实现健康检查机制。你需要在客户端实现,当服务不可用时,客户端可以连接到另外一个影响尽可能小的服务器上。

分布式处理

涉及大量数据的用例(任何由单机不能短时完成的任务),需要一个分布式处理的方案。通过将数据切分为小块,你可以将它们分布到一个可用集群上并行处理。

如何实现分布式处理

离线批处理任务可以由如Apache Hadoop这种分布式处理引擎来完成。在AWS上,你可以毫不费力地在EC2上,用Amazon EMR来执行一个Hadoop任务。对于实时处理流数据,Amazon Kinesis可以将数据切分到不同的分区然后由多个EC2或者Lambda函数来执行消费。

如需获取更多信息,请参见《Big Data Analytics Options On AWS》白皮书

用临时资源替代固定资源

在传统的基础设施环境中,由于前置消费,你需要与固定资源打交道并且花费大量时间熟悉硬件。这将会导致,需要手工登录服务器去部署软件、修复bug、制定IP地址、运行测试等一系列工作。
在AWS环境下,你可以抛弃之前的想法,以便利用云计算天然带有的动态特性。你可以认为服务器和其它计算资源都是临时的,可以按你的需求任意启动启动这些资源并且只在你需要的时候才运行。
对于长期运行的固定资源来说,配置转移是另外一个问题。长期的需求变更和软件补丁可能导致不同环境配置混乱且缺乏测试。这个问题可以使用“不可变基础设施(immutable infrastructure)”来解决。使用这种办法,一个服务一旦启动之后就不会再更新了。相比于每次发现问题就用一个新的服务来代替,这样做可以保证资源的一致性并且更容易回滚。

实例化计算资源

不论你是设置测试环境还是给现有的系统增加资源,你都不会想要手动去设置这些资源的配置和代码。为了避免长耗时以及人工失误,令这个过程自动化是非常必要的。如下几个方法可以完成自动化。

引导(Bootstrapping)

当你启动如EC2或RDS资源时,是以一个默认的配置。然后你可以自动执行一个引导程序,即执行一个自动安装软件或复制资源的脚本,使得被启动资源到达一个特定状态。你可以参数化配置细节以匹配不同的环境(比如生产、测试环境等)。这样一来,同样的脚本就可以达到复用。

引导实践

你可以使用用户数据脚本和cloud-init或AWS OpsWork生命周期事件去自动化启动一个EC2实例。你可以使用普通的脚本或者如Chef和Puppet的配置管理工具。AWS OpsWorks天然支持Chef清单和Bash/PowerShell脚本。此外,还可以通过自定义脚本和AWS API,或通过使用AWS CloudFormation支持AWS Lambda支持的自定义资源,可以编写几乎任何AWS资源的供应逻辑。

Golden Images

特定AWS资源,如EC2实例、RDS实例或Amazon EBS卷等,都可以从Golden Images上启动。Golden Images是某个资源在特定状态的快照,相比于引导的方式,Golden Images可以更快地启动,并且无需配置服务或第三方库等依赖。这对需要自动负载均衡的系统来说,是一个快速而又可靠的方案。
你可以自定义一个EC2实例并且通过Amazon Machine Image来创建一个配置。你可以通过AMI启动任意数量的实例,这些实例都会包括上述自定义配置。当你需要修改配置的时候,都必须重新创建一个golden image。长期来说,这就需要对其做一个版本管理。相比AMI,我们推荐你用脚本去引导启动EC2实例,这样可以更灵活地多次测试和修改这些镜像。
此外,如果你有个现成的本地部署的可视化环境,你可以用VM Import/Export将各种可视化格式转换为AMI。你还可以从AWS社区的AMI目录或者AWS市场或者第三方,直接使用各种已经预置好的AMI镜像。
除了EC2,Golden Images还可以用来启动RDS或EBS卷。例如,当你需要配置一个新的测试环境时,你可以直接从某个RDS镜像来初始化数据,无需冗长的SQL脚本。

容器

另外一个很受开发者欢迎的技术就是Docker——一种可以在容器内构建部署分布式应用的开源容器技术。Docker允许用户将软件打包在Docker镜像内。镜像本身是一个标准的软件执行单位,包括软件执行所需的所有依赖(如代码、环境和系统工具等)。AWS Elastic Beanstalk和Amazon EC2 Container Service支持用户跨EC2实例集群部署管理多Docker容器。

混合方式

AWS支持部分使用Golden Images和部分使用动态引导脚本的混合方式。

引导脚本和golden image的区别

资源内不经常改变或引入外部依赖的部分,通常使用golden images。例如,每次启动实例时,您的Web服务器软件都必须由第三方存储库下载,这是一个很好的选择。

资源中经常依环境不同而变化的部分可以使用引导脚本来配置。例如,如果要经常部署应用程序的新版本,则为每个应用程序版本创建新的AMI可能不切实际。 您也不希望将数据库主机名配置硬编码到AMI,因为测试和生产环境之间会有所不同。 用户数据或标签可用于允许您使用更多可在启动时修改的通用AMI。 例如,如果您为多个小型业务启动了web服务器,他们都可以使用相同的AMI并在启动时从用户指定的Amazon S3桶中恢复数据。

AWS Elastic Beanstalk使用混合模式。它提供预设置的运行环境(均从其AMI启动)并且支持运行引导脚本(执行.ebextensions后缀的配置文件),通过环境变量来参数化运行环境的差异。
欲知更多关于管理部署新资源的讨论,参见《Overview of Delplyment Options on AWS》和《Managing Your AWS Infrastructure at Scale》白皮书。

基础设施即代码

之前讨论的使用原则,并不局限于某种特定资源,因为AWS服务都是可编程的,你可以应用软件部署的技术、实践和工具来使你整个架构可复用性更强、稳定性更强、可扩展性更强并且可以测试。

AWS CloudFormation模板为开发人员和系统管理员提供了一种简单的方法来创建和管理相关AWS资源的集合,并以有序和可预测的方式提供和更新它们。 您可以描述您的AWS资源、任何相关依赖、运行时参数来运行您的程序。您的CloudFormation模板可以保存在您的版本管理库中,允许架构重用并使得从测试环境复制的生产环境更加可靠。

自动化

在传统的IT基础设施中,您经常需要手动应对各种情况。当您在AWS上部署应用时,经常可以做到自动化,因此可以提升您系统的稳定性及运营效率。
AWS Elastic Beanstalk是在AWS上运行应用最简单快捷的方法。开发者只需上传他们的应用代码,AWS服务会自动处理如资源供应、负载均衡、自动扩缩容及监控等细节。
Amazon EC2 Auto Recovery:你可以创建一个Amazon CloudWatch报警来监控EC2实例并可以使其自动从损坏状态中恢复。恢复的实例和原实例完全一样,包括实例ID、私有IP、弹性IP及所有实例元数据。但是,这个特性只对实例配置有效,更多最新描述请参见EC2文档。此外,在实例恢复过程中会重启实例,因此内存中的数据会丢失。
Auto Scaling:通过Auto Scaling,您可以保证应用的可用性,可以根据您定义的条件自动提升或减少EC2的资源。您可以使用Auto Scaling来保证跨可用区运行的EC2实例数量是正符合需要。Auto Scaling也可以在流量高峰的时候提高EC2数量来保证性能,同时在非忙时刻降低数量来节约成本。
Amazon CloudWatch Alarm:你可以创建一个CloudWatch报警,在某个指标超过阈值一定次数时候,通过Amazon SNS来发送报警消息。Amazon SNS消息可以触发Lambda向Amazon SQS中推送消息或者发起一个POST请求。
Amazon CloudWatch Events:CloudWatch服务提供了一个几乎实时的事件流系统来监控AWS资源的变化。通过您可以在几分钟内设置一个简单的规则,将事件路由到一个或多个目标上,如AWS lambda、Amazon Kinesis Streams或Amazon SNS等。
AWS OpsWorks Lifecycle events:AWS OpsWorks支持根据生命周期事件持续配置,自动更新您实例的配置来适应环境变化。这些事件可以在每个实例上触发Chef清单来执行特定的配置任务。例如,当一个新的数据库实例启动加入DB层后,配置事件可以触发Chef令应用层将配置指向该实例。
AWS lambda Scheduled events:这些事件允许您创建一个Lambda函数,令Lambda定期执行一些任务。

松耦合

随着应用复杂度上升,一个IT系统可以描述的属性就是它可以切分为小块、松耦合的组件。这意味着IT系统在设计时应减少交叉依赖,即一个组件的变动不应该影响其它组件。

良定义接口

减少交叉依赖的一个方法是令各组件之间都只通过技术无关的接口(如RESTful API)。通过这种方式,技术细节被隐藏在内部,从而开发团队可以改变底层实现而不影响其它组件。只要这些接口保证后端适配,其它组件的部署就可以解耦。

Amazon API Gateway是一个完全托管的服务,易于开发者在任意尺度上创建、发布、维护、监控和安保API接口。它可以同时处理成百上千的请求,同时还有流量管理、授权访问限制、监控和API版本管理。

服务发现

一个由一系列小型服务组成的应用,依赖于这些服务之间的交互。由于每个服务都可能跨机器运行,因此需要一个方法来记录服务运行地址。比如,在传统架构中,您的web前端需要访问后端服务,您可以将服务运行的IP地址硬编码到应用中。虽然这种方式在云环境中仍然可行,但如果要求服务间松耦合,这些服务应该不依赖先验的网络拓扑细节来获取该地址。除了隐藏复杂度,这样设计允许基础设施细节在任意时刻发生改变。由于云上资源可能在任意时刻启动或销毁,如果您想利用云计算的弹性特性,松耦合是至关重要的。为了达到这个目的,您需要几种实现服务发现的方式。

如何实现服务发现

对于一个建立在EC2上的服务,一个实现服务发现的简单方式就是使用Elastic Load Balancing。由于每个负载均衡器都有特定的地址,您就获得了一个稳定的服务发现终端。这个可以和DNS及Amazon Route53结合,这样负载均衡器终端也可以在任意时刻改变。

另外一个方案是使用服务注册和发现方法,返回一个终端IP和端口。由于服务发现是组件间交互的桥梁,则服务发现本身需要高可用性。如果没有使用负载均衡器,类似心跳检测的功能仍要可用。一些现有案例,包括使用标签密码,高可用数据库和调用AWS API的自定义脚本,如Eureka、Synapse和Consul的开源软件。

异步集成

异步集成是服务间松耦合的另外一个形式。这个模型适用于那种无需立即响应只要请求被注册了的场景。它发生于一个组件生产消息另一个组件消费消息。组件间不是通过点对点集成而是通过一个交互持久层(例如Amazon SQS队列或如Kinesis的流数据平台)

这个方法解耦了组件并且额外增加了弹性。比如一个进程读取队列中的消息消费失败了,消息仍存在于队列中,等待系统恢复后继续消费。它可以在前端流量洪峰时,保护后台无法扩展的服务,同时使您在成本和处理延迟中找到平衡。比如,在应对写操作流量洪峰时您可以选择不扩展您的数据库,只要您可以接受异步写入带来的延迟。最后,通过把慢操作移出同步请求,也可以提高终端用户体验。

异步集成案例

  • 前端应用向Amazon SQS队列中插入任务消息,后端系统消费这些任务并按照自己的节奏处理。
  • 一个API产生事件并推入Amazon Kinesis Streams。后端应用分批拉取这些消息来聚合出时序数据存储在数据库中。
  • 多个混合系统使用Amazon SWF来相互交流工作流,而不是直接相连。
  • AWS Lambda函数可以从多个AWS源中消费数据(例如Amazon DynamoDB的更新流、S3的事件通知等)。在这种场景下,你甚至不用担心队列或其它异步方法的实现,服务已经为您处理了这些。

优雅失败

另外一个降低组件间耦合度的方法是,组件可以优雅地处理异常情况。您可以明确一个方法来减少对终端用户的影响,提高在某些组件失效情况下的离线处理能力。

优雅失败实践

一个失败的请求可以进行额外重试,或者存储在队列中延迟处理。例如当数据库不可用时,前端页面可以提供其它的或者缓存的内容而不是彻底的失败页面。Amazon Route53的失效转移机制可以将您从先前不可用的服务中路由到可用的服务。您可以在S3上或其它动态环境设置一个静态的web站点。

服务而非服务器

开发、管理、运维一个应用,尤其在扩展时,需要各种各样的底层技术组件。在传统IT架构中,企业需要构建并操作所有组件。
AWS提供了一系列的计算、存储、数据库、分析、应用和部署服务,帮助组织快速成长并降低IT成本。不考虑扩展性的架构,通常不能充分利用云计算的特点,同时可能失去提高生产力和运营效率的机会。

托管服务

在AWS上,有一系列的模块可供开发者使用,来提高应用能力。这些托管服务包括数据库、机器学习、分析、队列、搜索、邮件、消息通知等等。比如,使用Amazon SQS,您无需管理和运维一个高可用的消息队列集群,只需要按使用量付出使用费。不止如此,Amazon SQS是内部可扩展的。这个特性S3同样具有,您可以存储任意量的数据并且访问它们,无需担心容量、硬盘配置、副本等等。此外,Amazon S3同样可以为网站或移动app提供静态内容访问,提供一个可以自动扩展应对高流量的高可用解决方案。
还有许多其它应用,如用于内容分发的Amazon CloudFront,用于负载均衡的ELB,NoSQL数据库Amazon DynamoDB,用于搜索的Amazon CloudSearch,用于视频编码的Amazon Elastic Transcoder,用于发邮件的Amazon SES,等等。

无服务器架构

另外一个减少运维复杂度的方法就是将应用跑在无服务器架构上。为移动端、web、分析和IoT构建一个事件驱动的异步服务并不是空谈。由于无需为底层服务器付费,这样的架构可以减少很大成本,同时您也无需为架构的高可用性担心。

您可以将业务代码上传到AWS lambda计算服务上,该服务将使用AWS基础设施来运行您的代码。使用AWS Lambda,您需要为代码执行的每100毫秒以及触发代码的次数付费。通过Amazon API Gateway,您可以利用AWS Lambda开发一个虚拟的近乎无尽扩展的异步API。配合Amazon S3提供的静态内容,这个模式就是一个完整的web应用。更多架构详情,参见白皮书《AWS Serverless Multi-Tier Architectures》

对于移动APP,还有一种方法可以减少基于服务器架构的覆盖面。使用Amazon Cognito,您无需管理后端用户授权、网络状态、存储和同步,Amazon Cognito会为您的用户生成身份标识。以上这些可以在其它访问策略中引用,可以基于每个用户启用或限制对其它AWS资源的访问。Amazon Cognito提供临时的AWS凭据,允许移动端直接与IAM交互。例如,通过IAM您可以限制特定终端用户访问S3桶的权限。
对于IoT应用,传统组织需要提供、运行、扩展和维护他们自己的服务器和设备网关来处理终端硬件和他们服务的连接。AWS IoT提供了完全托管的设备网关,无需人工运维即可完成完成自动扩容。

数据库

使用传统IT架构的团队,经常受限于他们所使用的数据库或存储技术,可能受限于许可成本和支持多数据库引擎的能力。在AWS上,这些限制都将不复存在,托管的数据库服务可以用开源软件的成功提供企业级的性能。因此,将程序运行在多语言数据存储层并为每个工作负载选择正确的技术并非不可能。

为工作负载选择数据库技术

如下问题可以帮助您选择架构中的解决方案。

  • 是读操作多还是写操作多,抑或读写均衡?您需要每秒完成多少次读和写操作?当用户数提升时,这些数字又该如何变化。
  • 您需要存储多少数据?存储多长时间?您预计数据量如何增长?在可预见的未来,是否有数据量上限?每个对象的体积多大?如何访问这些对象?
  • 您对于数据持久性的需求是什么?这些数据会成为“绝对依据”么?
  • 您的数据模型是什么?计划如何访问数据?您需要跨关系查询么(例如跨表JOINs)?您可不可以抛弃掉表结构而使用更易扩展的扁平化结构?
  • 您需要什么样的功能?您需要强关系还是更灵活(例如弱结构存储)?您是否需要复杂报告或搜索能力?相比于NoSQL,开发人员是否更熟悉关系型数据库?

关系型数据库

关系型数据库(也被称为RDBS或SQL数据库)将格式化的数据存储在由行列组成的定义良好的表格中。它提供强大的查询语言、灵活的索引、强关系控制和快速高效多表联合的能力。Amazon RDS就是一款云端易于设置、运维和扩展的关系型数据库。

扩展性

关系型数据库可以纵向扩展(比如切换为更大的DB实例和增加更快的存储介质)。此外,Amazon Aurora是一款比标准MySQL有更高吞吐的数据库引擎的关系型数据库。对于读操作多的应用,您可以横向扩展,增加更多的读副本,来获得比单DB实例更多的容量。

如何利用读副本

读副本是一个独立的数据库,从源库异步同步数据。因此,他们受制于复制延迟有可能丢失最近的事务。程序设计者需要考虑哪些查询可以容忍少许的数据延迟。这些查询可以从读副本种获取数据,其它的则需要从主节点获取。读副本也不支持任何写操作。

需要突破单实例限制并扩展写容量的关系型数据库,需要另一种称为“分区分片”的方式。在这个模型中,数据被切分到多个数据库中,每个数据库都拥有自治的主节点。虽然Amazon RDS避免了数据库实例的运维工作,但是分片还是为应用引入了一些复杂度。应用的数据访问层需要知道数据具体是如何分片的,以便查询时可以直接连到正确的实例上。此外,任何表结构的变动需要同步到所有数据库实例中,因此需要为此做一些自动化的工作。

高可用性

对于生产环境的关系型数据库,我们推荐使用Amazon RDS多可用区部署,这样可以在不同的可用区创建同步的副本实例。当主节点失效时,RDS可以自动切换到备用副本中,无需管理员手动干预。当故障转移发生时,主节点会在短时间内无法访问。通过减少功能,弹性应用程序可以设计为优雅失效的。(例如,只读模式利用读副本)

反模式

如果您的应用程序主键索引和查询数据而不需要连表或复杂事务(尤其是希望突破单实例写限制的),请考虑使用NoSQL数据库。如果您有大型二进制文件需要存储(音频视频图片等),将它们存到S3中并让数据库只存储元数据,是更高效的方式。
更多详细信息及最佳实践请参见Amazon RDS文档。

NoSQL数据库

NoSQL是这样一种数据库,用一些关系型数据库的查询和事务能力来交换灵活的数据结构和无缝横向扩展。NoSQL数据库有多种数据模型,包括图形、键值对和JSON文档。NoSQL数据库被广泛认为具有易部署、可扩展性能、高可用和弹性。Amazon DynamoDB是一款高效灵活的NoSQL数据库,可用在任意尺度上为应用提供毫秒级延迟。它完全托管于云端并支持文档和键值对模型。

扩展性

NoSQL数据库通常通过横向扩展的方式,使用数据分区,来平衡读写操作。它以一种透明的方式来完成数据分区,无需应用数据访问层来实现。Amazon DynamoDB已经自动为您做好了分区,并且会随着表容量增大或者读写需求增加而添加新的分区。
为了在设计时充分利用Amazon DynamoDB的扩展性,请参见Amazon DynamoDB最佳实践文档。

高可用性

Amazon DynamoDB服务在Amazon区域内的三个可用区同步数据副本,以此提供某个可用区不可用时容错性的保证。

反模式

如果您的数据结构无法反正规化,同时您需要复杂联查和事务,那么关系型数据库应该是更好的选择。如果您有大型二进制文件需要存储(音频视频图片等),将它们存到S3中并让数据库只存储元数据,这种方式更为高效。
当迁移和评估哪些业务需要从关系型数据库移到DynamoDB时,请参见《Best Practice for Migrating from RDBMS to DynamoDB》。

数据仓库

数据仓库是一类特别的关系型数据库,对于大量数据查询和报告做了一定优化。它可以从多个源组合事务数据(比如从web、财务系统和CRM收集用户行为),最终做一个综合分析和决策。
传统来说,设置、运行和扩展数据仓库是一个复杂又高成本的动作。在AWS,您可以使用Amazon Redshift,从设计时就至少节省为十分之一操作成本的解决方案。

高可用性

Amazon Redshift有多种特性来提高您数据仓库集群的稳定性。我们推荐在您的生产环境中,将服务部署在多节点集群中,所有在某个节点上的写操作都会自动同步到集群内的其它节点上,数据同样会持续备份到S3上。Amazon Redshift持续监控集群健康和自动从失效节点上同步数据,如果有必要,同时替换节点。更多请见Amazon Redshift FAQ。

反模式

由于Amazon Redshift是一个基于SQL的关系型数据库管理系统,它适配其它RDBMS应用和报表工具。虽然Redshift提供RDBMS的功能,包括OLTP功能,但它并非为此而设计。如果您需要高并发并涉及小数据量的全栏读写操作,Amazon RDS和DynamoDB是更好的选择。

搜索

涉及复杂搜索功能的应用,通常会超出关系型或NoSQL数据库的能力。一个搜索服务,应该可以支持索引和搜索结构化和非结构化文本,支持如自定义排序、面过滤、同义词和词干提取等其它数据库不支持的功能。
在AWS中,您可以选择Amazon CloudSearch和Amazon Elasticsearch Service。其中,Amazon CloudSearch是一个托管的无需过多配置的服务,并且可以自动扩展。另一方面,Amazon ES提供了开源API并给予您更多配置细节。Amazon ES除了是一个搜索解决方案,还可以承担更多功能。它经常扮演分析引擎的角色,如日志分析、实时应用监控和点击流分析。

扩展性

Amazon CloudSearch和Amazon ES都使用了数据分区和副本来实现横向扩展。这两者的区别是,您无需担心Amazon CloudSearch的分区和副本数量,服务本身会处理这些。

高可用性

两个服务都提供了跨可用区的冗余数据。更多细节请看对应服务文档。

移除单点故障

生产系统在运行过程中通常伴随着定义好的和不明晰的对象。当一个系统可以承受单个或多个组件(如硬盘、服务器和网络连接)失效的时候,我们称之为高可用的。您可以考虑各种方法,在架构的每一层来自动恢复和减少失败带来的影响。这一节将讨论高可用设计。对于更多该主题信息,请参见《Building Fault Tolerant Application》白皮书。

引入冗余

单点故障可通过引入冗余来解决,即使用更多资源来完成相同任务。冗余可以用待命和激活模式实现。
在待命冗余中,当资源失效,功能会在第二资源上重新恢复,也成为“故障转移”。故障转移通常需要花费一定时间,在这段时间内,资源仍是不可用状态。备用资源可以只在需要时启动(可节约成本),或者运行在空闲状态(加速故障转移减少影响)。待命冗余通常应用在有状态组件上,比如关系型数据库。
在激活冗余中,请求被分配到多个冗余计算资源中,当其中一个失效时,其它资源可以帮助处理掉这一部分请求。相比于待命式的冗余,这种方式对资源利用更充分并且在资源失效时影响更小。

发现失效

您在设计过程中,应尽量构建一个自动化的发现和响应失效的系统。您可以使用如ELB或Route 53的服务来配置健康检查同时将流量路由到健康节点上来掩盖服务失效。此外,可以配置自动扩展来自动替换掉非健康节点。或者您可以使用Amazon EC2 auto-recovery或AWS OpsWorks或者AWS Elastic Beanstalk来恢复非健康节点。事先预测所有失效情况是不可能的。确认您收集了足够的日志和指标来了解您的系统行为。在此之后,您可以设置报警来手动或自动处理问题。

设计优良的健康检查

为您的应用配置一个优良的健康检查将决定了您正确应对多种失效场景的能力。

在一个典型的三层应用中,您应在ELB服务上配置健康检查。设计您的运行状况检查,目的是可靠地评估后端节点的运行状况。一个简单的TCP健康检查无法发现它自己是否健康,但web服务已经崩溃了。相对地,对于一些简单请求,无论web服务器是否返回了200都应该可以访问。

在这一层中,配置一个所谓的深度健康检查并不合适,深度检查依赖于您应用的其他层是否可用。比如,您的健康检查还检验了您的服务器是否可以连接后端数据库,当数据库短暂不可用是,您的健康检查有可能将所有服务器都标记为不可用。通常同层检验是最好的。深度检查在Amazon Route53层实现比较合适。通过运行更全面的检查来确定该环境是否能够实际提供所需的功能,您可以将Amazon Route53配置为故障转移到网站的静态版本,直到数据库启动并再次运行。

持久化存储

您的应用和用户会创造和存储多种数据。架构保证数据的可用性和完整性是非常重要的。数据副本就是一种引入冗余复制数据的技术。它可以横向扩展可读副本并且增加数据的持久性和可用性。在许多场景中都可以使用副本技术。
同步副本只在主节点和副本上都持久化好数据才会提交一个事务。它是在主节点失效时保证数据完整性的理想方案。同步化的副本同样可以扩展可读副本并且保证是最新的数据(强一致)。同步副本的缺点在于,主节点和副本的耦合。一个事务只有在所有副本都写入完成后才会确认。这就需要性能和可用性的妥协(尤其是运行在不可信或高延迟的环境中)。同样地它并不适合持有太多的同步副本。

持久性:不可替代的备份

不论您使用哪种持久化方案,都没有备份的可替代方法。同步副本会存储您所有数据的冗余,即使是由于软件bug和人为失误造成的。然而对于存储在S3中的对象,您可以使用版本号来保存、回退和恢复到任意版本。使用版本号,您可以将用户意外操作和程序失效造成的错误恢复。

异步副本解耦了主节点和副本,解决了副本间复制数据的开销。这意味着主节点上的改变并不会立刻反应到副本节点上。异步副本用在可以用来扩展能容忍数据延迟的系统中。它同样可以用来增加数据的持久性,但会在容忍范围内丢失一些最近的事务数据。比如,您可以对您的数据库在不同的区域采取异步副本来从灾难中恢复数据。
基于选举的副本结合了同步和异步副本来解决大型分布式数据库的问题。通过确定一个最小成功写入副本数来管理整个副本集群。更细节的讨论超出了本文范围,您可以参见《Amazon Dynamo》白皮书来了解高可用可扩展数据库的核心原则。

数据持久性的实践

了解每种技术适用于哪种存储模型是很重要的。它们在故障转移或备份恢复时的行为,决定了您的恢复点和恢复时间。您需要确定您可以容忍丢失数据的量和恢复时间。例如,基于Redis的Amazon ElasticCache可以自动故障转移,但其副本是异步存储的。在故障转移时,最近的一些事务极有可能丢失。然而,跨多可用区的Amazon RDS,就设计为可提供同步数据副本来保证备用节点和主节点数据一致。

自动化弹性多数据中心

核心业务应用需要应对单点磁盘、服务器和机架损坏的情况。在传统基础设施架构中,当遇到主节点崩溃,您通常需要一个将故障转移到远方第二数据中心的方案。由于距离的原因,数据延迟使得保持跨数据中心的数据同步性并不现实。因此,一次故障转移将导致数据丢失或者带来巨大的数据恢复成本。这个过程将变得非常危险并不可测试。当然,这样的模式为极小概率的大灾难提供了保护,比如自然灾害破坏了您整个数据中心。您可以参考AWS灾难恢复白皮书来获得更多关于这类信息和指导。
短暂的中断是种更常见的状况。对于短期故障,由于时间不会持续很长,故障转移的选择就更加困难并且经常被错过。在AWS上,您可以方便地采用一种简单高效方式来应对这种故障。每个AWS地区(Region)都含有多个独立的可用区(Avaliability Zone)。一个可用区的故障是独立于其它可用区的。一个可用区就是一个数据中心,有些情况下,一个可用区也包含多个数据中心。在一个地区间的可用区之间的连接,成本低廉且低网络延迟。这将使得您跨数据中心地同步数据变得可能,因此当发生故障转移时,您的用户将没有感知。
同时,您可以实现活跃的冗余并且无需为此付费。比如,一组应用服务器可以被跨可用区部署并且挂载到ELB服务之下。当健康检查发现某个可用区的EC2实例不可用后,ELB将不会再向这些节点发送流量。结合Auto Scaling,健康节点的数量将被负载均衡到另外一个可用区上,无需手动干预。
事实上,许多AWS高阶服务本身设计就是跨可用区的。比如,Amazon RDS提供的高可用性以及实例自动故障转移就是跨可用区实现的,还有S3和Dynamo DB的数据冗余备份也是放到多可用区上。

故障独立和传统横向扩展。

虽然活跃冗余模式对负载流量和处理可用区故障很有效,但对于某些本身有害的请求就显得不足了。比如,有一个可能影响每个实例的场景。一个特定的请求引发了一个系统bug,然后触发故障转移后,请求方可能重复刚才的请求以致在所有实例上引发级联失效。

随机切片

一个在传统水平扩展种可以实现的故障独立方法叫做“切片”。类似于传统数据存储技术的用法,并不把流量分担到每个节点上,而是将节点分组分片。比如您有一个8实例的服务。您可以创建4个分片,每个分片2实例,每个用户将被分配到特定分片。通过这种方式,您可以减少对客户的影响,与您拥有的分片数量成正比。然而,这对用户还是产生了影响,因此关键在于在客户端实现故障容忍。如果客户端可以在分片中尝试每个节点直到成功,您将获得巨大提升。该技术被称为随机分片,在博客中有更详细介绍。

优化成本

通过将现有系统上云,企业组织可以减少开支并可以依赖AWS低廉扩展平稳运行。通过迭代利用更多的AWS服务,人们又更多的可能去创建成本优化云架构。这部分将讨论AWS云优化成本的主要原则。

用量合适

AWS提供了各种类型的资源来配合各种场景需求。比如,基础服务包括Amazon EC2、Amazon RDS、Amazon Redshift和Amazon Ealsticssearch Service都可以选择多种类型实例。在使用中,您应选择最便宜的类型来满足您的需求。某些情况下,使用更少的大型实例会减少开销或得到更好的性能。您应进行测试并根据您的应用使用CPU、内存、网络、磁盘容量和IO情况来选择合适的实例。
类似地,您可以选用合适的存储方案来减少成本。比如,Amazon S3提供了各种存储类型,包括标准型、少冗余性和标准低频访问型。其它服务如Amazon EC2、Amazon RDS和Amazon ES支持不同类型的Amazon EBS卷类型(磁盘型、SSD、IOPS SSD)。您可以评估使用。

持续监控和标记

成本优化是一个迭代过程。您的应用和功能将随着时间进化。此外,AWS也将频繁按时发布新的功能。

AWS提供将提供工具来帮助您找到那些可以节约的成本并且保证您的资源在一个合理的容量。为了让这些工具正确地反映状态,您需要为您的AWS资源定义和实现一个标签机制。您可以标记您构建过程的一部分并且使用如AWS Elastic Beanstalk和AWS OpsWorks来实现自动化。您还可以使用AWS Config提供的托管规则来评估特定标记是否应用于您的资源。

弹性

另外一个在AWS上省钱的方式是利用平台的弹性。尽量将您的工作负载加入到Auto Scaling的计划中,以便自动地在需要时扩容,在不需要时缩容,以此节约成本。此外,您可以在不需要时,自动将非生产资源关闭。更进一步,考虑哪些业务可以用AWS lambda实现从而您无需为空闲或冗余资源付费。
尽量将Amazon EC2的业务转移到AWS托管服务上,这样您将无需考虑容量问题(比如ELB、Aamzon CloudFront、Amazon SQS、Amazon Kinesis Firehose、AWS lambda、Amazon SES、Amazon CloudSearch)或者令您可以在需要时方便地调整容量(比如,Amazon DynamoDB、Amazon RDS、Amazon Elasticsearch Service)。

利用多种付费方式

Amazon EC2 按需实例定价为您提供最大的灵活性,无需长期承诺。另外还有两种Amazon EC2实例类型来帮助您减少开支:预留实例和竞价实例。

预留实例

与按需实例价格相比,Amazon EC2预留实例允许您保存Amazon EC2计算资源来换取大量按时计费折扣。这非常适合可预测最低容量的需求。您可以利用如AWS Trusted Advisor和Amazon EC2使用报告等工具来确定您需要保留的最常用的资源。根据您购买的预留实例,折扣将在月度账单上得到反映。需要说明的是,预留实例和按需实例在技术上没有任何区别,区别只在于您付费的方式。
还有一些服务也可以选择预留实例(如Amazon Redshift、Amazon RDS、Amazon DynamoDB和Amazon CloudFront)。

贴士:在对生产中的应用程序进行充分基准测试之前,不应提交预留实例购买。 购买预留实例后,您可以使用预留实例利用率报告来确保您仍然可以充分利用预留容量。

竞价实例

对于工作量不稳定的业务,您可以考虑使用竞价实例。Amazon EC2竞价实例允许您对空闲的计算资源进行竞价。由于竞价实例通常比按需实例价格低廉,您可以由此大量节省成本。
竞价实例对那些可以灵活开始和结束的业务量非常合适。您的竞价实例将在您出价高于市场价时为您启动,并且运行至您选择停止或有人比您出更高价格时。如果竞价市场价格提升到您出价之上,您的实例将自动停止并且您无需为接下来的时间付费。
总的来说,竞价实例非常适合那些可以容忍中断的业务。但是,如果需要更可预测的可用性,还可以使用竞价型实例。

**竞价策略:**只要竞价实例在运行,您将按市场价为其付费(不是您的竞拍价)。您的竞拍策略可以比期望值略高一些,即使市场价偶尔飙升,长期来说您仍可以节省大部分开销。

**与按需实例混合:**考虑混合预留,按需和竞价型实例,将可预测的最小容量与对其他计算资源的“机会性”访问相结合,具体取决于竞价市场价格。这是一个提高应用性能和吞吐的好方法。

**固定时长的竞价实例:**您还可以竞拍固定时长的竞价实例。这些实例有不同的单小时价格但允许您设置一个需求时长。如果您的竞拍价格被接受了,实例将会一直运行直到您选择终止它或者当您的时长到期。您的实例将不会因为市场价格的变化而被停止。(当然您仍需要将这一部分设计为可容错的,因为竞价实例仍可以像其它EC2实例一样故障。)

竞价最佳实践

竞价实例允许您同时对多种类型的实例进行出价。由于每类实例的价格在一个可用区内是独立变化的,如果您的应用可以灵活运行在不同类型的实例上,您将更易获得更多计算资源。可能的话,在不同类型的实例上测试您的应用。对所有类型进行竞价,满足您的需求并长期减少您的成本。

缓存

缓存是一种存储先前计算结果以备未来使用的技术。该技术可以提高应用性能并节约实现成本。它可以应用在架构的各个部分。

应用数据缓存

应用可以使用缓存以便从快速、托管的内存介质上存储和取出数据。缓存数据可能包括IO密集型的数据库查询结果和计算密集型的输出。当缓存中找不到结果集的时候,应用可以重新计算或者从数据库中读取结果并存入缓存。当缓存中有结果时就可以直接使用,这样可以减少终端用户的延迟并减小对后台系统的压力。您的应用应该可以控制每个缓存项的存活时间。在某些场景中,对热数据进行几秒钟的缓存都可以大幅减少对数据库的压力。
Amazon EasltiCache是一个易于部署、操作和扩展的内存缓存服务。它支持两种开源的内存缓存引擎:Memcached和Redis。如想知道更多关于如何为工作负载选择存储引擎的细节,以及ElastiCache的一般设计模式,请参见《Performance at Scale with Amazon ElastiCache》白皮书。

边际缓存

静态内容的副本(如图像、CSS文件、视频流)和动态内容(如HTML响应,实时视频)可以被缓存在Amazon CloudFront中。它是一个分布在世界各地的CDN服务。边缘缓存允许内容由更接近观看者的基础设施提供服务,从而降低延迟并为您提供将高速持续的传输速率,来将大型热门对象大规模交付给最终用户。
对于您内容的请求将由Amazon S3或者您的服务器承担。如果原始请求运行在AWS上,该请求将被转移到优化后的网络路径上以获得更可靠持续的体验。Amazon CloudFront可以用来发布您整个网站包括不可缓存的内容。这得益于Amazon CloudFront重用了现有的Amazon CloudFront边缘和您服务器的连接,减少了从原始请求建立连接的延迟。连接优化同时应用于避免Internet瓶颈,完全利用了边缘和用户间的可用带宽。这意味着Amazon CloudFront可以加速传输您的动态内容并为您的用户提供持续可靠又定制化的网站浏览体验。Amazon CloudFront同样可以如下载动态内容般,为上传流量提供性能优化。

安全

大部分您在传统IT架构中已经熟知的安全工具和技术也可以应用在云上。同时,AWS允许您通过多种方式来提高安全性。AWS平台自身就可以帮助您规范安全设计。它简化了管理员和运行程序的操作,同时更容易对环境进行持续审计。这部分宏观上为您展示了AWS安全最佳实践。对于欲获得更多关于高级权限管理的细节,请参加《Security at Scale: Governance in AWS》和《AWS Security Best Practice》白皮书。

利用AWS服务来深度防御

AWS提供了丰富的服务来帮助您的系统来构建深度防御。从网络层开始,您可以构建一个VPC拓扑,利用子网、安全组和路由,将架构分隔开来。如AWS WAF服务,是一个可以保护您的web应用不受SQL注入和其它有害代码破坏的web应用防火墙。对于访问控制,您可以使用IAM来定义一个集合,赋予它们用户和组以及AWS资源。总之,AWS平台提供了多种选择来保护数据,不论是传输中的还是静态存储的数据都会进行加密。更详细的列表超出了本文范围,您可以参考AWS Security页面。

将安全责任交给AWS

AWS的操作是基于一个责任共担模型,即AWS负责底层云服务的安全,用户来负责部署在AWS上的业务安全。这样一来,您可以缩小安全管理的范围并集中关注于您业务的核心竞争力。比如,当您使用如AWS RDS、Amazon ElasticCache和Amazon CloudSearch等服务时,其安全补丁由AWS负责,这不光减少了您团队的运维工作,还可以减少暴露在风险中的可能性。

减少特权访问

当您把服务器当作可编程资源的时候,其实也可以同样对待安全领域。当您可以随时更改服务器时,可以消除客户操作系统访问生产环境的需要。如果一个实例遇到问题,您可以自动或手动终止并且替换它。当然,在您替换掉实例之前,应该先收集并中心化存储实例上的日志,来帮助您复现问题并在持续部署流程中修复它。这在临时服务器的弹性计算环境中非常重要。您可以使用Amazon CloudWatch日志来收集这些信息。当您无法访问但需要时,您可以通过使用API操作实现即时访问,以便仅在必要时打开网络以进行管理。您可以将这些访问请求与您的票务系统集成,从而这些请求可以被追踪并在允许的情况下动态执行。
另一个常见安全隐患来源就是用户账户。在传统环境中,服务账号将会被分配一个长期认证并保存在配置文件中。在AWS上,您可以通过一个临时认证,使用IAM角色来授权运行在EC2实例上的应用。这些认证会自动分发并轮转。对于移动应用,使用Amazon Cognito,授予客户端使用一个临时密钥来获得受控的访问权限。对于AWS管理控制台用户,您同样可以创建一个临时认证来获取受控的访问权限,而不是在AWS账户里创建一个IAM用户。通过这种方式,一个离职的员工将会从组织目录中移除并失去访问AWS账号的权限。

代码即安全

传统安全框架、规则、组织策略定义了安全需求,相关还有防火墙规则、网络访问控制、外部内部子网以及操作系统硬化。您同样可以在AWS环境中实现这些,而且您可以在一个脚本中集合上述所有并定义一个“金色环境”。这意味着您可以创建一个AWS CloudFormation脚本来捕获所有安全策略并可靠地部署它们。安全最佳实践可以在多个项目中复用同时成为您持续集成的一部分。您可以在发布周期中进行安全测试并且自动发现应用漏洞以便调整您的安全策略。
此外,对于更进一步的安全控制,AWS CloudFormation模板可以当作“产品”导入AWS Service Catalog。这开启了资源的中心化管理,支持统一管理、安全和匹配需求,同时使得用户可以快速部署授权的IT服务。您可以使用IAM来控制谁可以查看修改您的产品,同时您可以决定特定AWS资源在部署生产环境时的限制。

实时审计

对环境进行测试和审计是保持高速前行时又保证安全的关键。传统的定期检查方法并不足够(通常需要手动和样例),尤其是在经常变化的敏捷环境中。在AWS中,可以实现持续监控以及自动化控制来最小化应用暴露在安全隐患的可能性。如AWS Config、Amazon Inspector和AWS Trusted Advisor可以持续监控合规性和有害操作,给您一个关于IT资源是否合规的清晰图景。使用AWS Config规则,您同样可以知道一个组件是否合格,即使在一个简短的周期内,使得基于时间点和时间段的审计都非常有效。您可以为您的应用实现可扩展的日志(用Amazon CloudWatch Logs),对AWS API的调用使用AWS CloudTrail。AWS CloudTrail是一个记录API调用的服务,并且将日志文件投递到S3桶中。这些日志可以以不可变的方式来存储并且被自动处理,以通知或采取行动,从那些非合规操作中保护您的应用。您可以使用AWS Lambda、Amazon EMR、Amazon Elasticsearch Service或来自AWS Marketpalce的第三方工具来扫描如无用授权、过度授权的账号、私钥的使用、异常登录、违反策略和系统滥用。

结论

本白皮书提供了一系列关于设计架构的指导,覆盖了大部分AWS平台的重要使用原则和设计模式:从如何选择合适的数据库,到将应用设计为高可用水平扩展架构。由于每个场景都是独立的,您需要评估如何应用到您自己的业务中。对于云计算的话题非常宽广而且不断变化。您可以从AWS网站的海量材料、AWS培训和认证中持续获得更新。