AWS EC2竞价型实例可用性

时间:2020-10-20 02:57:55

标签: amazon-web-services amazon-ec2 spot-instances

我正在使用API​​调用request_spot_instances创建竞价型实例,而没有指定任何可用区域。通常,API会选择一个随机AZ。竞价请求有时会返回无容量状态,而我可以通过另一个可用区中的AWS控制台成功请求竞价型实例。在调用request_spot_instance之前检查特定实例类型的竞价型实例的可用性的正确方法是什么?

2 个答案:

答案 0 :(得分:3)

没有公共API检查竞价型实例的可用性。话虽如此,您仍然可以通过执行以下步骤来实现所需的目标:

  1. 改为使用request_spot_fleet,并将其配置为启动单个实例。
  2. 灵活使用您所使用的实例类型,选择尽可能多的实例类型并将其包含在请求中。为了帮助您选择实例,请检查Spot Instance advisor实例中断和节省费用。
  3. 根据Spot Fleet请求,将AllocationStrategy配置为capacityOptimized,这将允许舰队从实例列表中的最可用 Spot实例分配容量,并降低可能性点中断。
  4. 不设置最高价格SpotPrice,将使用默认的竞价型实例价格。竞价的定价模式已经更改,不再基于竞标,因此竞价价格更加稳定并且不会波动。

答案 1 :(得分:0)

这可能对您要查找的内容有些夸张,但是通过部分代码,您可以找到过去一小时的现货价格历史记录(可以更改)。它会为您提供实例类型,AZ和其他信息。从那里您可以遍历实例类型到AZ。如果某个竞价型实例在30秒内没有出现,请尝试下一个可用区。

就艾哈迈德的回答而言,可以在spot_fleet_request中使用此信息,而不必循环遍历AZ。如果您在临时机群请求中传递了错误的可用区或子网,则它可能会通过dryrun api调用,但仍然可能使真实调用失败。如果要使用dryrun参数,请注意这一点。

以下是代码的输出:

In [740]: df_spot_instance_options
Out[740]:
    AvailabilityZone   InstanceType  SpotPrice  MemSize  vCPUs  CurrentGeneration Processor
0         us-east-1d        t3.nano      0.002      512      2               True  [x86_64]
1         us-east-1b        t3.nano      0.002      512      2               True  [x86_64]
2         us-east-1a        t3.nano      0.002      512      2               True  [x86_64]
3         us-east-1c        t3.nano      0.002      512      2               True  [x86_64]
4         us-east-1d       t3a.nano      0.002      512      2               True  [x86_64]
..               ...            ...        ...      ...    ...                ...       ...
995       us-east-1a    p2.16xlarge      4.320   749568     64               True  [x86_64]
996       us-east-1b    p2.16xlarge      4.320   749568     64               True  [x86_64]
997       us-east-1c    p2.16xlarge      4.320   749568     64               True  [x86_64]
998       us-east-1d    p2.16xlarge     14.400   749568     64               True  [x86_64]
999       us-east-1c  p3dn.24xlarge      9.540   786432     96               True  [x86_64]

[1000 rows x 7 columns]

这是代码:

ec2c = boto3.client('ec2')
ec2r = boto3.resource('ec2')

#### The rest of this code maps the instance details to spot price in case you are looking for certain memory or cpu
paginator = ec2c.get_paginator('describe_instance_types')
response_iterator = paginator.paginate( )

df_hold_list = []
for page in response_iterator:
    df_hold_list.append(pd.DataFrame(page['InstanceTypes']))

df_instance_specs = pd.concat(df_hold_list, axis=0).reset_index(drop=True)
df_instance_specs['Spot'] = df_instance_specs['SupportedUsageClasses'].apply(lambda x: 1 if 'spot' in x else 0)
df_instance_spot_specs = df_instance_specs.loc[df_instance_specs['Spot']==1].reset_index(drop=True)

#unapck memory and cpu dictionaries
df_instance_spot_specs['MemSize'] = df_instance_spot_specs['MemoryInfo'].apply(lambda x: x.get('SizeInMiB'))
df_instance_spot_specs['vCPUs'] = df_instance_spot_specs['VCpuInfo'].apply(lambda x: x.get('DefaultVCpus'))
df_instance_spot_specs['Processor'] = df_instance_spot_specs['ProcessorInfo'].apply(lambda x: x.get('SupportedArchitectures'))

#look at instances only between 30MB and 70MB
instance_list = df_instance_spot_specs['InstanceType'].unique().tolist()

#---------------------------------------------------------------------------------------------------------------------
# You can use this section by itself to get the instancce type and availability zone and loop through the instance you want
# just modify instance_list with one instance you want informatin for
#look only in us-east-1
client = boto3.client('ec2', region_name='us-east-1')
prices = client.describe_spot_price_history(
    InstanceTypes=instance_list,
    ProductDescriptions=['Linux/UNIX', 'Linux/UNIX (Amazon VPC)'],
    StartTime=(datetime.now() -
               timedelta(hours=1)).isoformat(),
               # AvailabilityZone='us-east-1a'
    MaxResults=1000)

df_spot_prices = pd.DataFrame(prices['SpotPriceHistory'])
df_spot_prices['SpotPrice'] = df_spot_prices['SpotPrice'].astype('float')
df_spot_prices.sort_values('SpotPrice', inplace=True)
#---------------------------------------------------------------------------------------------------------------------

# merge memory size and cpu information into this dataframe
df_spot_instance_options = df_spot_prices[['AvailabilityZone', 'InstanceType', 'SpotPrice']].merge(df_instance_spot_specs[['InstanceType', 'MemSize', 'vCPUs',
                                            'CurrentGeneration', 'Processor']], left_on='InstanceType', right_on='InstanceType')