亚马逊AWS官方博客

成本优化利器——Amazon EC2 Spot实例详细介绍

1.  前言

AWS EC2实例类型从实例类型上可以划分成通用型,计算优化型,内存优化型,存储优化型,GPU加速计算等实例类型。从实例的购买模式来看,又可以分为按需实例、预留实例、专用实例、Spot实例等类型。今天我来给大家介绍一下Spot实例这样一个非常有特色的实例类型。本文将会着重介绍Spot实例的基本概念,新的定价模型和计费方法,如何启动Spot实例,以及Spot实例的中断处理,Stop和Resume,Hibernate。希望通过这篇文章,您可以对Spot实例有个全面的了解。

2.  什么是Spot实例(Spot Instance)

Amazon EC2 Spot 实例,是 AWS服务中的可用空闲计算容量。与按需实例的价格相比,这类实例可提供超低折扣。EC2 Spot 可帮助您优化 AWS服务的成本,可在预算相同的情况下将应用程序的吞吐量提高到10倍。您只需在启动 EC2 实例时选择“Spot”,即可节省按需实例价格的 90%;

按需实例和 Spot 实例的唯一区别在于,当 EC2 需要更多容量时,它会发出两分钟的通知继而中断 Spot 实例。您可以将 EC2 Spot 用于各种容错且灵活的应用程序,如测试和开发环境、无状态 Web 服务器、图像渲染、视频转码,以运行分析、机器学习和高性能计算 (HPC) 工作负载。EC2 Spot 还可与其他 AWS 产品紧密集成,包括 EMR、Auto Scaling、Elastic Container Service (ECS)、CloudFormation等,让您可以灵活选择如何启动和维护 Spot 实例上运行的应用程序。

Spot实例是购买和使用 Amazon EC2 实例的新方式。Spot实例的现货价格根据供需情况定期变化。直接使用类似购买按需实例的方式启动Spot实例,价格将根据供需关系确定(不超过按需实例价格);用户也可以设置一个最高价,当设置的最高价高于当前现货价格的期间内运行此类实例。Spot实例是按需实例和预留实例的补充,为获得计算容量提供了另一种选择。以下是Spot实例的一些基本概念:

  • Spot实例池 – 一组未使用的 EC2 实例,具有相同的实例类型、操作系统、可用区。
  • 现货价格 – Spot 实例当前的每小时市场价格,该价格由 Amazon EC2 根据执行的最后出价设置。您还可以检索现货价格历史记录。
  • Spot实例请求 – 提供您愿意为Spot实例支付的每小时最高价格。如果您没有指定最高价格,则默认的最高价格是按需价格。当您的请求的每小时最高价格超过现货价格时,如果容量可用,Amazon EC2将满足您的请求。Spot实例请求可以是一次性的,也可以是持久性的。
  • Spot队列 – 一组基于指定条件启动的 Spot 实例。 Spot 队列会选择满足您的需要的 Spot 实例池,并启动 Spot 实例以满足队列的目标容量。默认情况下,在队列中的 Spot 实例终止之后,系统会启动替代实例以维持 Spot 队列的目标容量。您可以将 Spot 队列作为一次性请求来提交,这种请求在实例终止后不会被保留。
  • Spot实例中断 – 当现货价格超过您的请求的最高价格或容量不再可用时,Amazon EC2会终止,停止或休眠您的Spot实例。Amazon EC2会在中断发生之前2分钟给出一个Spot实例中断通知。

3.  全新的定价模型和名字的改变

熟悉“竞价型实例”的AWS服务的老用户可能会有些疑问,为什么原先的“竞价型实例”变成了“Spot实例”呢?这是因为从今年11月开始,AWS服务对该实例类型启用了全新的定价模型。

