亚马逊AWS官方博客

Amazon EC2 Spot 实例在AWS EMR 集群中的成本优化应用实践

一. 前言

Amazon EMR 的定价是根据所部署的 Amazon EC2 实例的实例类型和数量及您启动集群的区域。业务数据的处理和分析通常需要比较大规模的EMR集群和更多的节点数来处理,本文介绍如何通过合理配置和使用Spot 实例类型来大幅降低EMR集群成本,特别对于跑特定任务的瞬时集群来说,Spot 实例的使用是特定的应用场景,如何选型和配置更是成本优化的关键之处。

二. Spot实例

Amazon EMR集群使用EC2来构建节点,而EC2 Spot 实例是一种使用备用 EC2 容量的实例,它以低于按需价格提供。竞价型实例允许您以极低的折扣请求未使用的 EC2 实例,最高可节省按需实例价格的 90%(如下图以R5D为例),因此会显著降低用户的 Amazon EMR集群的整体成本。竞价型实例的每小时价格称为 Spot 价格,每个可用区中的每种实例类型的 Spot 价格是由 Amazon EC2 设置的,并根据竞价型实例的长期供求趋势逐步调整。只要容量可用,并且请求的每小时最高价超过 Spot 价格,竞价型实例就会运行。

各种应用程序特定场景的节点类型购买选项和配置的快速参考

三. Amazon EMR

Amazon EMR(以前称为 Amazon Elastic MapReduce)是一个托管集群平台,可简化在AWS上运行大数据框架(如 Apache Hadoop 和 Apache Spark)的过程,以处理和分析海量数据。使用这些框架和相关的开源项目,用户可以处理用于分析目的的数据和业务情报相关的工作负载。集群的节点类型有:

主节点:该节点管理集群并通过运行软件组件来协调节点间分配数据和任务的过程以便进行处理。

核心节点:该节点具有运行任务并在集群上的 Hadoop 分布式文件系统 (HDFS) 中存储数据的软件组件。

任务节点:该节点具有仅运行任务但不在 HDFS 中存储数据的软件组件。任务节点是可选的。

如上所述,SPOT实例通常运行于EMR集群的任务节点,集群本身有计划YARN任务的功能,应用任务的主进程仅运行在核心节点,而任务节点的竞价实例的回收并不会导至任务失败。此外,特别当您运行的是暂时性的(transient)集群,如果降低成本比完成时间更重要并可接受损失部分工作,那么以竞价型实例运行整个集群来可以享受较大的成本节约。而对于数仓型的集群,用户以按需实例的方式启动主实例组和核心实例组来处理正常容量,并以竞价型实例的方式启动任务实例组来处理业务的峰值负载需求,以此来优化集群运行的成本。

a)     集群节点的选型:

节点选型的工具:

  1. amazon-ec2-instance-selector

在创建集群时,要尽可能地多选可用的实例类型作为实例集的成员,您可以为每个实例集队列指定最多 5 个 Amazon EC2 实例类型以便 Amazon EMR 在实现目标时使用,或者使用 AWS CLI 或 Amazon EMR API 且以按需实例和 Spot 实例的分配策略来创建集群时,可以为每个实例集队列指定最多 30 个 Amazon EC2 实例类型。如下是选择Spot实例类型的两种方法:

https://github.com/aws/amazon-ec2-instance-selector    (如下为示例)

% ec2-instance-selector --memory-min 64 GiB --memory-max 512 GiB --vcpus-min 8 --vcpus-max 24 --region us-west-2 --max-results 30 -o table

  1. Spot Instance Advisor

用此工具选实例类例时,您应该权衡应用程序对中断的容错能力和您的成本节省目标。中断率越低,Spot 实例的运行时间可能就越长。

https://aws.amazon.com/ec2/spot/instance-advisor/      (如下为示例)

TIPS:

在使用 Advanced Options (高级选项) 创建集群的情况下,将鼠标悬停在 Spot 购买选项旁边的信息工具提示上方,即可在控制台中看到实时 Spot 价格。这将显示所选区域中每个可用区的价格。最低价格位于绿色行中。

b)     实例集的分配策略

在创建集群时,可以应用实例集分配策略选项,以此来加快集群的配置且更准确地进行竞价型实例分配,同时也减少了竞价型实例的中断。如下是针对SPOT实例的容量优化策略:

Spot 实例使用容量优化的策略,该策略从竞价型实例池启动竞价型实例,这些实例池可为要启动的实例数量提供最佳容量。

当您用控制台去创建集群时,需要注意激活分配策略选项:

而在使用命令行去创建集群时,有如下CLI export的参数显示:

