#amazon-web-services #amazon-ec2 #spot-instances
#amazon-веб-сервисы #amazon-ec2 #спотовые инстансы
Вопрос:
Я использую вызов API request_spot_instances
для создания точечного экземпляра без указания какой-либо зоны доступности. Обычно API выбирает случайный AZ. Запрос spot иногда возвращал статус отсутствия емкости, тогда как я мог бы успешно запросить спотовый экземпляр через консоль AWS в другом AZ. Как правильно проверить доступность точечного экземпляра определенного типа экземпляра перед вызовом request_spot_instance?
Ответ №1:
Не существует общедоступного API для проверки доступности спотовых инстансов. Тем не менее, вы все равно можете добиться желаемого, выполнив следующие действия:
- Вместо этого используйте request_spot_fleet и настройте его для запуска одного инстанса.
- Будьте гибкими в выборе используемых типов инстансов, выбирайте как можно больше и включайте их в запрос. Чтобы помочь вам выбрать инстансы, проверьте Spot Instance advisor на предмет прерывания инстансов и экономии средств.
- По запросу спотового парка настройка
AllocationStrategy
наcapacityOptimized
это позволит автопарку распределять емкость для наиболее доступного спотового инстанса из вашего списка инстансов и снизить вероятность спотовых перебоев. - Не устанавливайте максимальную цену
SpotPrice
, будет использоваться цена спотового экземпляра по умолчанию. Модель ценообразования для спотовых инстансов изменилась и больше не основана на ставках, поэтому спотовые цены более стабильны и не колеблются.
Ответ №2:
Это может быть немного излишним для того, что вы ищете, но с помощью частей кода вы можете найти историю спотовых цен за последний час (это можно изменить). В нем будут указаны тип инстанса, AZ и дополнительная информация. Оттуда вы можете перейти от типа инстанса к по AZ. Если спотовый экземпляр не появляется, скажем, через 30 секунд, попробуйте следующий AZ.
И, по словам Ахмеда в его ответе, эта информация может быть использована в spot_fleet_request вместо перебора AZS. Если вы передадите неправильный AZ или подсеть в запросе спотового парка, вызов API dryrun может пройти, но реальный вызов все равно может завершиться ошибкой. Просто предупреждаю об этом, если вы используете параметр 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')