Amazon EC2 简化了 Amazon EC2 Spot 实例的定价模型,转变为提供可预测的低价,并根据长期供需趋势逐步调整价格。您将继续获得与按需实例相比高达 90% 的节省比例,且正在运行实例的现货价格在每个实例小时的开始时生效。所以从现在开始,您可以不设定价格就可以使用Spot实例,当然如果您需要控制成本,也可以像以前那样设置一个最高价,当现货价格低于您设置的最高价时,您需要的Spot实例就会被启动。鉴于定价模型的巨大变化,原先的“竞价型实例”的名字,已经成为了历史,将会用“Spot实例”这个新名称来代替。原先的“竞价出价”,也由“最高价”来进行了替换。

我们来看一下Spot实例的定价历史记录:

从上面的截图可以看出,在旧的“竞价型实例”的定价模型下,现货价格变化非常频繁,难以预测,有时价格甚至会达到按需实例价格的10倍。这使得用户非常难以制定一个合适的出价,使用起来非常不便。而在新的定价模型下,Spot实例的价格变化非常的平滑,而且最高价不会超过按需实例的价格。用户可以不设置价格,由服务自己来确定Spot实例的价格;也可以根据价格历史,合理设置最高价,这样极大地方便了用户的使用。

另外在新的定价模型下,Spot实例的启动方式也有了很大的改变。用户可以使用类似于启动按需实例的方式来启动Spot实例。具体信息可以参考“8. 购买Spot实例的操作步骤”章节。

4.  Spot实例的特点

  • 该实例价格随供需随时变化;
  • 该实例可能会被Amazon EC2中断(如果您设置的最高价不够高或者Spot实例的容量不够时);

5.  Spot实例的优势

Spot实例的最大优势就是价格便宜。Spot实例可以让客户无需预付即可购买计算容量,其小时费率也通常低于按需实例的费率。利用Spot实例,最高可以将运营成本降低 70%–90% (与按需实例相比),大幅度节约用户的使用成本。借助 Amazon EC2 Spot实例,您可以对备用的 Amazon EC2 计算容量出价。由于Spot实例相对于按需定价有一定的折扣,因此您不仅可以大大降低应用程序的运行成本,在预算不变的情况下提升应用程序的计算容量和吞吐量,还能启用新型云计算应用程序。

6.  适合Spot实例的使用场景

对于在应用程序运行时具有灵活性的客户,Spot实例可以显着降低Amazon EC2成本,例如:

√ 测试和开发环境

√ 无状态 Web 服务

√  图像渲染和视频转码

√ 科学研究和大数据分析

√ 机器学习

√ 高性能计算 (HPC)

√ 财务分析和测试

7.  Spot实例的计费方法

Spot实例的计费还有一个很大的特点是如果是Amazon EC2主动终止了Spot实例,则用户会有机会免除全部或者部分费用。这也是Spot实例和按需实例的一个很大区别。另外从今年的10月份起,Amazon EC2对一些符合条件的机型开始启用按秒计费。该计费模式也同样适用于Spot实例。新的按秒计费的计费方法,进一步帮助用户减少了Spot实例的使用成本。

  • 符合按秒计费条件的Spot实例: 在启动的第1个小时里,如果该实例因为价格原因被Amazon EC2终止,则不会产生任何费用;如果超过1小时以后产生中断,则会按秒计算费用精确到实际使用时间;如果是用户主动终止该Spot实例,即便不满1小时,也会按照实际使用时间按秒进行计费。
  • 按小时计费的Spot实例: 在启动的第1个小时里,如果该实例因为价格原因被Amazon EC2终止,则不会产生任何费用; 如果由于现货价格超过用户的出价导致Spot实例在实例小时的中间被中断,则用户无需为中断的不足1个小时部分付费;如果用户在实例小时的中间主动终止了Spot实例,则需要为该小时付费。

例如,可以参考下面表格:

操作系统 是否符合按秒计费 中断方 中断前使用时间 实际计费
Amazon Linux Amazon EC2 55分钟30秒 0
Amazon Linux 用户 55分钟30秒 55分钟30秒
Amazon Linux Amazon EC2 或用户 1小时15分钟30秒 1小时15分钟30秒
Windows Server Amazon EC2 55分钟30秒 0
Windows Server 用户 55分钟30秒 1小时
Windows Server Amazon EC2 1小时15分钟30秒 1小时
Windows Server 用户 1小时15分钟30秒 2小时