--instance-fleets '[{"InstanceFleetType":"TASK","TargetOnDemandCapacity":0,"TargetSpotCapacity":xx,"LaunchSpecifications":{"OnDemandSpecification":{"AllocationStrategy":"LOWEST_PRICE"},"SpotSpecification":{"TimeoutDurationMinutes":60,"AllocationStrategy":"CAPACITY_OPTIMIZED"

而集群创建完成后,会有如下显示:

以上确认您的实例集分配策略已经生效。

c)     使用 EMR 托管扩展优化SPOT实例集

可以启用 EMR 托管扩展,对EMR集群的实例集进行自动增加和减少实例或单元的数量,特别是对于SPOT实例组成实例集,EMR 会持续评估集群指标,以便做出扩展决策,从而优化集群的成本和速度。

您需要为托管扩展配置以下参数。如下参数限制仅适用于核心节点和任务节点。

Minimum (最小)MinimumCapacityUnits)– 集群中允许的 EC2 容量的下限。其衡量方式为通过虚拟中央处理单位(vCPU)核心或实例组中的实例进行衡量。其衡量方式为通过实例集单位进行衡量。

Maximum (最大)MaximumCapacityUnits)– 集群中允许的 EC2 容量的上限。其衡量方式为通过虚拟中央处理单位(vCPU)核心或实例组中的实例进行衡量。其衡量方式为通过实例集单位进行衡量。

On-Demand limit (按需限制)MaximumOnDemandCapacityUnits)(可选)– 集群中按需市场类型允许的 EC2 容量的上限。如果未指定此参数,则默认为 MaximumCapacityUnits 的值。

Maximum core nodes (最大核心节点)MaximumCoreCapacityUnits)(可选)– 集群中核心节点类型允许的 EC2 容量的上限。如果未指定此参数,则默认为 MaximumCapacityUnits 的值。

以下为通过命令行方式修改EMR托管扩展的设置的示例(可以适时调整您的扩展需求):

aws emr put-managed-scaling-policy --cluster-id j-XXXXXXXXX  --managed-scaling-policy ComputeLimits='{MinimumCapacityUnits=32,MaximumCapacityUnits=130,MaximumOnDemandCapacityUnits=0,MaximumCoreCapacityUnits=4,UnitType= InstanceFleetUnits}'

d)     Spot 蓝图

Spot蓝图通过简单地允许您以vCPU和内存表述计算容量需求,而对未知的工作负载来更加容易地配置EC2实例类型。同时它的向导会自动将这些需求扩展到您正在操作的AWS区域中。与传统向导不同,Spot 蓝图在每个步骤中以代码的形式实时生成自定义基础结构,因此您可以轻松了解配置的详细信息,这些步骤旨在收集工作负载需求,同时解释和配置Spot最佳实践。Spot蓝图还采用高级Spot最佳实践,比如可用性区域灵活性、容量优化分配策略等,并将其应用于您的工作负载计算需求。

在控制台如下菜单项中,我们选择EMR蓝图,然后单击“配置蓝图”来进行模板生成:

在按照向导完成配置后,可以点“在CloudFormation中部署“直接进行所在区域的部署:

下面是我们模板的CloudFormation代码样本。您可以看到EMR集群的创建、正在安装的应用程序(Spark、Hadoop和Ganglia)、实例类型和可用区的列表及已经启用的容量优化分配策略。

