View a markdown version of this page

Menanggapi peristiwa kapasitas instans cluster Amazon EMR yang tidak mencukupi - Amazon EMR

Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.

Menanggapi peristiwa kapasitas instans cluster Amazon EMR yang tidak mencukupi

Gambaran umum

Cluster Amazon EMR mengembalikan kode peristiwa EC2 provisioning - Insufficient Instance Capacity ketika Zona Ketersediaan yang dipilih tidak memiliki kapasitas yang cukup untuk memenuhi permintaan mulai atau perubahan ukuran cluster Anda. Peristiwa akan dipancarkan secara berkala dengan grup instans dan armada instans jika Amazon EMR berulang kali menemukan pengecualian kapasitas yang tidak mencukupi dan tidak dapat memenuhi permintaan penyediaan untuk memulai cluster atau operasi pengubahan ukuran cluster.

Halaman ini menjelaskan cara terbaik untuk merespons jenis peristiwa ini ketika terjadi pada cluster EMR Anda.

Respon yang disarankan untuk acara kapasitas yang tidak mencukupi

Kami menyarankan Anda menanggapi peristiwa kapasitas yang tidak memadai dengan salah satu cara berikut:

  • Tunggu kapasitas untuk pulih. Kapasitas sering bergeser, sehingga pengecualian kapasitas yang tidak mencukupi dapat pulih dengan sendirinya. Cluster Anda akan mulai atau selesai mengubah ukuran segera setelah kapasitas Amazon EC2 tersedia.

  • Atau, Anda dapat menghentikan cluster, memodifikasi konfigurasi jenis instans, dan membuat cluster baru dengan permintaan konfigurasi cluster yang diperbarui. Untuk informasi selengkapnya, lihat Fleksibilitas Zona Ketersediaan untuk cluster Amazon EMR.

Anda juga dapat mengatur aturan atau respons otomatis terhadap peristiwa kapasitas yang tidak mencukupi, seperti yang dijelaskan di bagian selanjutnya.

Pemulihan otomatis dari peristiwa kapasitas yang tidak mencukupi

Anda dapat membangun otomatisasi sebagai respons terhadap peristiwa Amazon EMR seperti yang memiliki kode EC2 provisioning - Insufficient Instance Capacity acara. Misalnya, AWS Lambda fungsi berikut mengakhiri cluster EMR dengan grup instance yang menggunakan On-Demand instance, dan kemudian membuat cluster EMR baru dengan grup instance yang berisi jenis instans berbeda dari permintaan asli.

Kondisi berikut memicu proses otomatis terjadi:

  • Peristiwa kapasitas yang tidak mencukupi telah dipancarkan untuk node primer atau inti selama lebih dari 20 menit.

  • Cluster tidak dalam keadaan READY atau WA ITING. Untuk informasi selengkapnya tentang status cluster EMR, lihatMemahami siklus hidup klaster.

catatan

Saat Anda membangun proses otomatis untuk pengecualian kapasitas yang tidak mencukupi, Anda harus mempertimbangkan bahwa peristiwa kapasitas tidak mencukupi dapat dipulihkan. Kapasitas sering bergeser dan cluster Anda akan melanjutkan perubahan ukuran atau mulai beroperasi segera setelah kapasitas Amazon EC2 tersedia.