备注:Windows Server没有采用BYOL方式

有关EC2实例按秒计费的详细信息,请参考以下链接:

https://www.amazonaws.cn/new/2017/per-second-billing-for-ec2-instances-and-ebs-volumes-is-now-available-in-aws-china-beijing-region-operated-by-sinnet/

8.  购买Spot实例的操作步骤

在北京区域使用Spot实例,首选必须创建一个Spot服务相关角色,可以使用以下命令行创建该服务相关角色:

aws iam create-service-linked-role –aws-service-name spot.amazonaws.com

否则在启动Spot实例时会遇到以下报错:

 

1)  使用命令行或函数启动Spot实例:

新的定价模型,使得Spot实例的启动方式也有了很大的改变。Amazon EC2 Spot 现在支持通过 RunInstances 函数、run-instances 命令或 AWS 管理控制台启动Spot实例,只需简单地指明您希望使用 Spot。与需要了解竞价市场、出价以及调用独立异步 API 的旧模型不同,新模型是同步的,并且与按需实例一样简单易用。要通过命令行启动Spot实例,只需简单地在调用 run-instances 命令时为 InstanceMarketOption 参数指定 Spot,如果满足容量要求,您将立即收到实例 ID。例如,你可以使用以下命令行,使用类似于启动按需实例的方法启动一个Spot实例:

当然,为了保持兼容性,以前的RequestSpotInstances或者RequestSpotFleet函数/命令行将继续有效,不过不在需要SpotPrice这个参数了。

另外用户也可以使用AWS EC2的request-spot-instances命令行的方式来购买Spot实例,详细内容请参考链接:

docs.aws.amazon.com/cli/latest/reference/ec2/request-spot-instances.html

2)  在管理控制台启动和管理Spot实例:

在AWS的管理控制台上,用户可以在启动新的实例的时候,可以直接勾选“请求竞价型实例”,设置好出价,进行Spot实例的购买:

为了简化Spot实例的购买流程,AWS服务也提供了Spot实例队列(Spot Fleet)的方式来请求Spot实例。Spot队列会尝试启动适当数量的Spot实例,以满足在Spot队列请求中指定的目标容量要求。如果您的Spot实例由于现货价格或可用容量的变化而中断,则Spot队列还会尝试维持其目标容量队列。下面我来演示一下如何在AWS管理控制台的操作界面上通过几下点击创建一个Spot Fleet的请求。

在EC2的页面上选择“竞价请求”:

进入竞价请求页面以后,我们可以看到“请求竞价型实例”,“定价历史记录”等选项。

点击“请求Spot实例”

请求类型分为三种:

a)  请求:该请求类型用户提交一次性Spot实例请求。如果现货价格提高并超过您的出价,Spot实例会终止,Spot实例请求关闭;

b)  请求并维护:当选择这个类型的Spot实例时,会自动补充由Spot实例中断关闭的实例;

c)  预留持续时间:当现货价格发生更改时,Amazon EC2 不会终止带有指定持续时间的Spot实例 (也被称作Spot限制)。这使得此实例非常适合需在有限时间内完成的任务,如批处理、编码和渲染、建模和分析以及连续集成。您可将持续时间指定为 1-6 小时。

目标容量:

可以以设置实例的数量,也可以设置vCPU的个数:

AMI的设置可以是系统默认的AMI:

也可以是自定义的AMI:

例如,需要启动4台C4.large实例,AMI为自定义的Linux的系统:

设置实例的类型:

上面截图中我们可以看到Spot实例现货价格和优惠比例。例如C4系列的机型,Spot实例类型比按需实例便宜了88%,使用Spot实例的成本仅为按需实例的12%。

注意在这个页面上提供了“定价历史记录”来帮助用户选择机型。点击”定价历史记录“,会显示出某个机型的市场价格历史记录和当前价格,作为用户做出价的参考:

