10

如果可用区在 Amazon Web Services/EC2 中出现中断,是否有任何工具或技术可用于在不同的可用区中自动创建新实例?

我想我了解如何在可用区 (AZ) 中断的情况下进行自动故障转移,但是从中断中自动恢复(在新 AZ 中创建新实例)呢?那可能吗?

示例场景:

  1. 我们有一个三实例集群。
  2. ELB 轮询到集群的流量。
  3. 我们可以丢失任何一个实例,但不能丢失集群中的两个实例,但仍然可以正常工作。
  4. 由于 (3),每个实例位于不同的 AZ。称他们为 AZs A、B 和 C。
  5. 配置 ELB 健康检查,以便 ELB 可以确保每个实例都是健康的。
  6. 假设一个实例由于 AZ A 中的 AZ 中断而丢失。

此时,ELB 将看到丢失的实例不再响应运行状况检查,并将停止将流量路由到该实例。所有请求都将转到剩余的两个健康实例。故障转移成功。

恢复是我不清楚的地方。有没有办法自动(即无需人工干预)替换新 AZ(例如 AZ D)中丢失的实例?这将避免出现中断的可用区 (A),而不使用其中已经有实例的可用区(可用区 B 和 C)。

自动缩放组?

AutoScaling Groups 似乎是一个很有前途的起点,但我不知道他们是否能正确处理这个用例。

问题:

在 AutoScaling 组中,似乎没有办法指定替换死/不健康实例的新实例应在新 AZ 中创建(例如,在 AZ D 中创建,而不是在 AZ A 中创建)。这是真的吗?在 AutoScaling 组中,似乎没有办法告诉 ELB 删除失败的 AZ 并自动添加新的 AZ。是对的吗?

这些是 AutoScaling 组中的真正缺点,还是我遗漏了什么?

如果 AutoScaling Groups 无法做到这一点,是否有其他工具可以自动为我做到这一点?

2011 年 FourSquare、Reddit 和其他人因依赖单一可用区而陷入困境 ( http://www.informationweek.com/cloud-computing/infrastructure/amazon-outage-multiple-zones-a-smart-str/240009598 ) . 从那时起,工具似乎已经走了很长一段路。我对缺乏自动恢复解决方案感到惊讶。每家公司是否只是推出自己的解决方案和/或手动进行恢复?或者他们只是在掷骰子并希望它不会再次发生?

更新:

@Steffen Opel,感谢您的详细解释。Auto Scaling 组看起来更好,但我认为它们在与 ELB 一起使用时仍然存在问题。

假设我创建了一个 Auto Scaling 组,其最小值、最大值和期望值设置为 3,分布在 4 个可用区。Auto Scaling 将在 3 个不同的 AZ 中创建 1 个实例,第 4 个 AZ 留空。如何配置 ELB?如果它转发到所有 4 个 AZ,那将不起作用,因为一个 AZ 将始终拥有零个实例,而 ELB 仍会将流量路由到它。这将导致当流量进入空 AZ 时返回 HTTP 503。我过去曾亲身经历过。这是我之前看到的一个例子

这似乎需要手动将 ELB 的可用区更新为仅在其中运行实例的可用区。每次自动缩放导致不同的可用区组合时,都需要发生这种情况。是这样吗,还是我错过了什么?

4

3 回答 3

7

有没有办法自动(即无需人工干预)替换新 AZ(例如 AZ D)中丢失的实例?

Auto Scaling确实是适合您的用例的服务 - 回答您各自的问题:

在 AutoScaling 组中,似乎没有办法指定替换死/不健康实例的新实例应在新 AZ 中创建(例如,在 AZ D 中创建,而不是在 AZ A 中创建)。这是真的吗?在 AutoScaling 组中,似乎没有办法告诉 ELB 删除失败的 AZ 并自动添加新的 AZ。是对的吗?

您不必明确指定/告诉任何内容,它隐含在 Auto Scaling 的工作方式中(请参阅Auto Scaling 概念和术语) - 您只需配置一个 Auto Scaling 组,其中包含 a)您要运行的实例数(通过定义组必须拥有的运行 EC2 实例的最小、最大和所需数量)和 b) 哪些 AZ 是您的实例的合适目标(通常/理想情况下,您的账户在一个区域内可用的所有 AZ)。

