Reaktion auf Ereignisse mit unzureichender Instance-Kapazität im Amazon-EMR-Cluster - Amazon EMR

Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.

Reaktion auf Ereignisse mit unzureichender Instance-Kapazität im Amazon-EMR-Cluster

Übersicht

Amazon-EMR-Cluster geben den Ereigniscode EC2 provisioning - Insufficient Instance Capacity zurück, wenn die ausgewählte Availability Zone nicht über genügend Kapazität verfügt, um Ihre Anfrage zum Clusterstart oder zur Größenänderung zu erfüllen. Das Ereignis wird regelmäßig sowohl bei Instance-Gruppen als auch bei Instance-Flotten ausgelöst, wenn Amazon EMR wiederholt auf Ausnahmen mit unzureichender Kapazität stößt und Ihre Bereitstellungsanforderung für einen Cluster-Start oder eine Cluster-Größenänderung nicht erfüllen kann.

Auf dieser Seite wird beschrieben, wie Sie am besten auf diesen Ereignistyp reagieren können, wenn er für Ihren EMR-Cluster auftritt.

Empfohlene Reaktion auf ein Ereignis mit unzureichender Kapazität

Es wird empfohlen, dass Sie auf ein Ereignis mit unzureichender Kapazität mit einer der folgenden Methoden reagieren:

  • Warten Sie, bis die Kapazität wiederhergestellt ist. Die Kapazität ändert sich häufig, sodass sich eine Ausnahme mit unzureichender Kapazität von selbst erholen kann. Ihre Cluster beginnen oder beenden die Größenänderung, sobald EC2 Amazon-Kapazität verfügbar ist.

  • Alternativ können Sie Ihren Cluster beenden, Ihre Instance-Typ-Konfigurationen ändern und einen neuen Cluster mit der aktualisierten Cluster-Konfigurationsanforderung erstellen. Weitere Informationen finden Sie unter Flexibilität der Availability Zone für einen Amazon EMR-Cluster.

Sie können auch Regeln oder automatische Reaktionen auf ein Ereignis mit unzureichender Kapazität einrichten, wie im nächsten Abschnitt beschrieben.

Automatisierte Wiederherstellung nach einem Ereignis mit unzureichender Kapazität

Sie können eine Automatisierung als Reaktion auf Amazon-EMR-Ereignisse erstellen, z. B. solche mit Ereigniscode EC2 provisioning - Insufficient Instance Capacity. Die folgende AWS Lambda Funktion beendet beispielsweise einen EMR-Cluster mit einer Instanzgruppe, die On-Demand-Instances verwendet, und erstellt dann einen neuen EMR-Cluster mit einer Instanzgruppe, die andere Instance-Typen als die ursprüngliche Anfrage enthält.

Die folgenden Bedingungen lösen den automatisierten Prozess aus:

  • Das Ereignis „unzureichende Kapazität“ wird seit mehr als 20 Minuten für Primär- oder Core-Knoten ausgelöst.

  • Der Cluster befindet sich nicht im Status READY oder WAITING. Weitere Informationen zu EMR-Cluster-Status finden Sie unter Verstehen des Cluster-Lebenszyklus.

Anmerkung

Wenn Sie einen automatisierten Prozess für eine Ausnahme mit unzureichender Kapazität erstellen, sollten Sie berücksichtigen, dass das Ereignis „unzureichende Kapazität“ wiederherstellbar ist. Die Kapazität ändert sich häufig und Ihre Cluster setzen die Größenänderung fort oder beginnen mit dem Betrieb, sobald EC2 Amazon-Kapazität verfügbar ist.

Beispiel Funktion zur Reaktion auf ein Ereignis mit unzureichender Kapazität
// 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")