选择完机型以后,显示如下,Amazon EC2会在这几种机型里面进行Spot实例的选择:

设置分配策略,网络,可用区和最高价,点击下一步:

分配策略:

a)  最低价格:Spot 实例来自具有最低价格的池。这是目前AWS推荐的使用方式。这种方式下Amazon EC2会使用新的定价模型,寻找价格最低的Spot实例给用户。

b)  多样化:如果您的队列较大或长时间运行,则您可以通过在多个池间分配Spot实例来提高队列的可用性。例如,如果您的Spot队列请求指定 10 个池,且目标容量为 100 个实例,则Spot队列会在每个池中启动 10 个Spot实例。如果一个池的现货价格上涨到超过您对该池的出价,则只有队列的 10% 受到影响。使用此策略还可降低您的队列对单个池的现货价格随时间上涨的敏感度。

设置最高价:

a)  自动出价:采用新的定价模型,按照市场现货价格预配置Spot实例,以按需价格为上限。

b)  自己设置最高价:如果有些用户想把成本控制在一定范围之内,也可以自己手工设定一个能够接受的最高价。通过定价历史记录显示,C4.large Linux机型现货价格为每小时0.13-0.14元之间:

例如:参考历史价格和当前现货价格,用户可以手工设定一个0.14元每vCPU每小时的价格,来进行出价:

 

点击下一步以后,在设置页面,设置好存储,用户数据,密钥对,IAM Role,安全组,有效时间以后,进入审核页面:

进入审核,进入审核页面:

点击“启动”即可启动Spot实例:

等待该Spot请求变为Active状态,可以看到所有的已经启动的Spot实例的信息:

第二天检查了一下当前账单,发现使用了28个实例小时的C4.large, 总共花费才3.81元,相对于每小时1.134元的按需实例成本降低了很多:

9.  如何处理Spot实例的中断

前面文中提到Spot实例的一个特点是当用户的出价低于现货价格时,Spot实例会被中断。当没有足够的未用 EC2 实例来满足对Spot实例的需求时,Amazon EC2 将从出价最低的实例开始中断Spot实例。如果多个Spot实例的出价相同,则随机确定实例的中断顺序。所以如果您有长时间的任务需要运行的话, 建议可以把出价定高一些,这样可以大大减少中断的可能性。另外如果您希望Spot实例在一段时间内保证不会被中断,也可以使用预留持续时间的方式购买Spot实例,这样在一段持续时间内,无论Spot实例的现货价格如何变化,您运行的Spot实例都不会被中断。当然,这种Spot实例的价格相对于普通的Spot实例价格会高一些。

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

  • 价格 – 现货价格高于您设置的最高价。
  • 容量 – 如果没有足够的未使用的EC2实例来满足Spot实例的需求,Amazon EC2会中断Spot实例。 Amazon EC2确定实例中断的顺序。
  • 约束 – 如果您的请求包含约束,例如启动组或可用区组,那么,当不再满足约束条件时,这些Spot实例将作为一个组终止。

用户可以通过EC2的元数据中instance-action条目获取到该实例的状态,可以按如下方式检索它:

curl http://169.254.169.254/latest/meta-data/spot/instance-action

instance-action 项目指定操作 (停止或终止) 和操作发生的大致时间 (用 UTC 表示)。以下示例指示将停止此实例的时间:

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

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

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

如果Spot实例标记为由Spot服务终止,则您的实例元数据中将显示 termination-time 项目。为向后兼容而保留此项目。您可以按如下方式检索它:

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

用户可以参考上述方法编写脚本,运行定时任务来检查当前Spot实例的状态,以便运行在Spot实例里的应用程序及时应对。

10.  支持Stop、Resume和 Hibernate

默认情况下,在Spot实例中断时将其终止。但是这样做会导致用户数据的丢失,给用户带来了极大的不便。

