IT系统架构弹性分两种,水平弹性和垂直弹性

1 垂直弹性

  • 实现途径
    通过增加单个资源的性能来实现。
  • aws中的实现方式
    在aws中可以通过先停止Instance的运行,然后可以增加其RAM,CPU,IO,Networking的性能。
  • 缺点
    垂直弹性很容易被限制。通常性价比不好,可用性也不高
  • 优点
    在某些场景下很比较容易实施,尤其在赶时间的时候。

2 水平弹性

  • 途径
    通过增加资源数量来实现。
  • aws中实现方式
    增加硬盘数量、增加服务器台数。

3 适合水平弹性的用户场景

3.1 无状态应用 stateless application

所谓的无状态应用,就是指应用完全无需知道前一交互的状态,不存储任何session信息。给这种应用同样的输入、同样的资源,它一定能提供一样的输出给最终用户。

无状态应用能够增加水平弹性的原因是:一个请求能够发给任何一个可用的计算机来处理,比如aws的EC2,lambda。因为无需共享session,所以可以毫无限制地按需增加计算机资源。当不需要那么多容量时,任何计算机都可以在任务跑完后安全地停掉。这些计算机资源完全无需知道同伴存在,只需把工作负荷分配给他们就行

3.2 如何把工作负荷分配到多个节点

How to distribute load to multiple nodes

  • 推送模式 Push model

比较流行的方式是负载均衡load balancing solution。aws的服务就是Elastice Load Balancing(ELB) service.ELB能把进来的请求路由到多台EC2,一种常规的处理方式是实现一个DNS轮转 round robin,比如aws的Amazon Route 53.在这种方案中DNS在响应请求时,从一个可用列表中轮流返回EC2的地址。这种方案虽然容易实现,但对于云计算的弹性并不是总是有效的,因为即使你给DNS记录设置了很短的TTL,但是其他DNS服务器的缓存是不受Amazon Route 53的控制,其它DNS并不一定会遵循你的设置。

  • 拉取模式 Pull model

异步事件驱动架构Asynchronous event-driven workloads 不会受限于负载均衡。在拉取模式中,需要执行的任务或者需要处理的数据被存储在消息队列Amazon Simple Queue Service(Amazon SQS) 中,或者放在数据流中 streaming data solution like Amazon Kinesis.然后可以用多个计算机节点分布式地去消耗队列中的消息

3.3 无状态组件 stateless components

  • 应用场景1

在实践中,大部分应用还是需要存储一些状态信息,比如说跟踪用户的登陆状态,或者根据前一步的交互来展示个性化的内容,以及多步骤处理应用也需要知道当前的状态才能决定下一步是什么。这种情况下依然可以使应用的一部分无状态,实现方式就是不要在服务端保存任何非单个请求需要用的信息。

比如,在http/https请求中,用cookies来保存session相关的信息(比如购物车),这样浏览器在每一个请求中都会给服务器带上这些信息,服务器就不需要在存储它们了。然而这个方案有两个缺陷,首先,因为cookies中的信息存储在客户端,所以你需要在每一步都校验其真实性。其次,因为cookies在每次请求中都会被传输,这意味着你要把数据量压缩到最小以避免不必要的时延。

为了克服第二个缺点,可以在客户端的cookies中只存储会话id之类的主键,然后把更多的对话详细信息存储在服务端,大部分编程语言中都都支持这种方式(也就是session),但是默认情况下这些session信息都被存储在服务端的文件系统中,这会导致应用变成一个有状态应用,对于这个问题的通常解决方案是,把session信息保存到一个数据库中。Amazon DynamoDB是一个绝佳的选择,因为它有着弹性、高可用性和持久性等特点,在一些编程平台中还有SDK可以让你方便快速地把信息存储到Amazon DynamoDB中

  • 应用场景2

大文件上传。可以使用AWS的文件存储层来实现无状态组件。比如Amazon S3 or Amazon Elastic File System

  • 应用场景3

复杂的多步骤工作流,你需要跟踪步骤的执行状态,Amazon Simple Workflow Service (Amazon SWF)可以用来作为中心存储这些执行历史,从而使得这些工作负载无状态

3.4 有状态组件

  • 场景1
    一些遗留系统。其设计就是用来跑在单台服务器并且依赖本地资源的

  • 场景2:有些应用场景中,客户端就是需要与服务端保持长连接,比如多人实时对战游戏,这些游戏让多人能够低时延地实时看到游戏画面,一个简单的实现方式就是让游戏者们都连接到同一台服务器。

在以上两种场景中,你仍然可以通过在负载分发时使用session affinity来获得水平弹性。在这种模式中,你需要将一个session的所有请求都分发到同一个计算机资源去。这种模式还有一个缺点,首先已经存在的会话不能直接通过新增资源而获益。更重要的是,session affinity并不可靠,当一个节点关机或者不可用时,连接到这个节点的用户将会丢失连接及其session中存储的数据信息。

3.5 如何实现session affinity?

  • 方式1

http协议的请求可以通过ELB 的sticky session策略来实现。Elastic Load Balancing会尽力把相同session的请求分发到同一个节点。

  • 方式2

如果你可以控制客户端的请求代码,那你可以使用客户端负载均衡策略。这会增加复杂性,但在服务端不能用负载均衡时(非http协议)很有效。常见的应用场景是在游戏客户端中,你想让游戏的参与者都匹配到同一台电脑,但是你用的协议服务端负载均衡又不支持.在这种模式中,客户端需要有途径知道全部可用的服务端节点,这个可以通过DNS或者专门的API接口来实现。因为没有使用负载均衡,所以客户端还需要实现健康检查的机制,当服务器不可用的时候,要能够平滑地切换到另一个节点

3.6 分布式处理

在需要大数据处理的场合,需要分布式处理。将一个大的任务分解成几个小的工作,这些小的工作量可以在任意计算机资源上完成。

  • 实现方式1

Apache Hadoop。Amazon Elastic MapReduce (Amazon EMR) service

  • 实现方式2

对于实时数据流,可以使用Amazon Kinesis将数据割裂成多个碎片,接下来就可以通过使用多个EC2来处理这些碎片数据,从而实现分布式处理