{"value":"随着客户的业务发展,终端用户的数据量以及大数据分析的需求也随之增加。此时,大数据分析的成本也随之上升。Amazon 提供多种工具协助客户做成本优化,其中使用 [EMR on EC2 Spot Instances](https://aws.amazon.com/cn/ec2/spot/use-case/emr/) 是常用且有效的方式,节省可高达90% 。客户在高峰期大量使用 Spot 时可能会出现申请失败的情况,EMR 服务在无法满足申请 Spot 需求时,会在60分钟内重试,如60分钟后仍无法成功,则会放弃重试,后期即便有充足的 Spot 也不会重新发起申请。因此对于此情况下需要节省成本依旧使用 Spot 实例的客户,只能通过多次手动调整集群大小来获取足够的 Spot 实例运行 EMR 任务,大大增加维护成本。\n\n以下方案是基于客户有大量每日需要运行4-8小时的临时集群且集群名称保持一致,Spot 使用量大因此频繁性产生申请失败,通过 EventBridge 及 Lambda 实现 EMR 自动调整集群大小。\n\n#### **服务介绍**\n\n##### **Amazon EventBridge**\n\nAmazon EventBridge 是一种无服务器事件总线,可使用从您的应用程序、集成式软件即服务 (SaaS) 应用程序和 Amazon 服务生成的事件,更轻松地大规模构建事件驱动型应用程序。EventBridge 提供从事件源到目标对象的实时数据流。借助 EventBridge,可实现 Amazon Services 之间基于规则的实时驱动,同时也支持定时任务式的交互驱动。\n\n\n\n##### **Amazon Lambda**\n\nAmazon Lambda 是一项高可用的 ServerLess 计算服务,可使用户无需预配置或管理服务器即可运行代码。用户可以运行 Lambda 以响应事件,在使用时只需负责自己写的代码(支持如 Node.js、Python、Java 等7种编程语言),通过代码来实现业务逻辑。基于 Lambda 用户可以实现在云上轻松实现服务间的自动化调用,提升云上服务效率。\n\n##### **Amazon DynamoDB**\n\nAmazon DynamoDB 是一种完全托管式、无服务器的 NoSQL 键值数据库,旨在运行任何规模的高性能应用程序。用户可以利用 DynamoDB 作为轻量化的键值数据库,用于存放自动化方案中需要引用的参数。同时,DynamoDB 与 云上服务有多个灵活接口及 SDK,易于服务间交互。\n\n#### **方案架构**\n\n\n\n基于客户的需求,此方案架构可以在新建EMR集群时触发 EventBridge 规则,从而触发 Lambda 记录 EMR 集群的 id, 名称, 创建时间于 DynamoDB。同时,通过 EventBridge Schedule 定期任务的功能,可触发 Lambda 检查集群是否当前运行 Spot 数量小于目标值,如是,则帮助自动执行调整集群大小动作。\n\n通过此方案,客户可以做到无人工干预地调整集群 Spot 数量大小到目标值,可有效地降低成本及提升运维效率。\n\n#### **方案配置**\n\n##### **创建 Dynamodb**\n\n1. 创建 emr-newcluster 表\n\n\n\n2. 创建 emr-resize-cluster 表\n\n\n\n更新需要进行 resize 的 cluster 名称:\n\n\n\n\n\n**创建 Lambda**\n\n1. 创建 emr_dw_new_cluster_event 函数\n\n```\ndef lambda_handler(event, context):\n #从event中读取新建EMR集群的cluster id,名称及创建时间\n cid=event['detail']['clusterId']\n name=event['detail']['name'] \n timestamp=event['time']\n #将对应信息写入DynamoDB\n dynamodb.put_item(TableName='emr-newcluster', \n Item={'clusterid':{'S':cid},'clustername':{'S':name},'timestamp':{'S':timestamp}})\n```\n\n注:对应 IAM Role 需要有 dynamodb table 'emr-newcluster' 的 putitem 权限。\n\n2. 创建 emr-dw-resize 函数\n\n ```\nresponse1=dynamodb.scan(TableName='emr-newcluster',FilterExpression=\"clustername= :n\",ExpressionAttributeValues={\":n\":{\"S\":cname}})\n \n cid=[]\n j=0\n \n while(j < response1['Count']):\n cid.append(response1['Items'][j]['clusterid']['S'])\n j=j+1\n \n for c in cid:\n response2=emr.describe_cluster(ClusterId=c)\n state=response2['Cluster']['Status']['State']\n if((state=='WAITING')):\n resizeinstancefleet(c)\n\n注:对应IAM Role需要有以下权限:\ndynamodb table 'emr-newcluster' 和'emr-resize-cluster'的scan权限。\nemr listinstancefleets,describe_cluster和modifyinstancefleet权限。\n```\n\n**创建 EventBridge**\n\n1. 配置 emr_dw_new_cluster_event Rule\na. Event pattern\n\n```\n{\n \"source\": [\"aws.emr\"],\n \"detail-type\": [\"EMR Cluster State Change\"],\n \"detail\": {\n \"state\": [\"STARTING\"]\n }\n}\n```\nb. Targets\n\n\n\n2. 配置 emr_dw_schedule Rule \na. Event schedule\n\n\n\nb. Targets\n\n\n\n#### **方案测试**\n\n##### **测试说明**\n\n由于测试环境中难以模拟 spot 申请失败,因此通过固定值的方式来模拟 resize:\n\n```\nif provisionedspot <= targetspot:\n response2 = emr.modify_instance_fleet(\n ClusterId=resizecid,\n InstanceFleet={\n 'InstanceFleetId': fleetid,\n 'TargetOnDemandCapacity': targetondemand,\n 'TargetSpotCapacity': 20\n }\n );\n```\n\n##### **新建 cluster name为emr-eventbase-resize 集群:**\n\n```\naws emr create-cluster --applications Name=Hadoop Name=Hive Name=Pig Name=Hue Name=Sqoop Name=Presto Name=Tez Name=Oozie Name=Spark Name=Ganglia --ebs-root-volume-size 10 --ec2-attributes '{\"KeyName\":\"EmrKeyPair\",\"InstanceProfile\":\"EMR_EC2_DefaultRole\",\"SubnetId\":\"subnet-091aff2145a19c21a\",\"EmrManagedSlaveSecurityGroup\":\"sg-052e14156908b936a\",\"EmrManagedMasterSecurityGroup\":\"sg-06de70e887339b988\"}' --service-role EMR_DefaultRole --enable-debugging --release-label emr-5.35.0 --log-uri 's3n://aws-logs-602709463925-us-west-2/elasticmapreduce/' --name 'emr-eventbase-resize' --configurations '[{\"Classification\":\"hive-site\",\"Properties\":{\"hive.metastore.client.factory.class\":\"com.amazonaws.glue.catalog.metastore.AWSGlueDataCatalogHiveClientFactory\"}}]' --scale-down-behavior TERMINATE_AT_TASK_COMPLETION --instance-fleets '[{\"InstanceFleetType\":\"TASK\",\"TargetOnDemandCapacity\":0,\"TargetSpotCapacity\":4,\"LaunchSpecifications\":{\"SpotSpecification\":{\"TimeoutDurationMinutes\":60,\"TimeoutAction\":\"TERMINATE_CLUSTER\"}},\"InstanceTypeConfigs\":[{\"WeightedCapacity\":4,\"EbsConfiguration\":{\"EbsBlockDeviceConfigs\":[{\"VolumeSpecification\":{\"SizeInGB\":32,\"VolumeType\":\"gp2\"},\"VolumesPerInstance\":2}]},\"BidPriceAsPercentageOfOnDemandPrice\":100,\"InstanceType\":\"m5.xlarge\"}],\"Name\":\"Task - 3\"},{\"InstanceFleetType\":\"MASTER\",\"TargetOnDemandCapacity\":1,\"TargetSpotCapacity\":0,\"LaunchSpecifications\":{},\"InstanceTypeConfigs\":[{\"WeightedCapacity\":1,\"EbsConfiguration\":{\"EbsBlockDeviceConfigs\":[{\"VolumeSpecification\":{\"SizeInGB\":32,\"VolumeType\":\"gp2\"},\"VolumesPerInstance\":2}]},\"BidPriceAsPercentageOfOnDemandPrice\":100,\"InstanceType\":\"m5.xlarge\"}],\"Name\":\"Master - 1\"},{\"InstanceFleetType\":\"CORE\",\"TargetOnDemandCapacity\":0,\"TargetSpotCapacity\":4,\"LaunchSpecifications\":{\"SpotSpecification\":{\"TimeoutDurationMinutes\":60,\"TimeoutAction\":\"TERMINATE_CLUSTER\"}},\"InstanceTypeConfigs\":[{\"WeightedCapacity\":4,\"EbsConfiguration\":{\"EbsBlockDeviceConfigs\":[{\"VolumeSpecification\":{\"SizeInGB\":32,\"VolumeType\":\"gp2\"},\"VolumesPerInstance\":2}]},\"BidPriceAsPercentageOfOnDemandPrice\":100,\"InstanceType\":\"m5.xlarge\"}],\"Name\":\"Core - 2\"}]' --region us-west-2\n```\n##### **查看 Dynamodb emr-newcluster 表,有对应的 item**\n\n\n\n##### **Lambda 可看到对应的 Invocation**\n\n\n\n##### **Cluster 进入 waiting 状态时,TASK Node 已 Resize 为20 Spot units:**\n\n\n\n对于生产中 Spot 申请失败后的 Resize,可在生产中进行验证。\n\n#### **总结**\n\n简而言之,Amazon 平台上服务多样且灵活。用户可以基于生产需求,通过无服务方式来实现灵活的配置以及自动化流程。Amazon Lambda 可以通过定制化的方式来满足不同业务场景的需求,也可以和其他相关服务集成进一步提升运维自动化的能力。基于此方案,客户可以做到无人工干预地调整集群 Spot 数量大小到目标值,可有效地降低成本及提升运维效率。\n\n#### **本篇作者**\n\n\n\n\n#### **梁绮莹**\n\n亚马逊云科技解决方案架构师,专注于数字原生企业的云架构设计和咨询,负责支持全球头部电商公司云项目。在云网络、应用交付、应用层安全、CDN、容器及微服务等领域有丰富的实战经验。\n\n\n\n#### **刘亚彬**\n\nAmazon 解决方案架构师。负责基于 Amazon 的云计算方案架构的咨询和设计,同时致力于 Amazon 云服务在国内的应用和推广。在加入 Amazon 前,拥有超过15年项目实施经验,曾就职于 Citrix,主要服务于国内外金融类客户。","render":"<p>随着客户的业务发展,终端用户的数据量以及大数据分析的需求也随之增加。此时,大数据分析的成本也随之上升。Amazon 提供多种工具协助客户做成本优化,其中使用 <a href=\"https://aws.amazon.com/cn/ec2/spot/use-case/emr/\" target=\"_blank\">EMR on EC2 Spot Instances</a> 是常用且有效的方式,节省可高达90% 。客户在高峰期大量使用 Spot 时可能会出现申请失败的情况,EMR 服务在无法满足申请 Spot 需求时,会在60分钟内重试,如60分钟后仍无法成功,则会放弃重试,后期即便有充足的 Spot 也不会重新发起申请。因此对于此情况下需要节省成本依旧使用 Spot 实例的客户,只能通过多次手动调整集群大小来获取足够的 Spot 实例运行 EMR 任务,大大增加维护成本。</p>\n<p>以下方案是基于客户有大量每日需要运行4-8小时的临时集群且集群名称保持一致,Spot 使用量大因此频繁性产生申请失败,通过 EventBridge 及 Lambda 实现 EMR 自动调整集群大小。</p>\n<h4><a id=\"_4\"></a><strong>服务介绍</strong></h4>\n<h5><a id=\"Amazon_EventBridge_6\"></a><strong>Amazon EventBridge</strong></h5>\n<p>Amazon EventBridge 是一种无服务器事件总线,可使用从您的应用程序、集成式软件即服务 (SaaS) 应用程序和 Amazon 服务生成的事件,更轻松地大规模构建事件驱动型应用程序。EventBridge 提供从事件源到目标对象的实时数据流。借助 EventBridge,可实现 Amazon Services 之间基于规则的实时驱动,同时也支持定时任务式的交互驱动。</p>\n<p><img src=\"https://dev-media.amazoncloud.cn/42b3a6b2a547402c921666a7c94a1100_image.png\" alt=\"image.png\" /></p>\n<h5><a id=\"Amazon_Lambda_12\"></a><strong>Amazon Lambda</strong></h5>\n<p>Amazon Lambda 是一项高可用的 ServerLess 计算服务,可使用户无需预配置或管理服务器即可运行代码。用户可以运行 Lambda 以响应事件,在使用时只需负责自己写的代码(支持如 Node.js、Python、Java 等7种编程语言),通过代码来实现业务逻辑。基于 Lambda 用户可以实现在云上轻松实现服务间的自动化调用,提升云上服务效率。</p>\n<h5><a id=\"Amazon_DynamoDB_16\"></a><strong>Amazon DynamoDB</strong></h5>\n<p>Amazon DynamoDB 是一种完全托管式、无服务器的 NoSQL 键值数据库,旨在运行任何规模的高性能应用程序。用户可以利用 DynamoDB 作为轻量化的键值数据库,用于存放自动化方案中需要引用的参数。同时,DynamoDB 与 云上服务有多个灵活接口及 SDK,易于服务间交互。</p>\n<h4><a id=\"_20\"></a><strong>方案架构</strong></h4>\n<p><img src=\"https://dev-media.amazoncloud.cn/5c87cc5170964d6a92abcf9e67511b9f_image.png\" alt=\"image.png\" /></p>\n<p>基于客户的需求,此方案架构可以在新建EMR集群时触发 EventBridge 规则,从而触发 Lambda 记录 EMR 集群的 id, 名称, 创建时间于 DynamoDB。同时,通过 EventBridge Schedule 定期任务的功能,可触发 Lambda 检查集群是否当前运行 Spot 数量小于目标值,如是,则帮助自动执行调整集群大小动作。</p>\n<p>通过此方案,客户可以做到无人工干预地调整集群 Spot 数量大小到目标值,可有效地降低成本及提升运维效率。</p>\n<h4><a id=\"_28\"></a><strong>方案配置</strong></h4>\n<h5><a id=\"_Dynamodb_30\"></a><strong>创建 Dynamodb</strong></h5>\n<ol>\n<li>创建 emr-newcluster 表</li>\n</ol>\n<p><img src=\"https://dev-media.amazoncloud.cn/fad8c10d20924f959a823e3793647379_image.png\" alt=\"image.png\" /></p>\n<ol start=\"2\">\n<li>创建 emr-resize-cluster 表</li>\n</ol>\n<p><img src=\"https://dev-media.amazoncloud.cn/cdc27044bfb640039deed6578a6190a0_image.png\" alt=\"image.png\" /></p>\n<p>更新需要进行 resize 的 cluster 名称:</p>\n<p><img src=\"https://dev-media.amazoncloud.cn/2c8a732ffbce4bed8b67417f82d05eba_image.png\" alt=\"image.png\" /></p>\n<p><img src=\"https://dev-media.amazoncloud.cn/77b88d8f63e0402b8d9e3e91c3ec3a8b_image.png\" alt=\"image.png\" /></p>\n<p><strong>创建 Lambda</strong></p>\n<ol>\n<li>创建 emr_dw_new_cluster_event 函数</li>\n</ol>\n<pre><code class=\"lang-\">def lambda_handler(event, context):\n #从event中读取新建EMR集群的cluster id,名称及创建时间\n cid=event['detail']['clusterId']\n name=event['detail']['name'] \n timestamp=event['time']\n #将对应信息写入DynamoDB\n dynamodb.put_item(TableName='emr-newcluster', \n Item={'clusterid':{'S':cid},'clustername':{'S':name},'timestamp':{'S':timestamp}})\n</code></pre>\n<p>注:对应 IAM Role 需要有 dynamodb table ‘emr-newcluster’ 的 putitem 权限。</p>\n<ol start=\"2\">\n<li>创建 emr-dw-resize 函数</li>\n</ol>\n<pre><code class=\"lang-\">response1=dynamodb.scan(TableName='emr-newcluster',FilterExpression="clustername= :n",ExpressionAttributeValues={":n":{"S":cname}})\n \n cid=[]\n j=0\n \n while(j < response1['Count']):\n cid.append(response1['Items'][j]['clusterid']['S'])\n j=j+1\n \n for c in cid:\n response2=emr.describe_cluster(ClusterId=c)\n state=response2['Cluster']['Status']['State']\n if((state=='WAITING')):\n resizeinstancefleet(c)\n\n注:对应IAM Role需要有以下权限:\ndynamodb table 'emr-newcluster' 和'emr-resize-cluster'的scan权限。\nemr listinstancefleets,describe_cluster和modifyinstancefleet权限。\n</code></pre>\n<p><strong>创建 EventBridge</strong></p>\n<ol>\n<li>配置 emr_dw_new_cluster_event Rule<br />\na. Event pattern</li>\n</ol>\n<pre><code class=\"lang-\">{\n "source": ["aws.emr"],\n "detail-type": ["EMR Cluster State Change"],\n "detail": {\n "state": ["STARTING"]\n }\n}\n</code></pre>\n<p>b. Targets</p>\n<p><img src=\"https://dev-media.amazoncloud.cn/04556485a5594667b3d07b795d6fb3bd_image.png\" alt=\"image.png\" /></p>\n<ol start=\"2\">\n<li>配置 emr_dw_schedule Rule<br />\na. Event schedule</li>\n</ol>\n<p><img src=\"https://dev-media.amazoncloud.cn/19a10d97dad34546827f12551abd8aa6_image.png\" alt=\"image.png\" /></p>\n<p>b. Targets</p>\n<p><img src=\"https://dev-media.amazoncloud.cn/543da44696514208a964b9d207351859_image.png\" alt=\"image.png\" /></p>\n<h4><a id=\"_113\"></a><strong>方案测试</strong></h4>\n<h5><a id=\"_115\"></a><strong>测试说明</strong></h5>\n<p>由于测试环境中难以模拟 spot 申请失败,因此通过固定值的方式来模拟 resize:</p>\n<pre><code class=\"lang-\">if provisionedspot <= targetspot:\n response2 = emr.modify_instance_fleet(\n ClusterId=resizecid,\n InstanceFleet={\n 'InstanceFleetId': fleetid,\n 'TargetOnDemandCapacity': targetondemand,\n 'TargetSpotCapacity': 20\n }\n );\n</code></pre>\n<h5><a id=\"_cluster_nameemreventbaseresize__131\"></a><strong>新建 cluster name为emr-eventbase-resize 集群:</strong></h5>\n<pre><code class=\"lang-\">aws emr create-cluster --applications Name=Hadoop Name=Hive Name=Pig Name=Hue Name=Sqoop Name=Presto Name=Tez Name=Oozie Name=Spark Name=Ganglia --ebs-root-volume-size 10 --ec2-attributes '{"KeyName":"EmrKeyPair","InstanceProfile":"EMR_EC2_DefaultRole","SubnetId":"subnet-091aff2145a19c21a","EmrManagedSlaveSecurityGroup":"sg-052e14156908b936a","EmrManagedMasterSecurityGroup":"sg-06de70e887339b988"}' --service-role EMR_DefaultRole --enable-debugging --release-label emr-5.35.0 --log-uri 's3n://aws-logs-602709463925-us-west-2/elasticmapreduce/' --name 'emr-eventbase-resize' --configurations '[{"Classification":"hive-site","Properties":{"hive.metastore.client.factory.class":"com.amazonaws.glue.catalog.metastore.AWSGlueDataCatalogHiveClientFactory"}}]' --scale-down-behavior TERMINATE_AT_TASK_COMPLETION --instance-fleets '[{"InstanceFleetType":"TASK","TargetOnDemandCapacity":0,"TargetSpotCapacity":4,"LaunchSpecifications":{"SpotSpecification":{"TimeoutDurationMinutes":60,"TimeoutAction":"TERMINATE_CLUSTER"}},"InstanceTypeConfigs":[{"WeightedCapacity":4,"EbsConfiguration":{"EbsBlockDeviceConfigs":[{"VolumeSpecification":{"SizeInGB":32,"VolumeType":"gp2"},"VolumesPerInstance":2}]},"BidPriceAsPercentageOfOnDemandPrice":100,"InstanceType":"m5.xlarge"}],"Name":"Task - 3"},{"InstanceFleetType":"MASTER","TargetOnDemandCapacity":1,"TargetSpotCapacity":0,"LaunchSpecifications":{},"InstanceTypeConfigs":[{"WeightedCapacity":1,"EbsConfiguration":{"EbsBlockDeviceConfigs":[{"VolumeSpecification":{"SizeInGB":32,"VolumeType":"gp2"},"VolumesPerInstance":2}]},"BidPriceAsPercentageOfOnDemandPrice":100,"InstanceType":"m5.xlarge"}],"Name":"Master - 1"},{"InstanceFleetType":"CORE","TargetOnDemandCapacity":0,"TargetSpotCapacity":4,"LaunchSpecifications":{"SpotSpecification":{"TimeoutDurationMinutes":60,"TimeoutAction":"TERMINATE_CLUSTER"}},"InstanceTypeConfigs":[{"WeightedCapacity":4,"EbsConfiguration":{"EbsBlockDeviceConfigs":[{"VolumeSpecification":{"SizeInGB":32,"VolumeType":"gp2"},"VolumesPerInstance":2}]},"BidPriceAsPercentageOfOnDemandPrice":100,"InstanceType":"m5.xlarge"}],"Name":"Core - 2"}]' --region us-west-2\n</code></pre>\n<h5><a id=\"_Dynamodb_emrnewcluster__item_136\"></a><strong>查看 Dynamodb emr-newcluster 表,有对应的 item</strong></h5>\n<p><img src=\"https://dev-media.amazoncloud.cn/e8252c09046b4a9dbc4464759fce295e_image.png\" alt=\"image.png\" /></p>\n<h5><a id=\"Lambda__Invocation_140\"></a><strong>Lambda 可看到对应的 Invocation</strong></h5>\n<p><img src=\"https://dev-media.amazoncloud.cn/6cae054f4f2047ea917cf2e3ff26daee_image.png\" alt=\"image.png\" /></p>\n<h5><a id=\"Cluster__waiting_TASK_Node__Resize_20_Spot_units_144\"></a><strong>Cluster 进入 waiting 状态时,TASK Node 已 Resize 为20 Spot units:</strong></h5>\n<p><img src=\"https://dev-media.amazoncloud.cn/cde72d8c95824f66b5ee239894365b6b_image.png\" alt=\"image.png\" /></p>\n<p>对于生产中 Spot 申请失败后的 Resize,可在生产中进行验证。</p>\n<h4><a id=\"_150\"></a><strong>总结</strong></h4>\n<p>简而言之,Amazon 平台上服务多样且灵活。用户可以基于生产需求,通过无服务方式来实现灵活的配置以及自动化流程。Amazon Lambda 可以通过定制化的方式来满足不同业务场景的需求,也可以和其他相关服务集成进一步提升运维自动化的能力。基于此方案,客户可以做到无人工干预地调整集群 Spot 数量大小到目标值,可有效地降低成本及提升运维效率。</p>\n<h4><a id=\"_154\"></a><strong>本篇作者</strong></h4>\n<p><img src=\"https://dev-media.amazoncloud.cn/aef0df70c5eb4352acca749fa0e65c4b_image.png\" alt=\"image.png\" /></p>\n<h4><a id=\"_159\"></a><strong>梁绮莹</strong></h4>\n<p>亚马逊云科技解决方案架构师,专注于数字原生企业的云架构设计和咨询,负责支持全球头部电商公司云项目。在云网络、应用交付、应用层安全、CDN、容器及微服务等领域有丰富的实战经验。</p>\n<p><img src=\"https://dev-media.amazoncloud.cn/c074ee026f024b2ca01f45be766b1c4b_image.png\" alt=\"image.png\" /></p>\n<h4><a id=\"_165\"></a><strong>刘亚彬</strong></h4>\n<p>Amazon 解决方案架构师。负责基于 Amazon 的云计算方案架构的咨询和设计,同时致力于 Amazon 云服务在国内的应用和推广。在加入 Amazon 前,拥有超过15年项目实施经验,曾就职于 Citrix,主要服务于国内外金融类客户。</p>\n"}