从今年9月份起,Spot实例支持Stop and Resume功能。 当实例中断时,EC2只是Stop该实例,并不终止该实例和删除EBS的boot盘和数据盘,这样OS和所有的数据都能得到保存。当Spot实例池的容量恢复或者现货价格低于用户设置的最高价以后,EC2会帮助用户重新Start该实例,详细内容请参考链接:

https://amazonaws-china.com/cn/blogs/aws/new-stop-resume-workloads-on-ec2-spot-instances/

现在,用户可以指定 Amazon EC2 在Spot实例中断时是应将其停止还是终止。满足以下要求时,Amazon EC2 在Spot实例中断时将其停止:

  • 对于Spot实例请求,类型必须是 “persistent”,而不是 “one-time”。您不能在Spot实例请求中指定启动组或可用区组。
  • 对于Spot队列请求,类型必须是”请求并维护(maintain)”,而不只是”请求 (request)”。
  • 根卷必须是 EBS 卷,而不是实例存储卷。

最近AWS针对实例的Stop和Resume又更进一步推出了Hibernate(休眠)的功能。这样用户的内存中如果有大量的工种状态,在Spot实例被Stop的时候,会把内存中的数据写到磁盘上,在Resume的时候再从磁盘恢复内存中的数据。如果您运行的内存中保持大量状态的工作负载,您将会喜欢这个新功能。要启用休眠功能,您必须安装一个hibernation的agent,并且在实例启动的时候把他运行起来。另外,休眠功能对操作系统的类型,Spot的启动方式等也有一定的条件的要求,因为篇幅有限,详细信息请参考官方文档。

有关Stop和Hibernate的详细信息,请参考AWS官方链接:

http://docs.amazonaws.cn/en_us/AWSEC2/latest/UserGuide/spot-interruptions.html

11.  防范中断的最佳实践

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

下面提供了在您使用Spot实例时可以遵循的最佳实践:

  • 选择一个合理的最高价。
  • 使用包含所需软件配置的 Amazon 系统映像 (AMI),确保您的实例在请求完成时随时可以启动。
  • 在不会受Spot实例终止影响的位置例行存储重要数据。
  • 将工作拆分为小的任务 (使用网格、Hadoop 或基于队列的架构) 或者使用检查点,以便您经常保存工作。
  • 使用Spot实例中断通知监控您的Spot实例的状态。
  • 测试应用程序,确保它很好地处理了意外的实例终止。

12.   使用Spot实例的最佳实践

  • 灵活使用实例类型:尽可能使用不同的实例类型测试您的应用程序。由于可用区内的每个实例类型的价格分开波动,因此,如果您灵活使用实例类型,则通常可以在价格不变的情况下获得更多计算容量。对满足您要求的所有实例类型设置最高价,可以进一步降低成本,并提升应用程序的性能。借助Spot队列,您可以同时对多个实例类型设置最高价。
  • 选择价格趋势有利的池:由于价格因供求关系、热门实例类型(如最近启动的实例系列)而发生波动,因此Spot实例定价往往变化较大。所以,选择不太热门的较旧实例类型往往能降低成本和减少中断。同样,不同可用区中同一实例类型的价格也可能不同。
  • 设置满足您要求的最高价:通常情况下,最好开始以按需实例价格或接近的价格设置最高价。出价较低能够进一步降低成本,而出价较高则可以降低中断发生的可能性。

13.   更多内容

更多有关Spot实例的相关内容,请大家参考AWS EC2的官方文档和FAQ:

http://docs.amazonaws.cn/AWSEC2/latest/UserGuide/using-spot-instances.html

https://www.amazonaws.cn/ec2/faqs/#spot-instances

 

作者介绍

张春涛,AWS解决方案架构师,负责基于AWS的云计算方案的架构设计,同时致力于AWS云服务在国内和全球的应用和推广。在加入AWS之前,曾就职于Motorola,TrendMicro,Citrix等公司。在大规模应用开发及架构,网络安全,桌面云,服务器虚拟化,企业IT等领域有广泛的设计与实践经验。