我正在创建 3 个 EC2 实例,然后对每个实例进行迭代和标记。有时标签请求会失败,尽管实例稍后似乎正在运行。
这可能是时间问题吗?我应该在创建实例后等待几秒钟再标记它吗?是否有确定的方法来等待它开始?
我正在创建 3 个 EC2 实例,然后对每个实例进行迭代和标记。有时标签请求会失败,尽管实例稍后似乎正在运行。
这可能是时间问题吗?我应该在创建实例后等待几秒钟再标记它吗?是否有确定的方法来等待它开始?
AWS 同时添加了关于Troubleshooting API Request Errors的更详细的文档,包括解决最终一致性的部分,这基本上证实了我在下面的初始答案中的分析:
由于支持 API 的系统的分布式特性,Amazon EC2 API 遵循最终一致性模型。这意味着您运行的影响 Amazon EC2 资源的 API 命令的结果可能不会立即对您运行的所有后续命令可见。[...]
[...] 例如,[...]如果您运行命令来修改或描述您刚刚创建的资源,它的 ID 可能没有在整个系统中传播,并且您将收到一个错误响应资源确实不存在。
要管理最终一致性,您可以执行以下操作:
在运行命令修改资源之前确认资源的状态。使用指数退避算法运行适当的 Describe 命令,以确保您有足够的时间让前一个命令在系统中传播。[...]
在后续命令之间添加等待时间,即使 Describe 命令返回准确的响应。从几秒钟的等待时间开始应用指数退避算法,然后逐渐增加到大约五分钟的等待时间。
[强调我的]
请注意:大多数AWS 开发工具包同时自动应用这些建议,包括调整默认重试策略或添加自定义实施的选项 - 如果需要,请参阅AWS 中的错误重试和指数退避以获取有关如何自行实施的指导。
AWS API 的最终一致性设计越来越多地被各种大规模 AWS 用户所遇到,他们自然需要深入研究并相应地解决它,例如,请参阅以下文章:
正如@datasage 已经评论的那样,AWS API 显然只需要被视为最终一致的——这在第一次遇到时肯定是出乎意料的,但对于事后看来的大规模服务(即工程响应)来说实际上并不太令人惊讶。操作权衡来解决CAP 定理。
另请参阅我对 Alex Ciminian 的问题Implementing idempotency for AWS Spot Instance Requests的评论,其中他讨论了他关于类似一致性问题的测试结果:
有趣的问题 - [...] 我在Bamboo AWS 插件的上下文中遇到了各种类似的 API 延迟,并得出结论认为 AWS API 需要被视为最终完全一致;例如,我什至遇到过从 create 调用收到资源 id 的情况,可以根据其 id 标记资源,但此后仍不对其进行描述,因为它应该不存在(尚不存在)。
有关上述案例的详细信息,您可能需要查看AWS API 的频繁轮询导致限制限制,我在其中总结了我们的分析和方法,以通过适用于 Java 的 AWS 开发工具包中可用但有限的重试/退避功能改进处理- 解决方案几乎是理想的,但它似乎暂时大大改善了事情。
同样,针对 PHP 2 重新设计的 AWS 开发工具包引入了专用的“Waiter”对象,允许您轮询资源,直到它处于解决问题所需的状态,有关详细信息,请参阅快速入门中的Waiters部分:
SDK 提供的高级抽象之一是“服务员”的概念。服务员通过轮询资源提供了一种简单的方法来等待资源进入特定状态,从而帮助更轻松地使用最终一致的系统。[...] 任何以“waitUntil”开头的@method 标签都会使用一个服务员。
$client->waitUntil('BucketExists', array('Bucket' => 'my-bucket'));
在启动实例之前无法创建标签名称。您可以尝试在创建实例时提供 key_name。如果您使用的是 boto,则可以通过
reservation = conn.run_instances(1, 1, instance_type='m1.small', key_name='samplename')
然后可以通过传递 key_name 来检索实例,一旦它们处于运行状态,您还可以为它们提供标签名称。