然后 Auto Scaling 负责 a) 启动请求数量的实例和 b) 在配置的 AZ 中平衡这些实例。自动处理 AZ 中断,请参阅可用区和区域

Auto Scaling 让您可以通过跨区域内多个可用区的 Auto Scaling 组来利用地理冗余的安全性和可靠性。当一个可用区变得不正常或不可用时,Auto Scaling 会在未受影响的可用区中启动新实例。当不正常的可用区恢复到正常状态时,Auto Scaling 会自动在所有指定的可用区中均匀地重新分配应用程序实例。[强调我的]

随后的多区实例分布和平衡部分进一步解释了该算法:

Auto Scaling 尝试在为您的 Auto Scaling 组启用的可用区之间平均分配实例。Auto Scaling 通过尝试在具有最少实例的可用区中启动新实例来做到这一点。但是,如果尝试失败,Auto Scaling 将尝试在其他区域中启动,直到成功。[强调我的]

请查看链接文档以获取更多详细信息以及如何处理边缘情况。

更新

关于您关于可用区数量高于实例数量的后续问题,我认为您需要采取务实的方法:

您应该简单地选择数量等于或小于您要运行的实例数量的 AZz;如果发生 AZ 中断,Auto Scaling 会很高兴地在剩余的健康 AZ 之间平衡您的实例,这意味着您将能够在示例中的 3 个 AZ 中的 2 个中断的情况下幸存下来,并且仍然让所有3 个实例在剩余的 AZ 中运行亚利桑那州。

请注意,尽管使用尽可能多的可用可用区可能很有趣,但新客户无论如何都只能访问美国东部(弗吉尼亚北部)的三个 EC2 可用区和美国西部(加利福尼亚北部)的两个可用区(请参阅全球基础设施),即只有较旧的帐户可能实际上可以访问 中的所有 5 个 AZ us-east-1,有些只有 4 个,而较新的帐户最多 3 个。

  • 我认为这是一个遗留问题,即 AWS 显然正在让较旧的 AZ 停止运行。例如,即使您可以访问 中的所有 5 个 AZ us-east-1,实际上某些实例类型可能在所有这些中都不可用(例如,新 EC2 第二代标准实例 m3.xlargem3.2xlarge并且仅在其中一个的 5 个 AZ 中的 3 个中可用。我正在使用的帐户)。

换句话说,2-3 个可用区被认为是一个区域内容错的相当好的折衷方案,如果有任何跨区域容错可能是我接下来要担心的事情。

于 2013-05-01T19:59:39.647 回答
2

有很多方法可以解决这个问题。在不知道您的“集群”是什么以及新节点如何活跃的情况下,可能会向主节点注册,加载数据等以进行引导。例如在 hadoop 上,一个新的从节点需要注册到将为其提供内容的 namenode。但忽略了这一点。只专注于新节点的启动。

您可以将 cli 工具用于 windows 或 linux 实例。我从我的两个操作系统的开发盒和两个操作系统的服务器上都将它们发射出去。这是 linux 的链接,例如:

http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/setting_up_ec2_command_linux.html#set_aes_home_linux

它们由许多命令组成,您可以在 dos 或 linux shell 上执行这些命令来执行诸如启动实例或终止实例之类的操作。它们需要配置环境变量,例如您的 aws 凭据和 java 的路径。这是在 AvailZone=us-east-1d 中创建实例的示例输入和输出

示例命令:ec2-request-spot-instances ami-52009e3b -p 0.02 -z us-east-1d --key DrewKP3 --group linux --instance-type m1.medium -n 1 --type one-time

示例输出:SPOTINSTANCEREQUEST sir-0fd0dc32 0.020000 一次性 Linux/UNIX 打开 2013-05-01T09:22:18-0400 ami-52009e3b m1.medium DrewKP3 linux us-east-1d monitoring-disabled