emrSparkInstanceFleetCluster:
    DependsOn:
      - vpc
      - publicRoute
      - publicSubnet1RouteTableAssociation
      - publicSubnet2RouteTableAssociation
      - publicSubnet3RouteTableAssociation
      - publicSubnet4RouteTableAssociation
      - publicSubnet5RouteTableAssociation
      - publicSubnet6RouteTableAssociation
    Properties:
      Applications:
        - Name: Spark
        - Name: Hadoop
        - Name: Ganglia
      Instances:
        CoreInstanceFleet:
          InstanceTypeConfigs:
            - InstanceType: m4.large
              WeightedCapacity: 2
            - InstanceType: c4.large
              WeightedCapacity: 2
            - InstanceType: r3.xlarge
              WeightedCapacity: 4
            - InstanceType: r4.xlarge
              WeightedCapacity: 4
            - InstanceType: r5.xlarge
              WeightedCapacity: 4
          Name:
            Ref: AWS::StackName
          TargetOnDemandCapacity: "2"
          LaunchSpecifications:
            OnDemandSpecification:
              AllocationStrategy: lowest-price
        Ec2SubnetIds:
          - Ref: publicSubnet1
          - Ref: publicSubnet2
          - Ref: publicSubnet3
          - Ref: publicSubnet4
          - Ref: publicSubnet5
          - Ref: publicSubnet6
        MasterInstanceFleet:
          InstanceTypeConfigs:
            - InstanceType: m4.large
            - InstanceType: c4.large
            - InstanceType: r3.xlarge
            - InstanceType: r4.xlarge
            - InstanceType: r5.xlarge
          Name:
            Ref: AWS::StackName
          TargetOnDemandCapacity: "1"
      JobFlowRole:
        Ref: spotBlueprintsEmrEc2InstanceProfile
      Name:
        Ref: AWS::StackName
      ReleaseLabel: emr-5.30.1
      ServiceRole: EMR_DefaultRole
      Tags:
        - Key: Name
          Value:
            Ref: AWS::StackName
      VisibleToAllUsers: true
    Type: AWS::EMR::Cluster
  emrSparkInstanceTaskFleet:
    DependsOn:
      - emrSparkInstanceFleetCluster
    Properties:
      ClusterId:
        Ref: emrSparkInstanceFleetCluster
      InstanceFleetType: TASK
      InstanceTypeConfigs:
        - InstanceType: m4.large
          WeightedCapacity: 2
        - InstanceType: c4.large
          WeightedCapacity: 2
        - InstanceType: r3.xlarge
          WeightedCapacity: 4
        - InstanceType: r4.xlarge
          WeightedCapacity: 4
        - InstanceType: r5.xlarge
          WeightedCapacity: 4
        - InstanceType: m3.xlarge
          WeightedCapacity: 4
        - InstanceType: m4.xlarge
          WeightedCapacity: 4
        - InstanceType: m5.xlarge
          WeightedCapacity: 4
        - InstanceType: c3.xlarge
          WeightedCapacity: 4
        - InstanceType: c4.xlarge
          WeightedCapacity: 4
        - InstanceType: c5.xlarge
          WeightedCapacity: 4
        - InstanceType: r3.2xlarge
          WeightedCapacity: 8
        - InstanceType: r4.2xlarge
          WeightedCapacity: 8
        - InstanceType: r5.2xlarge
          WeightedCapacity: 8
        - InstanceType: m3.2xlarge
          WeightedCapacity: 8
      LaunchSpecifications:
        SpotSpecification:
          TimeoutAction: TERMINATE_CLUSTER
          TimeoutDurationMinutes: 60
          AllocationStrategy: capacity-optimized
      Name: TaskFleet
      TargetSpotCapacity: "2"
    Type: AWS::EMR::InstanceFleetConfig

通过生成的模板,可以按照需求在相应的VPC部署您的集群:

当集群的工作已经完成后,我们可以通过删除CloudFormation堆栈以删除创建的AWS资源。

Spot蓝图旨在为每个特定工作负载快速解释和生成带有Spot最佳实践的模板。模板支持CloudFormation或Terraform格式,同时可以下载下来进行优化再定制。无论您是第一次使用Spot的用户,还是经验丰富的使用者,Spot蓝图都能帮助您学习到如何利用Spot实例进行成本和规模优化,并将您的Spot使用扩展到新的体系结构中。

总结

在前述的内容中,已经详细叙述如何通过各种方法最优化采用竞价实例,比如加入更多的竞价实例类型、容量优化分配策略、EMR 托管扩展设定和SPOT蓝图,来有效并合理地配置EMR集群以实现优化成本。目前有AWS的大数据用户具有企业级服务支持,相应的技术客户经理通过类似的方法,并协助监控和确认SPOT资源池的波动趋势,成功地帮助用户优化成本在30%左右。

更多内容

更多有关EMR集群及使用Spot实例的相关内容,请大家参考AWS EMR 官方文档和FAQ:

https://docs.aws.amazon.com/zh_cn/emr/latest/ManagementGuide/emr-plan-instances-guidelines.html#emr-dev-master-instance-group-spot

https://aws.github.io/aws-emr-best-practices/reliability/best_practices/#bp-26-use-instance-fleet-with-allocation-strategy

https://aws.amazon.com/blogs/compute/introducing-spot-blueprints-a-template-generator-for-frameworks-like-kubernetes-and-apache-spark/

https://docs.aws.amazon.com/zh_cn/emr/latest/ManagementGuide/emr-instance-fleet.html

本篇作者

Harris Han

AWS技术客户经理,负责企业级客户的架构和成本的优化、技术支持与服务等工作,同时致力于亚马逊云科技在国内和全球的应用及企业级服务的推广,并在产品部署、网络安全,桌面云,服务器虚拟化,企业运维管理等领域拥有丰富的设计与实践经验。