亚马逊AWS官方博客

借助Serverless服务实现EMR Instance Fleets集群自定义弹性伸缩

随着客户的业务发展,终端用户的数据量以及大数据分析的需求也随之增加。此时,大数据分析的成本也随之上升。AWS 提供多种工具协助客户做成本优化,其中使用EMR on EC2 Spot Instances是常用且有效的方式,节省可高达90% 。

Amazon EMR 实例组支持实例组(Instance Group)及实例集(Instance Fleets)两种配置,对比可参考以下表格:

Instance Group Instance Fleets
数量限制 最多 50 个实例组:一个主实例组、一个核心实例组和最多 48 个可选任务实例组 在 AWS Management Console上最多可为每个实例集指定 5 个 Amazon EC2 实例类型(使用 AWS CLI 或 Amazon EMR API 以及 实例集的分配策略 创建集群时,最多可为每个实例集指定 30 个类型)
手动调整 集群启动后手动调整核心和任务实例组的实例数量,也新增任务实例组,使用新的实例类型。 集群启动后不能更改实例类型,对于现有的核心和任务实例队列,可更改按需实例和竞价型实例的目标容量
扩展集群 托管扩展和自定义策略 托管扩展
多个主节点 支持 不支持

更多内容可参考集群配置指南及最佳实践

Instance Fleets 相比于Instance Group,不需要为 Amazon EMR 集群指定 Amazon EC2 可用区,并为 Amazon EMR 实例组指定 Amazon EC2 实例类型,只需要提供可用区和实例的列表,Amazon EMR 就会根据费用和可用性自动选择最优组合。客户在EMR Instance Group转为使用Instance Fleets后,大大增加了Spot的灵活度和成本优化。然而,Instance Fleets当前只支持托管伸缩规则,暂未支持如Instance Group的自定义伸缩规则。当客户使用EMR托管扩展时,集群的扩展决策指标较多且无法基于业务特性自定义。

对于客户有大量EMR集群,基于业务特性不同时伸缩阈值不同。尤其对于集群任务存在骤升骤降,且业务特征规律重复明显的情况,客户希望可自定义伸缩规则实现最大化的成本优化。

以下方案是EMR Instance Fleets通过EventBridge,Lambda,DynamoDB和CloudWatch实现EMR Instance Fleets自定义弹性伸缩。

服务介绍

Amazon EventBridge

Amazon EventBridge 是一种无服务器事件总线,可使用从您的应用程序、集成式软件即服务 (SaaS) 应用程序和 AWS 服务生成的事件,更轻松地大规模构建事件驱动型应用程序。EventBridge 提供从事件源到目标对象的实时数据流。借助EventBridge,可实现AWS Services之间基于规则的实时驱动,同时也支持定时任务式的交互驱动。

AWS Lambda

AWS Lambda 是一项高可用的ServerLess计算服务,可使用户无需预配置或管理服务器即可运行代码。用户可以运行Lambda以响应事件,在使用时只需负责自己写的代码(支持如Node.js、Python、Java等7种编程语言),通过代码来实现业务逻辑。基于Lambda 用户可以实现在云上轻松实现服务间的自动化调用,提升云上服务效率。

Amazon DynamoDB

Amazon DynamoDB 是一种完全托管式、无服务器的 NoSQL 键值数据库,旨在运行任何规模的高性能应用程序。用户可以利用DynamoDB 作为轻量化的键值数据库,用于存放自动化方案中需要引用的参数。同时,DynamoDB与AWS 云上服务有多个灵活接口及SDK,易于服务间交互。

Amazon CloudWatch

Amazon CloudWatch 是一种专门为 DevOps 工程师、开发人员、站点可靠性工程师 (SRE)、IT 经理和产品拥有者设计的监控和可观测性服务。CloudWatch 为您提供相关数据和切实洞察,以监控应用程序、响应系统范围的性能变化并优化资源利用率。CloudWatch 以日志、指标和事件的形式收集监控和运营数据。您可以统一查看运行状况,获得在 AWS 和本地运行的 AWS 资源、应用程序和服务的完全可见性。

方案架构

基于客户的需求,此方案架构可以基于客户自定义间隔定期触发EventBridge规则,读取DynamoDB中需要进行弹性伸缩集群的名称及参数,且比对CloudWatch中EMR集群的YARNMemoryAvailablePercentage,用于伸缩TASK节点组;比对CloudWatch中EMR集群的HDFSUtilization,用于伸缩CORE节点组,同时伸缩前检查DynamoDB中EMR集群上次伸缩的时间,冷却时间内不进行伸缩,最后基于自定义阈值进行弹性伸缩。