请注意,我是一个便宜货并使用 2 美分的 Spot 实例,因此您将使用标准实例而不是 Spot。但话又说回来,我正在创建数百台服务器。

好的,所以你有一个数据库。为论证起见,假设您有 AWS RDS mysql,微型实例以 Multi-AvailZone 模式运行,每小时额外收费半美分。也就是每天 72 美分。它包含一个表,称为 zonepref (AZ,preference)。如

us-west-1b,1

us-west-1c,2

us-west-2b,3

us-east-1d,4

eu-west-1b,5

ap-southeast-1a,6

你明白了。区域的偏好。

RDS 中还有一个类似于“active_nodes”的表,其中包含 IP addr、instance-id、zone、lastcontact、status 列(字符串、字符串、字符串、日期时间、字符)。假设它包含以下活动节点信息:

'10.70.132.101','i-2c55bb41','us-east-1d','2013-05-01 11:18:09','A'

'10.70.132.102','i-2c66bb42','us-west-1b','2013-05-01 11:14:34','A'

'10.70.132.103','i-2c77bb43','us-west-2b','2013-05-01 11:17:17','A'

'A'=活着和健康,'G'=快死了,'D'=死了

现在您的节点在启动时会建立一个 cron 作业或运行一个服务,让我们称其为使用您喜欢的任何语言(如 java 或 ruby​​)的服务器。这被烘焙到您的 ami 中以在启动时运行,并且在初始化时它会退出并将其数据插入到 active_nodes 表中,因此它的行就在那里。至少它每 5 分钟运行一次(取决于整个任务的关键程度)。cron 作业将以该时间间隔运行,或者 java/ruby 将创建一个线程,该线程将在该时间段内休眠。当涉及到生命时,它会获取它的 ipaddr、instanceid、AZ,并调用 RDS 来更新它的行,其中 status='A' 使用 UTC 时间作为 lastcontact 时间,这在不同时区是一致的。如果它的状态不是“A”,则不会发生更新。

此外,它会更新其中任何其他 ip addr 行的状态列,即 status='A',将其更改为 status='G'(即将死),就像我说的,其他 ipaddr that now()-lastcontact大于,比如说,6 或 7 分钟。此外,它可以使用套接字(选择一个端口)联系 Going Dead 服务器并说,嘿,你在吗?如果是这样,也许 Going Dead 服务器无法访问 RDS,但它位于多可用区,但仍可以处理其他流量。如果没有联系,则将其他服务器状态更改为“D”=Dead。根据需要细化。

在这里编写在其节点上运行的“服务器”的概念是具有休眠的管家线程和将阻塞/侦听端口的主线程。整个事情可以用不到 50 到 70 行代码用 ruby​​ 编写。

服务器可以使用 CLI 并终止其他服务器的实例 ID,但在此之前,它会执行一些操作,例如从 table zonepref 发出一个 select 语句,该语句按优先级排序,用于不在 active_nodes 中的第一行。它现在有下一个区域,它使用正确的 ami-id 和下一个区域等运行 ec2-run-instances,并在必要时传递用户数据。您不希望两个 Alive 服务器都创建一个新实例,因此要么在 mysql 中使用行锁包装创建,要么将请求推送到队列或堆栈中,以便只有其中一个执行它。

无论如何,这似乎有点矫枉过正,但我​​做了很多集群工作,其中节点必须直接相互通信。请注意,我并不是建议仅仅因为一个节点似乎已经失去了它的心跳,它的可用区已经关闭:>也许只是那个实例失去了它的午餐。

于 2013-05-01T15:24:02.440 回答
0

没有足够的代表发表评论。

我想补充一点,ELB 不会将流量路由到空 AZ。这是因为 ELB 将流量路由到实例,而不是 AZ。

将 AZ 附加到 ELB 只会在该 AZ的子网中创建一个弹性网络接口,以便在添加该 AZ 中的实例时可以路由流量。它正在添加创建路由的实例(AZ 与实例相关联,但也与 ELB 相关联)。

于 2014-05-16T17:47:05.470 回答