Amazon Elastic Compute Cloud
Linux 实例用户指南
AWS 文档中描述的 AWS 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 Amazon AWS 入门

Spot 实例中断

对 Spot 实例的需求可能因时间不同而有显著的差异,Spot 实例的可用性也会因为有多少未使用 EC2 实例可用而差别巨大。始终可能会中断您的Spot 实例。因此,必须确保应用程序针对Spot 实例中断做好准备。

下面列出了 Amazon EC2 中断 Spot 实例的可能原因:

  • 价格 – Spot 价格高于您的最高价。

  • 容量 - 如果没有足够的未使用 EC2 实例,无法满足 Spot 实例的需求,则 Amazon EC2 会中断 Spot 实例。实例的中断顺序是由 Amazon EC2 确定的。

  • 约束 – 如果请求中包含约束,例如启动组或可用区组,则当不再满足约束条件时,这些 Spot 实例将成组终止。

无法中断在 Spot 队列中指定的个按需实例。

中断行为

您可以指定在 Spot 实例中断时 Amazon EC2 应将其休眠、停止还是终止。您可以选择满足您的需求的中断行为。默认方式是在 Spot 实例中断时将其终止。要更改中断行为,请从控制台的中断行为中选择一个选项,或者在启动配置或启动模板中选择 InstanceInterruptionBehavior

停止中断的 Spot 实例

您可以更改中断行为,以便在满足以下要求时,Amazon EC2 停止中断的 Spot 实例。

要求

  • 对于Spot 实例请求,类型必须是 persistent,而不是 one-time。您不能在Spot 实例请求中指定启动组。

  • 对于Spot 队列请求,类型必须是 maintain,而不是 request

  • 根卷必须是 EBS 卷,而不是实例存储卷。

在 Spot 服务停止一个Spot 实例后,该实例只能由 Spot 服务使用同一启动配置来重新启动。在匹配某个已停止的Spot 实例的可用区和实例类型的容量可用时,该Spot 实例将启动。对于Spot 队列,如果容量仅适用于其他可用区或实例类型,则Spot 队列将使用具有可用容量的启动配置来启动一个新的Spot 实例。

在Spot 实例停止后,您可以修改其部分实例属性,但不能修改实例类型。如果您分离或删除一个 EBS 卷,则在Spot 实例启动时不会挂载该卷。如果您分离根卷,并且 Spot 服务尝试启动Spot 实例,则该实例将启动失败,并且 Spot 服务将终止已停止的实例。

当Spot 实例停止时,您可以将其终止。如果取消某个 Spot 请求或 Spot 队列,则 Spot 服务将终止所有已停止的关联 Spot 实例。

在Spot 实例停止后,您只需为保留的 EBS 卷付费。对于Spot 队列,如果您有许多已停止的实例,则可以超出您的账户的 EBS 卷数限制。

休眠中断的 Spot 实例

您可以更改中断行为,以便在满足以下要求时,Amazon EC2 在 Spot 实例中断时将其休眠。

要求

  • 对于Spot 实例请求,类型必须是 persistent,而不是 one-time。您不能在Spot 实例请求中指定启动组。

  • 对于Spot 队列请求,类型必须是 maintain,而不是 request

  • 根卷必须是 EBS 卷,而不是实例存储卷,并且它必须足够大以在休眠期间存储实例内存 (RAM)。

  • 支持以下实例:C3、C4、C5、M4、M5、R3 和 R4,并且内存少于 100 GB。

  • 支持以下操作系统:Amazon Linux 2、Amazon Linux AMI、AWS 优化的 Ubuntu 内核 (linux-aws) 高于 4.4.0-1041 的 Ubuntu 以及 Windows Server 2008 R2 和更高版本。

  • 在支持的操作系统上安装休眠代理,或者使用已包含该代理的以下 AMI 之一:

    • Amazon Linux 2

    • Amazon Linux AMI 2017.09.1 或更高版本

    • Ubuntu Xenial 16.04 20171121 或更高版本

    • Windows Server 2008 R2 AMI 2017.11.19 或更高版本

    • Windows Server 2012 或 Windows Server 2012 R2 AMI 2017.11.19 或更高版本

    • Windows Server 2016 AMI 2017.11.19 或更高版本

  • 启动该代理。我们建议您使用用户数据在实例启动时启动该代理。或者,您也可以手动启动该代理。

建议

  • 我们强烈建议您将加密的 EBS 卷作为根卷,因为在休眠期间实例内存存储在根卷上。这确保在卷上静态存储数据以及在实例和卷之间移动数据时,将加密内存 (RAM) 内容。如果您的 AMI 没有加密的根卷,您可以将其复制到新的 AMI 并请求加密。有关更多信息,请参阅 Amazon EBS Encryption复制 AMI

在 Spot 服务将Spot 实例休眠时,将保留 EBS 卷并在根卷上保留实例内存 (RAM)。还会保留实例的私有 IP 地址。不会保留实例存储卷和公有 IP 地址 (非弹性 IP 地址)。在实例休眠时,仅向您收取 EBS 卷费用。对于Spot 队列,如果具有很多休眠的实例,则可能会超过您的账户的 EBS 卷数限制。

在实例从 Spot 服务收到指令时,该代理将提示操作系统休眠。如果未安装该代理,则底层操作系统不支持休眠,或者没有足够的卷空间以保存实例内存,休眠将失败并且 Spot 服务停止该实例。

