如何使用Boto检查EMR现货实例价格历史记录

时间:2019-09-17 14:42:45

标签: python-3.x amazon-web-services boto3 amazon-emr

我想使用现货定价以编程方式创建EMR集群,以节省一些成本。为此,我尝试使用boto3从AWS检索EMR竞价型实例定价,但是我从Boto3知道的唯一可用API是使用ec2客户端的decribe_spot_price_history调用-https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/ec2.html#EC2.Client.describe_spot_price_history

EC2的价格 not 表示EMR的价格,如此处所示-https://aws.amazon.com/emr/pricing/。该值几乎是EMR的两倍。

有没有一种方法可以查看类似于EC2的EMR的现货价格历史记录?我已经在线查阅https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/emr.html和AWS的其他几页文档,却一无所获。

这是我用来检查可用于对EMR实例出价的近似定价的代码段。

max_bid_price = 0.140
min_bid_price = max_bid_price
az_choice = ''
response = ec2.describe_spot_price_history(
    Filters=[{
        'Name': 'availability-zone',
        'Values': ['us-east-1a', 'us-east-1c', 'us-east-1d']
        },
        {
            'Name': 'product-description',
            'Values': ['Linux/UNIX (Amazon VPC)']
        }],
    InstanceTypes=['r5.2xlarge'],
    EndTime=datetime.now(),
    StartTime=datetime.now()
)
# TODO: Add more Subnets in other AZ's if picking from our existing 3 is an issue
# 'us-east-1b', 'us-east-1e', 'us-east-1f'
for spot_price_history in response['SpotPriceHistory']:
    print(spot_price_history)
    if float(spot_price_history['SpotPrice']) <= min_bid_price:
        min_bid_price = float(spot_price_history['SpotPrice'])
        az_choice = spot_price_history['AvailabilityZone']

上述操作失败,因为EC2竞价型实例的价格比Amazon为EMR按需实例的正常每小时价格收取的价格高。 (例如,按需使用该规模的集群每小时仅需$ 0.126,而按需使用EC2则为$ 0.504 /小时,按需实例价格为 $ 0.20 /小时)。

1 个答案:

答案 0 :(得分:1)

如评论中所述,没有所谓的EMR现货定价。现货定价适用于EC2实例。您可以查看this AWS Spot Advisor页面以找出中断率较低的实例类别,然后根据该类别进行选择。

自2017年以来,AWS更改了现货定价算法,“ 根据供需的长期趋势,价格会逐渐调整”,因此您可能无需查看以历史现货价格计算。有关更多详细信息,请参见here

如今,使用该实例的最后价格(+差价)您很可能会很好。可以使用以下代码片段实现这一点:

def get_bid_price(instancetype, aws_region):
    instance_types = [instancetype]
    start = datetime.now() - timedelta(days=1)

    ec2_client = boto3.client('ec2', aws_region)
    price_dict = ec2_client.describe_spot_price_history(StartTime=start,
                                                        InstanceTypes=instance_types,
                                                        ProductDescriptions=['Linux/UNIX (Amazon VPC)']
                                                        )
    if len(price_dict.get('SpotPriceHistory')) > 0:
        PriceHistory = namedtuple('PriceHistory', 'price timestamp')
        price_list = [PriceHistory(round(float(item.get('SpotPrice')), 3), item.get('Timestamp'))
                      for item in price_dict.get('SpotPriceHistory')]
        price_list.sort(key=lambda tup: tup.timestamp, reverse=True)

        # Maybe add 10 cents to the last spot price
        bid_price = round(float(price_list[0][0] + .01), 3)
        return bid_price
    else:
        raise ValueError('Invalid instance type: {} provided. '
                         'Please provide correct instance type.'.format(instancetype))