通过此方案,客户针对EMR Instance Fleets集群基于自定义阈值进行弹性伸缩,可最大化的优化成本及精细化管理。

方案配置

创建Dynamodb

  1. 创建emr_scaling 表,输入以下信息,点击Create:

根据以下定义,创建对应的Item:

Attribute name Value
clustername 集群名称
coremaxunit CORE节点组最大Unit
coreminunit CORE节点组最小Unit
corescaleinspotunit CORE节点组缩容的单位Unit
corescaleoutspotunit CORE节点组扩容的单位Unit
highhdfsutilization HDFSUtilization大于的阈值
lowhdfsutilization HDFSUtilization小于的阈值
taskmaxunit TASK节点组最大Unit
taskminunit TASK节点组最小Unit
taskscaleinspotunit TASK节点组缩容的单位Unit
taskscaleoutspotunit TASK节点组扩容的单位Unit
highyarnavailmemory YARNMemoryAvailablePercentage大于的阈值
lowyarnavailmemory YARNMemoryAvailablePercentage小于的阈值
interval 通过CloudWatch读取指标的间隔
scaleincooldownperiod 缩容的冷却时间
scaleoutcooldownperiod 扩容的冷却时间
  1. 创建emr-instancefleet-scaling表,输入以下信息,点击Create:

创建Lambda

  1. 配置instancefleeting_auto_scaling 函数

  1. 导入以下代码:

https://github.com/christofile/aws-emr-instancefleet-custom-scaling/blob/main/aws_emr_instancefleet_custom_scaling.py

  1. 配置 Lambda 函数Permission具有以下权限

创建并attach以下Policy:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "ScalingPolicy",
            "Effect": "Allow",
            "Action": [
                "dynamodb:PutItem",
                "dynamodb:Scan",
                "dynamodb:UpdateItem"
            ],
            "Resource": [
                "arn:aws:dynamodb:us-west-2:<AccountID>:table/emr-instancefleet-scaling",
                "arn:aws:dynamodb:us-west-2: :<AccountID>:table/emr_scaling"
            ]
        },
        {
            "Sid": "VisualEditor1",
            "Effect": "Allow",
            "Action": [
                "elasticmapreduce:ListInstanceFleets",
                "elasticmapreduce:ListClusters",
                "cloudwatch:GetMetricStatistics",
                "elasticmapreduce:DescribeCluster",
                "elasticmapreduce:ModifyInstanceFleet"
            ],
            "Resource": "*"
        }
    ]
}

创建EventBridge

  1. 配置emr_instancefleet_schedule Rule

a.Event schedule

可根据业务需求定义定时任务的触发时间,建议和CloudWatch读取指标间隔(Interval)保持一致。

b.Targets

Target关联上面配置的Lambda。

配置完成后,可在Lambda侧看到以下关联关系

方案测试

基于以上方案,配置完成后,按照以下步骤测试:

  1. 开启集群的托管伸缩规则
  2. 调度平台调度27个测试任务
  3. 记录执行的Job Flow ID以及执行时间
  4. 关闭集群的托管伸缩规则
  5. 在DynamoDB emr_scaling添加需要测试的集群及对应的参数,以下是配置示例:

  1. 调度平台调度27个测试任务
  2. 记录执行的Job Flow ID以及执行时间。

测试结果:

测试1: 托管策略 执行时间:11min 花费 $26.5

测试2: 自定义策略 执行时间:13min 花费 $8.43

成本节省约68.2%。

总结

简而言之,AWS 平台上服务多样且灵活。用户可以基于生产需求,通过无服务方式来实现自定义配置,精细化管理以及自动化流程。AWS Lambda可以通过定制化的方式来满足不同业务场景的需求,也可以和其他相关服务集成进一步提升运维自动化的能力。客户针对EMR Instance Fleets集群基于自定义阈值进行弹性伸缩,可最大化的优化成本及精细化管理。

本篇作者

梁绮莹

亚马逊云科技解决方案架构师,专注于数字原生企业的云架构设计和咨询,负责支持全球头部电商公司云项目。在云网络、应用交付、应用层安全、CDN、容器及微服务等领域有丰富的实战经验。