从可用区域中断自动恢复?

时间:2013-05-01 02:57:25

标签: amazon-web-services amazon-ec2 autoscaling

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

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

示例场景:

  1. 我们有一个三实例集群。
  2. ELB循环访问群集的流量。
  3. 我们可以丢失任何一个实例,但不能丢失群集中的两个实例,并且仍然可以完全正常运行。
  4. 由于(3),每个实例都在不同的AZ中。称他们为亚洲A,B和C.
  5. 配置ELB运行状况检查,以便ELB可以确保每个实例都健康。
  6. 假设由于AZ A中的AZ中断而导致一个实例丢失。
  7. 此时,ELB将看到丢失的实例不再响应运行状况检查,并将停止将流量路由到该实例。所有请求都将转到剩下的两个健康实例。故障转移成功。

    恢复是我不清楚的地方。有没有办法自动(即没有人为干预)替换新AZ中的丢失实例(例如AZ D)?这将避免具有中断(A)的AZ并且不使用已经具有实例的AZ(AZs B和C)。

    AutoScaling Groups?

    AutoScaling群组似乎是一个很有前途的开始,但我不知道他们是否可以正确处理这个用例。

    问题:

    在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欧宝,感谢detailed explanation。自动缩放组看起来更好,但我认为与ELB一起使用时仍存在问题。

    假设我使用min,max和amp;创建一个自动缩放组。期望设置为3,分布在4个AZ中。自动缩放将在3个不同的AZ中创建1个实例,第4个AZ保留为空。如何配置ELB?如果它转发到所有4个AZ,那将无法工作,因为一个AZ将始终具有零实例,并且ELB仍将路由流量到它。这将导致在流量进入空AZ时返回HTTP 503。我过去经历过这一点。 Here is an example of what I saw before

    这似乎需要手动将ELB的AZ更新为那些在其中运行实例的AZ。每次自动缩放导致不同的AZ混合时,都需要进行此操作。是的,或者我错过了什么?

3 个答案:

答案 0 :(得分:7)

  

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

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

  

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

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

Auto Scaling然后负责a)启动所请求的实例数量,以及b)在配置的AZ中平衡这些实例。 AZ中断会自动处理,请参阅Availability Zones and Regions

  

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

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

  

Auto Scaling尝试在为Auto Scaling组启用的可用区之间均匀分布实例。 Auto Scaling通过尝试使用最少的实例在可用区中启动新实例来实现此目的。但是,如果尝试失败,Auto Scaling将尝试在其他区域中启动,直到成功为止。 [强调我的]

请查看链接的文档以获取更多详细信息以及边缘案例的处理方式。

更新

关于有关AZ数量高于实例数量的后续问题, 我认为你需要采取务实的方法:

您应该只选择等于或低于您想要运行的实例数量的AZz数量;如果发生AZ中断,Auto Scaling将很乐意在剩余的健康AZ中平衡您的实例,这意味着您可以在示例中的3个AZ中的2个中断,并且仍然所有 3个实例。

请注意,虽然使用尽可能多的AZ可能很有趣,但新客户可以访问美国东部(弗吉尼亚北部)和美国西部(北加利福尼亚州)的两个EC2可用区仅反正(请参阅Global Infrastructure),即只有较旧的帐户实际上可以访问us-east-1中的所有5个AZ,有些只有4个,最新的3个。

  • 我认为这是一个遗留问题,即AWS显然正在使旧的AZ停止运行。例如,即使您可以访问us-east-1中的所有5个AZ,实际上某些实例类型也可能无法使用(例如New EC2 Second Generation Standard Instances m3.xlarge和{{1}只在我正在使用的一个帐户中的5个AZ中有3个可用。

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

答案 1 :(得分:2)

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

你可以使用windows或linux实例的cli工具。我从我的开发盒和操作系统两个操作系统中都将它们关闭。这里是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监控禁用

请注意,我是一个便宜的使用2美分竞价型实例,您将使用标准实例,而不是现场。但是我又创造了数百台服务器。

好的,所以你有一个数据库。为了论证,让我们说你有AWS RDS mysql,微实例以Multi-AvailZone模式运行,每小时额外增加半美分。那是每天72美分。它包含一个表,称之为zonepref(AZ,首选项)。比如

我们西-1B,1

我们西-1C,2

我们西-2B,3

我们东-1D,4

EU-西-1B,5

AP-东南-1A,6

你明白了。区域的偏好。

RDS中还有另一个表,类似于“active_nodes”,其中包含IP addr,instance-id,zone,lastcontact,status(string,string,string,datetime,char)。假设它包含以下活动节点信息:

'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',则不会发生更新。

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

编写在其节点上运行的“服务器”的概念是一个具有睡眠的内务线程,以及将阻塞/侦听端口的主线程。整个事情可以用不到50到70行代码用ruby编写。

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

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

答案 2 :(得分:0)

没有足够的评论来评论。

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

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