

As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.

# Responder eventos de capacidade de instância insuficiente do cluster do Amazon EMR
<a name="emr-events-response-insuff-capacity"></a>

## Visão geral do
<a name="emr-events-response-insuff-capacity-overview"></a>

Os clusters do Amazon EMR retornam o código de evento `EC2 provisioning - Insufficient Instance Capacity` quando a zona de disponibilidade selecionada não tem capacidade suficiente para solucionar a solicitação de inicialização ou redimensionamento do cluster. O evento é emitido periodicamente com grupos de instâncias e frotas de instâncias se o Amazon EMR encontrar repetidamente exceções de capacidade insuficientes e não puder solucionar solicitação de provisionamento para iniciar ou redimensionar o cluster.

Esta página descreve como você pode responder melhor a esse tipo de evento quando ele ocorre no cluster do EMR.

## Solução recomendada a um evento de capacidade insuficiente
<a name="emr-events-response-insuff-capacity-rec"></a>

Recomendamos responder a um evento de capacidade insuficiente de uma das seguintes maneiras:
+ Aguarde a recuperação da capacidade. Como a capacidade muda com frequência, uma exceção de capacidade insuficiente pode se recuperar sozinha. Os clusters começarão ou terminarão de ser redimensionados assim que a capacidade do Amazon EC2 estiver disponível.
+ Como alternativa, você pode encerrar o cluster, modificar as configurações de tipo de instância e criar um novo cluster com a solicitação de configuração de cluster atualizada. Para obter mais informações, consulte [Flexibilidade da zona de disponibilidade em um cluster do Amazon EMR](emr-flexibility.md).

Também é possível configurar regras ou respostas automatizadas para um evento de capacidade insuficiente, conforme descrito na próxima seção.

## Recuperação automatizada de um evento de capacidade insuficiente
<a name="emr-events-response-insuff-capacity-ex"></a>

É possível criar automação em resposta aos eventos do Amazon EMR, como aqueles com código de evento `EC2 provisioning - Insufficient Instance Capacity`. Por exemplo, a AWS Lambda função a seguir encerra um cluster do EMR com um grupo de instâncias que usa instâncias sob demanda e, em seguida, cria um novo cluster do EMR com um grupo de instâncias que contém tipos de instância diferentes da solicitação original.

Estas condições acionam a ocorrência do processo automatizado:
+ O evento de capacidade insuficiente foi emitido para nós primários ou centrais durante mais de 20 minutos.
+ O cluster não está no estado **READY** ou **WAITING**. Para obter mais informações sobre estados de cluster do EMR, consulte [Noções básicas sobre o ciclo de vida do cluster](emr-overview.md#emr-overview-cluster-lifecycle).

**nota**  
Ao criar um processo automatizado para uma exceção de capacidade insuficiente, considere que o evento de capacidade insuficiente é recuperável. A capacidade muda com frequência, e os clusters retomarão o redimensionamento ou iniciarão a operação assim que a capacidade do Amazon EC2 estiver disponível.

**Example função para responder ao evento de capacidade insuficiente**  

```
// 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")
```