3.3 弹性能力——纵向扩展与水平伸缩
上一节介绍了云服务的计价方式,按需计价是云服务的主要特征,而这种计价方式在需求频繁变化时,更容易显示出其价值。这一节再来谈谈云服务的“可伸缩性”。
3.3.1 什么是可伸缩性?
如果当前系统的处理能力无法支撑业务需求,就需要扩展系统。而系统的扩展有以下两种方式。
● 纵向扩展(Scale Up):一般指升级当前使用资源的规格,从而获得更高的性能。例如,对于一台虚拟机而言,纵向扩展可以是增加它的内存,增加CPU的核数,或者切换为计算优化的CPU类型。这种方式一般适用于业务请求变得复杂,或者业务数据量增加,但是相互之间又有大量关联,无法简单分而治之的情况。
● 横向扩展(Scale Out):通过增加当前使用资源的个数,把业务压力尽可能均匀地分布在资源的不同资源实例上。这种方式一般适用于有大量相对独立的业务处理请求的情况。
由于云服务可以即时申请所需资源,所以即使是手动扩展系统,也只需在云服务商的页面上进行简单的操作,就能扩展对应的业务模块。但是云服务给用户带来的便利不止于此。通过程序调用一组应用程序接口(Application Programming Interface,API)监控对应的指标,用户可以自动地找到需要扩展的时机,然后再用程序调用另一组API,扩展用户的系统。例如,对于一个网站,在用户访问量增加时,加入更多的服务进程,升级数据库的CPU和内存大小。
常用的监控指标,一般包括以下几个方面。
● CPU使用的百分比。
● 内存使用的百分比。
● 磁盘队列长度。
● HTTP队列长度。
● 单位时间业务数据的流量。
3.3.2 自动化扩展云服务的一般设计
云服务由于虚拟化的存在,纵向扩展可以获得极高的自由度,比如在运行时升级内存甚至CPU资源。但是从目前业界的最佳实践而言,横向扩展是更加直接的方式。如果需要充分利用云服务的横向扩展能力,以下几点必须注意。
1)业务系统必须设计成可横向扩展的。避免对实例之间的关联性做出假设;不要出现某一业务逻辑必须在流程的特定实例中运行的设计。在横向扩展We b站点时,不要假设来自同一来源的一系列请求总是被路由到同一个实例。出于同样的原因,将服务设计为无状态,以避免将来自应用程序的一系列请求始终路由到服务的相同实例。在设计从队列读取消息并处理消息的服务时,不要对服务的哪个实例处理特定的消息做出任何假设。随着队列长度的增长,自动缩放可以启动服务的其他实例。竞争消费者模式描述了如何处理这种情况。
2)如果方案中有长时间运行的任务,则此任务需要支持动态增减实例。如果没有适当的注意,这样的任务可能会导致在系统扩展时无法干净地关闭进程实例,或者在强制终止进程时丢失数据。理想情况下,重构一个长时间运行的任务,并将其执行的处理分解为更小的、离散的块。利用管道和过滤器模式实现此目的。也可以实现一个检查点机制,定期记录关于任务的状态信息,并将此状态保存在持久存储中,运行该任务流程的任何实例都可以访问该持久存储。通过这种方式,如果进程被关闭,则可以通过使用另一个实例从最后一个检查点恢复它正在执行的工作。
3)不要用横向扩展应对短时间突发访问量暴增的情况。自动化的横向扩展不一定是处理工作负载短时间暴增的最合适的机制。提供和启动服务的新实例或向系统添加资源都需要时间,而且在这些额外资源可用时,需求的峰值可能已经过去了。此时应该考虑其他机制,如用队列来缓冲暴增的业务量。
3.3.3 实例——扩展Azure上的网站
微软Azure Web App提供了多种扩展网站的方法,用户可以在Azure Portal上进行操作。
1.纵向扩展
Azure Web App的扩展操作相当于将一个常规Web网站移动到更大的物理服务器。因此,当网站达到限额需要考虑扩展操作时,这表明用户正在超出现有的模式或选项。此外,几乎可以在任何内站进行扩展,而不必担心多实例数据一致性的影响。Azure提供了不同配置的Web网站的宿主,供用户选择,如图3-9所示。
图3-9 Azure上对扩展Web网站的宿主配置的选项
2.横向拓展
横向扩展操作相当于创建We b网站的多个副本,并添加负载均衡器在它们之间分配需求。当用户在Azure Web网站中扩展一个网站时,不需要单独配置负载平衡,因为平台已经提供了这一功能。
如果用户是Standard或者以上的Web App Plan,用户将看到基于条件的自动横向扩展选项。如图3-10所示是根据CPU的负载,在动态增加实例的数量。
图3-10 根据条件自动横向扩展的配置示例
[1] GB×s是指用户分配给Lambda的内存数量乘以用户使用的时间。例如,分配了10GB内存,运行了0.1s,那么消耗的用量是10×0.1=1GB×s。