contoh berfungsi untuk menanggapi peristiwa kapasitas yang tidak mencukupi
// Lambda code with Python 3.10 and handler is lambda_function.lambda_handler // Note: related IAM role requires permission to use Amazon EMR import json import boto3 import datetime from datetime import timezone INSUFFICIENT_CAPACITY_EXCEPTION_DETAIL_TYPE = "EMR Instance Group Provisioning" INSUFFICIENT_CAPACITY_EXCEPTION_EVENT_CODE = ( "EC2 provisioning - Insufficient Instance Capacity" ) ALLOWED_INSTANCE_TYPES_TO_USE = [ "m5.xlarge", "c5.xlarge", "m5.4xlarge", "m5.2xlarge", "t3.xlarge", ] CLUSTER_START_ACCEPTABLE_STATES = ["WAITING", "RUNNING"] CLUSTER_START_SLA = 20 CLIENT = boto3.client("emr", region_name="us-east-1") # checks if the incoming event is 'EMR Instance Fleet Provisioning' with eventCode 'EC2 provisioning - Insufficient Instance Capacity' def is_insufficient_capacity_event(event): if not event["detail"]: return False else: return ( event["detail-type"] == INSUFFICIENT_CAPACITY_EXCEPTION_DETAIL_TYPE and event["detail"]["eventCode"] == INSUFFICIENT_CAPACITY_EXCEPTION_EVENT_CODE ) # checks if the cluster is eligible for termination def is_cluster_eligible_for_termination(event, describeClusterResponse): # instanceGroupType could be CORE, MASTER OR TASK instanceGroupType = event["detail"]["instanceGroupType"] clusterCreationTime = describeClusterResponse["Cluster"]["Status"]["Timeline"][ "CreationDateTime" ] clusterState = describeClusterResponse["Cluster"]["Status"]["State"] now = datetime.datetime.now() now = now.replace(tzinfo=timezone.utc) isClusterStartSlaBreached = clusterCreationTime < now - datetime.timedelta( minutes=CLUSTER_START_SLA ) # Check if instance group receiving Insufficient capacity exception is CORE or PRIMARY (MASTER), # and it's been more than 20 minutes since cluster was created but the cluster state and the cluster state is not updated to RUNNING or WAITING if ( (instanceGroupType == "CORE" or instanceGroupType == "MASTER") and isClusterStartSlaBreached and clusterState not in CLUSTER_START_ACCEPTABLE_STATES ): return True else: return False # Choose item from the list except the exempt value def choice_excluding(exempt): for i in ALLOWED_INSTANCE_TYPES_TO_USE: if i != exempt: return i # Create a new cluster by choosing different InstanceType. def create_cluster(event): # instanceGroupType cloud be CORE, MASTER OR TASK instanceGroupType = event["detail"]["instanceGroupType"] # Following two lines assumes that the customer that created the cluster already knows which instance types they use in original request instanceTypesFromOriginalRequestMaster = "m5.xlarge" instanceTypesFromOriginalRequestCore = "m5.xlarge" # Select new instance types to include in the new createCluster request instanceTypeForMaster = ( instanceTypesFromOriginalRequestMaster if instanceGroupType != "MASTER" else choice_excluding(instanceTypesFromOriginalRequestMaster) ) instanceTypeForCore = ( instanceTypesFromOriginalRequestCore if instanceGroupType != "CORE" else choice_excluding(instanceTypesFromOriginalRequestCore) ) print("Starting to create cluster...") instances = { "InstanceGroups": [ { "InstanceRole": "MASTER", "InstanceCount": 1, "InstanceType": instanceTypeForMaster, "Market": "ON_DEMAND", "Name": "Master", }, { "InstanceRole": "CORE", "InstanceCount": 1, "InstanceType": instanceTypeForCore, "Market": "ON_DEMAND", "Name": "Core", }, ] } response = CLIENT.run_job_flow( Name="Test Cluster", Instances=instances, VisibleToAllUsers=True, JobFlowRole="EMR_EC2_DefaultRole", ServiceRole="EMR_DefaultRole", ReleaseLabel="emr-6.10.0", ) return response["JobFlowId"] # Terminated the cluster using clusterId received in an event def terminate_cluster(event): print("Trying to terminate cluster, clusterId: " + event["detail"]["clusterId"]) response = CLIENT.terminate_job_flows(JobFlowIds=[event["detail"]["clusterId"]]) print(f"Terminate cluster response: {response}") def describe_cluster(event): response = CLIENT.describe_cluster(ClusterId=event["detail"]["clusterId"]) return response def lambda_handler(event, context): if is_insufficient_capacity_event(event): print( "Received insufficient capacity event for instanceGroup, clusterId: " + event["detail"]["clusterId"] ) describeClusterResponse = describe_cluster(event) shouldTerminateCluster = is_cluster_eligible_for_termination( event, describeClusterResponse ) if shouldTerminateCluster: terminate_cluster(event) clusterId = create_cluster(event) print("Created a new cluster, clusterId: " + clusterId) else: print( "Cluster is not eligible for termination, clusterId: " + event["detail"]["clusterId"] ) else: print("Received event is not insufficient capacity event, skipping")