在 Spot 服务将Spot 实例休眠时,将收到一条中断通知,但不会在Spot 实例中断之前留出两分钟的时间。将立即开始休眠。在实例进行休眠过程中,实例运行状况检查可能会失败。在休眠过程完成时,实例状态为 stopped

在 Spot 服务将Spot 实例休眠后,只能由 Spot 服务恢复该实例。如果 Spot 价格低于您指定的最高价,并且具有可用的容量,Spot 服务将恢复该实例。

有关更多信息,请参阅 准备将实例休眠

准备中断

下面是在使用 Spot 实例时可以遵循的一些最佳实践:

  • 使用默认最高价 (这是按需价格)。

  • 使用包含所需软件配置的 Amazon 系统映像 (AMI),确保您的实例在请求完成时随时可以启动。您还可以使用用户数据在启动时运行命令。

  • 在不会受Spot 实例终止影响的位置例行存储重要数据。例如,您可以使用 Amazon S3、Amazon EBS 或 DynamoDB。

  • 将工作拆分为小的任务 (使用网格、Hadoop 或基于队列的架构) 或者使用检查点,以便您经常保存工作。

  • 使用Spot 实例中断通知监控您的 Spot 实例的状态。

  • 虽然我们尽一切努力尽快提供此警告,但您的Spot 实例可能会在我们提供此警告之前被终止。测试您的应用程序,确保它很好地处理了意外的实例终止,即使您正在针对中断通知进行测试。您可以使用个按需实例来运行应用程序,然后自行终止该个按需实例,以便确认这一点。

准备将实例休眠

您必须在您的实例上安装休眠代理,除非您使用已包含该代理的 AMI。您必须在实例启动时运行该代理,无论该代理是包含在您的 AMI 中,还是您自行安装的。

下列步骤帮助您准备 Linux 实例。有关准备 Windows 实例的说明,请参阅 Amazon EC2 用户指南(适用于 Windows 实例) 中的准备将实例休眠

准备 Amazon Linux 实例

  1. 确认您的内核支持休眠,并在必要时更新内核。

  2. 如果您的 AMI 不包含该代理,请使用以下命令安装该代理:

    sudo yum update; sudo yum install hibagent
  3. 将以下内容添加到用户数据中:

    #!/bin/bash /usr/bin/enable-ec2-spot-hibernation

准备 Ubuntu 实例

  1. 如果您的 AMI 不包含该代理,请使用以下命令安装该代理:

    sudo apt-get install hibagent
  2. 将以下内容添加到用户数据中:

    #!/bin/bash /usr/bin/enable-ec2-spot-hibernation

Spot 实例中断通知

防范Spot 实例中断的最佳方法是为应用程序设计容错能力。此外,您还可以利用Spot 实例中断通知,该通知可在 Amazon EC2 必须中断您的Spot 实例时,提前两分钟发出警告。建议您每 5 秒检查一次这些警告。

此警告作为 CloudWatch 事件以及Spot 实例上实例元数据中的项目提供。

EC2 Spot 实例 Interruption Warning

Amazon EC2 中断您的Spot 实例时,它会发出可由 Amazon CloudWatch Events 检测到的事件。有关更多信息,请参阅 Amazon CloudWatch Events 用户指南

以下是Spot 实例中断事件的示例。instance-action 的可能值为 hibernatestopterminate

{ "version": "0", "id": "12345678-1234-1234-1234-123456789012", "detail-type": "EC2 Spot Instance Interruption Warning", "source": "aws.ec2", "account": "123456789012", "time": "yyyy-mm-ddThh:mm:ssZ", "region": "us-west-2", "resources": ["arn:aws-cn:ec2:us-west-2:123456789012:instance/i-1234567890abcdef0"], "detail": { "instance-id": "i-1234567890abcdef0", "instance-action": "action" } }

instance-action

如果Spot 实例标记为由 Spot 服务休眠、停止或终止,将在您的实例元数据中包含 instance-action 项目。如果没有,则不显示。您可以按如下方式检索 instance-action

[ec2-user ~]$ curl http://169.254.169.254/latest/meta-data/spot/instance-action

instance-action 项目指定操作及其大致执行时间 (采用 UTC 格式)。以下示例指示将停止此实例的时间:

{"action": "stop", "time": "2017-09-18T08:22:00Z"}

以下示例指示将终止此实例的时间:

{"action": "terminate", "time": "2017-09-18T08:22:00Z"}

以下示例指示已立即启动休眠:

{"action": "hibernate", "time": "2017-11-28T08:22:00Z"}

如果 Amazon EC2 未准备休眠、停止或终止实例,或者,如果您自己终止了实例,则 instance-action 不存在且您会收到 HTTP 404 错误。

termination-time

为向后兼容而保留此项目;您应改为使用 instance-action

如果Spot 实例标记为由 Spot 服务终止,则您的实例元数据中将显示 termination-time 项目。如果没有,则不显示。您可以按如下方式检索 termination-time

[ec2-user ~]$ if curl -s http://169.254.169.254/latest/meta-data/spot/termination-time | grep -q .*T.*Z; then echo terminated; fi

termination-time 项目指定实例将收到关闭信号的大致时间 (用 UTC 表示)。例如:

2015-01-05T18:02:00Z

如果 Amazon EC2 未准备终止实例,或者,如果您自己终止了 Spot 实例 实例,则 termination-time 项目或者不存在 (这样您会收到 HTTP 404 错误),或者包含并非时间值的值。

如果 Amazon EC2 无法终止实例,请求状态将设置为 fulfilled。请注意,termination-time 会将实例元数据保持原始大致时间 (现已成为过去时间)。