

Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.

# Apache Spark
<a name="emr-spark"></a>

[Apache Spark](https://aws.amazon.com/emr/features/spark/) es un marco de procesamiento distribuido y un modelo de programación que lo ayuda a aplicar machine learning, procesamiento de flujos o análisis de gráficos con clústeres de Amazon EMR. Del mismo modo que Apache Hadoop, Spark es un sistema de procesamiento distribuido de código abierto utilizado frecuentemente para cargas de trabajo de big data. Sin embargo, Spark tiene varias diferencias notables con respecto a Hadoop MapReduce. Spark tiene un motor de ejecución optimizado de gráficos acíclicos dirigidos (DAG) y almacena en caché datos en memoria de forma activa, lo que puede aumentar el rendimiento especialmente para ciertos algoritmos y consultas interactivas.

Spark admite de forma nativa aplicaciones escritas en Scala, Python y Java. También incluye varias bibliotecas estrechamente integradas para SQL ([Spark](https://spark.apache.org/sql/)), aprendizaje automático ([MLlib](https://spark.apache.org/mllib/)), procesamiento de flujos ([Spark streaming](https://spark.apache.org/streaming/)) y procesamiento de [gráficos (GraphX](https://spark.apache.org/graphx/)). Estas herramientas facilitan que Spark aproveche el marco para una amplia variedad de casos de uso. 

Puede instalar Spark en un clúster de Amazon EMR junto con otras aplicaciones de Hadoop y el motor puede usar el sistema de archivos de Amazon EMR (EMRFS) para acceder directamente a los datos en Amazon S3. Hive también está integrado con Spark, por lo que puedes usar un HiveContext objeto para ejecutar scripts de Hive con Spark. Un contexto de Hive se incluye en el shell de Spark como `sqlContext`. 

Para ver un ejemplo de tutorial sobre cómo configurar un clúster de EMR con Spark y analizar un conjunto de datos de muestra, consulte [Tutorial: Cómo empezar con Amazon EMR](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-gs.html) en el blog de noticias. AWS 

Puede usar el agente de solución de problemas de Apache Spark para solucionar problemas de sus aplicaciones de Apache Spark en EMR en EC2 y EMR Serverless. Para obtener más información, consulte. [¿Qué es el agente de solución de problemas de Apache Spark para Amazon EMR?](spark-troubleshoot.md)

**importante**  
La versión 2.3.1 de Apache Spark, disponible a partir de la versión 5.16.0 de Amazon EMR, aborda [CVE-2018-8024](https://nvd.nist.gov/vuln/detail/CVE-2018-8024) y [CVE-2018-1334](https://nvd.nist.gov/vuln/detail/CVE-2018-1334). Se recomienda migrar las versiones anteriores de Spark a la versión 2.3.1 o posteriores de Spark.

En la siguiente tabla, se muestra la versión de Spark incluida en la última versión de la serie 7.x de Amazon EMR, junto con los componentes que Amazon EMR instala con Spark.

Para ver la versión de los componentes instalados con Spark en esta versión, consulta las versiones de [componentes de la versión 7.12.0](emr-7120-release.md).


**Información sobre la versión de Spark para emr-7.12.0**  

| Etiqueta de versión de Amazon EMR | Versión de Spark | Componentes instalados con Spark | 
| --- | --- | --- | 
| emr-7.12.0 | Spark 3.5.6-amzn-1 | delta, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-hdfs-zkfc, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, iceberg, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 

En la tabla siguiente, se muestra la versión de Spark incluida en la versión más reciente de la serie 6.x de Amazon EMR, junto con los componentes que Amazon EMR instala con Spark.

Para ver la versión de los componentes instalados con Spark en esta versión, consulte [Versiones de los componentes de la versión 6.15.0](emr-6150-release.md).


**Información de la versión de Spark para emr-6.15.0**  

| Etiqueta de versión de Amazon EMR | Versión de Spark | Componentes instalados con Spark | 
| --- | --- | --- | 
| emr-6.15.0 | Spark 3.4.1-amzn-2 | aws-sagemaker-spark-sdk, delta, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, iceberg, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 

**nota**  
La versión 6.8.0 de Amazon EMR incluye la versión 3.3.0 de Apache Spark. Esta versión de Spark utiliza Apache Log4j 2 y el archivo `log4j2.properties` para configurar Log4j en los procesos de Spark. Si utiliza Spark en el clúster o crea clústeres de EMR con parámetros de configuración personalizados y desea actualizar a la versión 6.8.0 de Amazon EMR, debe migrar al nuevo formato de clave y clasificación de configuración `spark-log4j2` de Apache Log4j 2. Para obtener más información, consulte [Migración de Apache Log4j 1.x a Log4j 2.x](emr-spark-configure.md#spark-migrate-logj42).

En la tabla siguiente, se muestra la versión de Spark incluida en la versión más reciente de la serie 5.x de Amazon EMR, junto con los componentes que Amazon EMR instala con Spark.

Para ver la versión de los componentes instalados con Spark en esta versión, consulte [Versiones del componente de la versión 5.36.2](emr-5362-release.md).


**Información de la versión de Spark para emr-5.36.2**  

| Etiqueta de versión de Amazon EMR | Versión de Spark | Componentes instalados con Spark | 
| --- | --- | --- | 
| emr-5.36.2 | Spark 2.4.8-amzn-2 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 

**Topics**
+ [Creación de un clúster con Apache Spark](emr-spark-launch.md)
+ [Ejecución de aplicaciones de Spark con Docker en Amazon EMR 6.x](emr-spark-docker.md)
+ [Usa el catálogo de AWS Glue Data Catalog con Spark en Amazon EMR](emr-spark-glue.md)
+ [Trabajar con una jerarquía de varios catálogos en AWS Glue Data Catalog with Spark en Amazon EMR](emr-multi-catalog.md)
+ [Configurar Spark](emr-spark-configure.md)
+ [¿Qué es el agente de solución de problemas de Apache Spark para Amazon EMR?](spark-troubleshoot.md)
+ [Optimización del desempeño de Spark](emr-spark-performance.md)
+ [Almacenamiento en caché de fragmentos de resultados de Spark](emr-spark-fragment-result-caching.md)
+ [Uso de Nvidia RAPIDS Accelerator de Nvidia para Spark](emr-spark-rapids.md)
+ [Acceso al intérprete de comandos de Spark](emr-spark-shell.md)
+ [Utilice Amazon SageMaker Spark para el aprendizaje automático](emr-spark-sagemaker.md)
+ [Escritura de una aplicación de Spark](emr-spark-application.md)
+ [Mejora del rendimiento de Spark con Amazon S3](emr-spark-s3-performance.md)
+ [Adición de un paso de Spark](emr-spark-submit-step.md)
+ [Visualización del historial de aplicaciones de Spark](emr-spark-application-history.md)
+ [Accede a la web de Spark UIs](emr-spark-webui.md)
+ [Uso del conector Amazon Kinesis Data Streams de streaming estructurado de Spark](emr-spark-structured-streaming-kinesis.md)
+ [Uso de la integración de Amazon Redshift para Apache Spark con Amazon EMR](emr-spark-redshift.md)
+ [Historial de lanzamientos de Spark](Spark-release-history.md)
+ [Uso de vistas materializadas con Amazon EMR](emr-spark-materialized-views.md)

# Creación de un clúster con Apache Spark
<a name="emr-spark-launch"></a>

El siguiente procedimiento crea un clúster con [Spark](https://aws.amazon.com/big-data/what-is-spark/) instalado a través de las **Opciones rápidas** en la consola de Amazon EMR.

Como alternativa, puede usar **Opciones avanzadas** para personalizar aún más la configuración del clúster o para enviar pasos a fin de instalar aplicaciones mediante programación y, a continuación, ejecutar las aplicaciones personalizadas. Con alguna de las opciones de creación de clústeres, puede elegir utilizar AWS como metaalmacén de Spark SQL. Para obtener más información, consulte [Usa el catálogo de AWS Glue Data Catalog con Spark en Amazon EMR](emr-spark-glue.md).

**Para lanzar un clúster con Spark instalado**

1. [Abra la consola Amazon EMR en https://console.aws.amazon.com /emr.](https://console.aws.amazon.com/emr/)

1. Elija **Crear clúster** para utilizar **Opciones rápidas**.

1. Ingrese un **nombre de clúster**. El nombre del clúster no puede contener los caracteres <, >, \$1, \$1 o ` (acento grave).

1.  En **Configuración de software**, elija una opción de **Versión**.

1.  En **Aplicaciones**, elija el paquete de aplicaciones de **Spark**.

1.  Seleccione las demás opciones que necesite y, a continuación, elija **Create cluster (Crear clúster)**.
**nota**  
Para configurar Spark cuando se crea el clúster, consulte [Configurar Spark](emr-spark-configure.md).

**Para lanzar un clúster con Spark instalado, utilice AWS CLI**
+ Cree el clúster con el siguiente comando:

  ```
  aws emr create-cluster --name "Spark cluster" --release-label emr-7.12.0 --applications Name=Spark \
  --ec2-attributes KeyName=myKey --instance-type m5.xlarge --instance-count 3 --use-default-roles
  ```

**nota**  
Se incluyen caracteres de continuación de línea de Linux (\$1) para facilitar la lectura. Se pueden eliminar o utilizar en los comandos de Linux. En Windows, elimínelos o sustitúyalos por un signo de intercalación (^).

**Para lanzar un clúster con Spark instalado con el SDK para Java**

Especifique Spark como una aplicación con `SupportedProductConfig` utilizado en `RunJobFlowRequest`.
+ El siguiente ejemplo muestra cómo crear un clúster con Spark mediante Java.

  ```
  import com.amazonaws.AmazonClientException;
  import com.amazonaws.auth.AWSCredentials;
  import com.amazonaws.auth.AWSStaticCredentialsProvider;
  import com.amazonaws.auth.profile.ProfileCredentialsProvider;
  import com.amazonaws.services.elasticmapreduce.AmazonElasticMapReduce;
  import com.amazonaws.services.elasticmapreduce.AmazonElasticMapReduceClientBuilder;
  import com.amazonaws.services.elasticmapreduce.model.*;
  import com.amazonaws.services.elasticmapreduce.util.StepFactory;
  
  public class Main {
  
          public static void main(String[] args) {
                  AWSCredentials credentials_profile = null;
                  try {
                          credentials_profile = new ProfileCredentialsProvider("default").getCredentials();
                  } catch (Exception e) {
                          throw new AmazonClientException(
                                          "Cannot load credentials from .aws/credentials file. " +
                                                          "Make sure that the credentials file exists and the profile name is specified within it.",
                                          e);
                  }
  
                  AmazonElasticMapReduce emr = AmazonElasticMapReduceClientBuilder.standard()
                                  .withCredentials(new AWSStaticCredentialsProvider(credentials_profile))
                                  .withRegion(Regions.US_WEST_1)
                                  .build();
  
                  // create a step to enable debugging in the AWS Management Console
                  StepFactory stepFactory = new StepFactory();
                  StepConfig enabledebugging = new StepConfig()
                                  .withName("Enable debugging")
                                  .withActionOnFailure("TERMINATE_JOB_FLOW")
                                  .withHadoopJarStep(stepFactory.newEnableDebuggingStep());
  
                  Application spark = new Application().withName("Spark");
  
                  RunJobFlowRequest request = new RunJobFlowRequest()
                                  .withName("Spark Cluster")
                                  .withReleaseLabel("emr-5.20.0")
                                  .withSteps(enabledebugging)
                                  .withApplications(spark)
                                  .withLogUri("s3://path/to/my/logs/")
                                  .withServiceRole("EMR_DefaultRole")
                                  .withJobFlowRole("EMR_EC2_DefaultRole")
                                  .withInstances(new JobFlowInstancesConfig()
                                                  .withEc2SubnetId("subnet-12ab3c45")
                                                  .withEc2KeyName("myEc2Key")
                                                  .withInstanceCount(3)
                                                  .withKeepJobFlowAliveWhenNoSteps(true)
                                                  .withMasterInstanceType("m4.large")
                                                  .withSlaveInstanceType("m4.large"));
                  RunJobFlowResult result = emr.runJobFlow(request);
                  System.out.println("The cluster ID is " + result.toString());
          }
  }
  ```

# Ejecución de aplicaciones de Spark con Docker en Amazon EMR 6.x
<a name="emr-spark-docker"></a>

**nota**  
El procedimiento descrito en esta sección solo aplica a Amazon EMR versión 6.x.

Con Amazon EMR 6.0.0, las aplicaciones de Spark pueden utilizar contenedores de Docker para definir sus dependencias de biblioteca, en lugar de instalar dependencias en las instancias de Amazon EC2 individuales del clúster. Para ejecutar Spark con Docker, primero debe configurar el registro de Docker y definir parámetros adicionales al enviar una aplicación Spark. Para obtener más información, consulte [Configuración de la integración de Docker](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-plan-docker.html).

Cuando se envía la aplicación, YARN invoca Docker para extraer la imagen de Docker especificada y ejecutar la aplicación Spark dentro de un contenedor de Docker. Esto le permite definir y aislar fácilmente las dependencias. Reduce la duración del proceso de arranque o preparación de las instancias en el clúster de Amazon EMR con las bibliotecas necesarias para la ejecución del trabajo. 

## Consideraciones al ejecutar Spark con Docker
<a name="emr-spark-docker-considerations"></a>

Cuando ejecute Spark con Docker, asegúrese de que se cumplen los siguientes requisitos previos:
+ El paquete `docker` y la CLI solo deben estar instalados en los nodos principales y de tareas.
+ En la versión 6.1.0 y posteriores de Amazon EMR, también puede instalar Docker en un nodo principal con los siguientes comandos.
  + 

    ```
    sudo yum install -y docker
    sudo systemctl start docker
    ```
+ El comando `spark-submit` siempre debe ejecutarse desde una instancia principal en el clúster de Amazon EMR.
+ Los registros de Docker utilizados con el fin de resolver imágenes de Docker deben definirse mediante la API de clasificación con la clave de clasificación `container-executor` para definir parámetros adicionales al iniciar el clúster:
  + `docker.trusted.registries`
  + `docker.privileged-containers.registries`
+ Para ejecutar una aplicación Spark en un contenedor de Docker, son necesarias las siguientes opciones de configuración:
  + `YARN_CONTAINER_RUNTIME_TYPE=docker`
  + `YARN_CONTAINER_RUNTIME_DOCKER_IMAGE={DOCKER_IMAGE_NAME}`
+ Cuando utilice Amazon ECR para recuperar imágenes de Docker, debe configurar el clúster de tal forma que se autentique por sí solo. Para ello, debe utilizar la siguiente opción de configuración:
  + YARN\$1CONTAINER\$1RUNTIME\$1DOCKER\$1CLIENT\$1CONFIG=\$1DOCKER\$1CLIENT\$1CONFIG\$1PATH\$1ON\$1HDFS\$1
+ En la versión 6.1.0 y posteriores de Amazon EMR, no es necesario utilizar el comando indicado `YARN_CONTAINER_RUNTIME_DOCKER_CLIENT_CONFIG={DOCKER_CLIENT_CONFIG_PATH_ON_HDFS}` cuando la característica de autenticación automática de ECR está habilitada.
+ Cualquier imagen de Docker utilizada con Spark debe tener Java instalado en la imagen de Docker.

Para obtener más información acerca de los requisitos previos, consulte [Configurar la integración de Docker](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-plan-docker.html).

## Creación de una imagen de Docker
<a name="emr-spark-docker-image"></a>

Las imágenes de Docker se crean utilizando un archivo Dockerfile, que define los paquetes y la configuración que se van a incluir en la imagen. Los siguientes dos ejemplos de Dockerfiles utilizan y PySpark SparkR.

**PySpark Dockerfile**

Las imágenes de Docker creadas a partir de este Dockerfile incluyen Python 3 y el paquete Python NumPy . Este archivo Dockerfile utiliza Amazon Linux 2 y Amazon Corretto JDK 8.

```
FROM amazoncorretto:8

RUN yum -y update
RUN yum -y install yum-utils
RUN yum -y groupinstall development

RUN yum list python3*
RUN yum -y install python3 python3-dev python3-pip python3-virtualenv

RUN python -V
RUN python3 -V

ENV PYSPARK_DRIVER_PYTHON python3
ENV PYSPARK_PYTHON python3

RUN pip3 install --upgrade pip
RUN pip3 install numpy pandas

RUN python3 -c "import numpy as np"
```

**Archivo Dockerfile de SparkR**

Las imágenes de Docker creadas a partir de este archivo Dockerfile incluyen R y el paquete randomForest CRAN. Este archivo Dockerfile incluye Amazon Linux 2 y Amazon Corretto JDK 8.

```
FROM amazoncorretto:8

RUN java -version

RUN yum -y update
RUN amazon-linux-extras install R4

RUN yum -y install curl hostname

#setup R configs
RUN echo "r <- getOption('repos'); r['CRAN'] <- 'http://cran.us.r-project.org'; options(repos = r);" > ~/.Rprofile

RUN Rscript -e "install.packages('randomForest')"
```

Para obtener más información sobre la sintaxis de los archivos Dockerfile, consulte la [documentación de referencia de Dockerfile](https://docs.docker.com/engine/reference/builder/).

## Uso de imágenes de Docker de Amazon ECR
<a name="emr-spark-docker-ECR"></a>

Amazon Elastic Container Registry (Amazon ECR) es un registro de contenedores de Docker completamente administrado que facilita el almacenamiento, la administración y la implementación de imágenes de contenedores de Docker. Cuando se utiliza Amazon ECR, el clúster debe configurarse de tal forma que confíe en su instancia de ECR. Además, debe configurar la autenticación para que el clúster utilice imágenes de Docker desde Amazon ECR. Para obtener más información, consulte [Configuración de YARN para acceder a Amazon ECR](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-plan-docker.html#emr-docker-ECR). 

Para garantizar que los hosts de Amazon EMR puedan acceder a las imágenes almacenadas en Amazon ECR, su clúster debe tener los permisos de la política `AmazonEC2ContainerRegistryReadOnly` asociados al perfil de instancia. Para obtener más información, consulte la política [https://docs.aws.amazon.com/AmazonECR/latest/userguide/ecr_managed_policies.html#AmazonEC2ContainerRegistryReadOnly](https://docs.aws.amazon.com/AmazonECR/latest/userguide/ecr_managed_policies.html#AmazonEC2ContainerRegistryReadOnly).

En este ejemplo, el clúster debe crearse con la siguiente configuración adicional para asegurarse de que el registro de Amazon ECR sea de confianza. Sustituya el *123456789123.dkr.ecr.us-east-1.amazonaws.com* punto de conexión por su punto de conexión de Amazon ECR.

```
[
  {
    "Classification": "container-executor",
    "Configurations": [
      {
        "Classification": "docker",
        "Properties": {
          "docker.privileged-containers.registries": "local,centos,123456789123.dkr.ecr.us-east-1.amazonaws.com",
          "docker.trusted.registries": "local,centos,123456789123.dkr.ecr.us-east-1.amazonaws.com"
        }
      }
    ],
    "Properties": {}
  }
]
```

**Uso PySpark con Amazon ECR**

El siguiente ejemplo usa el PySpark Dockerfile, que se etiquetará y se cargará en Amazon ECR. Tras cargar el Dockerfile, puede ejecutar el PySpark trabajo y consultar la imagen de Docker de Amazon ECR.

Tras lanzar el clúster, utilice SSH para conectarse a un nodo principal y ejecute los siguientes comandos para crear la imagen de Docker local a partir del ejemplo de Dockerfile. PySpark 

Primero, cree un directorio y un archivo Dockerfile.

```
mkdir pyspark
vi pyspark/Dockerfile
```

Pegue el contenido del PySpark Dockerfile y ejecute los siguientes comandos para crear una imagen de Docker.

```
sudo docker build -t local/pyspark-example pyspark/
```

Cree el repositorio `emr-docker-examples` de ECR para los ejemplos.

```
aws ecr create-repository --repository-name emr-docker-examples
```

Etiquete y cargue la imagen creada localmente en ECR y *123456789123.dkr.ecr.us-east-1.amazonaws.com* sustitúyala por su terminal de ECR.

```
sudo docker tag local/pyspark-example 123456789123.dkr.ecr.us-east-1.amazonaws.com/emr-docker-examples:pyspark-example
sudo docker push 123456789123.dkr.ecr.us-east-1.amazonaws.com/emr-docker-examples:pyspark-example
```

Utilice SSH para conectarse al nodo principal y preparar un script de Python con el nombre de archivo `main.py`. Pegue el siguiente contenido en el archivo `main.py` y guárdelo.

```
from pyspark.sql import SparkSession
spark = SparkSession.builder.appName("docker-numpy").getOrCreate()
sc = spark.sparkContext

import numpy as np
a = np.arange(15).reshape(3, 5)
print(a)
```

En Amazon EMR 6.0.0, para enviar el trabajo, haga referencia al nombre de la imagen de Docker. Defina los parámetros de configuración adicionales para asegurarse de que la ejecución del trabajo utiliza Docker como tiempo de ejecución. Cuando se utiliza Amazon ECR, `YARN_CONTAINER_RUNTIME_DOCKER_CLIENT_CONFIG` debe hacer referencia al archivo `config.json` que contiene las credenciales utilizadas para autenticarse en Amazon ECR.

```
DOCKER_IMAGE_NAME=123456789123.dkr.ecr.us-east-1.amazonaws.com/emr-docker-examples:pyspark-example
DOCKER_CLIENT_CONFIG=hdfs:///user/hadoop/config.json
spark-submit --master yarn \
--deploy-mode cluster \
--conf spark.executorEnv.YARN_CONTAINER_RUNTIME_TYPE=docker \
--conf spark.executorEnv.YARN_CONTAINER_RUNTIME_DOCKER_IMAGE=$DOCKER_IMAGE_NAME \
--conf spark.executorEnv.YARN_CONTAINER_RUNTIME_DOCKER_CLIENT_CONFIG=$DOCKER_CLIENT_CONFIG \
--conf spark.yarn.appMasterEnv.YARN_CONTAINER_RUNTIME_TYPE=docker \
--conf spark.yarn.appMasterEnv.YARN_CONTAINER_RUNTIME_DOCKER_IMAGE=$DOCKER_IMAGE_NAME \
--conf spark.yarn.appMasterEnv.YARN_CONTAINER_RUNTIME_DOCKER_CLIENT_CONFIG=$DOCKER_CLIENT_CONFIG \
--num-executors 2 \
main.py -v
```

En la versión 6.1.0 y posteriores de Amazon EMR, para enviar el trabajo, haga referencia al nombre de la imagen de Docker. Cuando la autenticación automática de ECR esté habilitada, ejecute el siguiente comando.

```
DOCKER_IMAGE_NAME=123456789123.dkr.ecr.us-east-1.amazonaws.com/emr-docker-examples:pyspark-example
spark-submit --master yarn \
--deploy-mode cluster \
--conf spark.executorEnv.YARN_CONTAINER_RUNTIME_TYPE=docker \
--conf spark.executorEnv.YARN_CONTAINER_RUNTIME_DOCKER_IMAGE=$DOCKER_IMAGE_NAME \
--conf spark.yarn.appMasterEnv.YARN_CONTAINER_RUNTIME_TYPE=docker \
--conf spark.yarn.appMasterEnv.YARN_CONTAINER_RUNTIME_DOCKER_IMAGE=$DOCKER_IMAGE_NAME \
--num-executors 2 \
main.py -v
```

Cuando se complete el trabajo, anote el ID de la aplicación YARN y utilice el siguiente comando para obtener el resultado del PySpark trabajo.

```
yarn logs --applicationId application_id | grep -C2 '\[\['
LogLength:55
LogContents:
[[ 0  1  2  3  4]
 [ 5  6  7  8  9]
 [10 11 12 13 14]]
```

**Uso de SparkR con Amazon ECR**

En el ejemplo siguiente se utiliza el archivo Dockerfile de SparkR, que se etiquetará y se cargará en ECR. Una vez cargado el Dockerfile, puede ejecutar el trabajo de SparkR y hacer referencia a la imagen de Docker desde Amazon ECR.

Después de iniciar el clúster, utilice SSH para conectarse a un nodo principal y ejecute los siguientes comandos para crear la imagen de Docker local desde el ejemplo de archivo Dockerfile de SparkR.

Primero, cree un directorio y el archivo Dockerfile.

```
mkdir sparkr
vi sparkr/Dockerfile
```

Pegue el contenido del archivo Dockerfile de SparkR y ejecute los siguientes comandos para crear una imagen de Docker.

```
sudo docker build -t local/sparkr-example sparkr/
```

Etiquete y cargue la imagen creada localmente en Amazon ECR y sustitúyala por su *123456789123.dkr.ecr.us-east-1.amazonaws.com* punto de conexión de Amazon ECR.

```
sudo docker tag local/sparkr-example 123456789123.dkr.ecr.us-east-1.amazonaws.com/emr-docker-examples:sparkr-example
sudo docker push 123456789123.dkr.ecr.us-east-1.amazonaws.com/emr-docker-examples:sparkr-example
```

Utilice SSH para conectarse al nodo principal y preparar un script de R con el nombre `sparkR.R`. Pegue los siguientes contenidos en el archivo `sparkR.R`:

```
library(SparkR)
sparkR.session(appName = "R with Spark example", sparkConfig = list(spark.some.config.option = "some-value"))

sqlContext <- sparkRSQL.init(spark.sparkContext)
library(randomForest)
# check release notes of randomForest
rfNews()

sparkR.session.stop()
```

En Amazon EMR 6.0.0, para enviar el trabajo, haga referencia al nombre de la imagen de Docker. Defina los parámetros de configuración adicionales para asegurarse de que la ejecución del trabajo utiliza Docker como tiempo de ejecución. Cuando se utiliza Amazon ECR, `YARN_CONTAINER_RUNTIME_DOCKER_CLIENT_CONFIG` debe hacer referencia al archivo `config.json` que contiene las credenciales utilizadas para autenticarse en ECR.

```
DOCKER_IMAGE_NAME=123456789123.dkr.ecr.us-east-1.amazonaws.com/emr-docker-examples:sparkr-example
DOCKER_CLIENT_CONFIG=hdfs:///user/hadoop/config.json
spark-submit --master yarn \
--deploy-mode cluster \
--conf spark.executorEnv.YARN_CONTAINER_RUNTIME_TYPE=docker \
--conf spark.executorEnv.YARN_CONTAINER_RUNTIME_DOCKER_IMAGE=$DOCKER_IMAGE_NAME \
--conf spark.executorEnv.YARN_CONTAINER_RUNTIME_DOCKER_CLIENT_CONFIG=$DOCKER_CLIENT_CONFIG \
--conf spark.yarn.appMasterEnv.YARN_CONTAINER_RUNTIME_TYPE=docker \
--conf spark.yarn.appMasterEnv.YARN_CONTAINER_RUNTIME_DOCKER_IMAGE=$DOCKER_IMAGE_NAME \
--conf spark.yarn.appMasterEnv.YARN_CONTAINER_RUNTIME_DOCKER_CLIENT_CONFIG=$DOCKER_CLIENT_CONFIG \
sparkR.R
```

En la versión 6.1.0 y posteriores de Amazon EMR, para enviar el trabajo, haga referencia al nombre de la imagen de Docker. Cuando la autenticación automática de ECR esté habilitada, ejecute el siguiente comando.

```
DOCKER_IMAGE_NAME=123456789123.dkr.ecr.us-east-1.amazonaws.com/emr-docker-examples:sparkr-example
spark-submit --master yarn \
--deploy-mode cluster \
--conf spark.executorEnv.YARN_CONTAINER_RUNTIME_TYPE=docker \
--conf spark.executorEnv.YARN_CONTAINER_RUNTIME_DOCKER_IMAGE=$DOCKER_IMAGE_NAME \
--conf spark.yarn.appMasterEnv.YARN_CONTAINER_RUNTIME_TYPE=docker \
--conf spark.yarn.appMasterEnv.YARN_CONTAINER_RUNTIME_DOCKER_IMAGE=$DOCKER_IMAGE_NAME \
sparkR.R
```

Cuando el trabajo se haya completado, tome nota del ID de aplicación de YARN y utilice el siguiente comando para obtener la salida del trabajo de SparkR. Este ejemplo incluye pruebas para asegurarse de que la biblioteca randomForest, la versión instalada y las notas de la versión están disponibles.

```
yarn logs --applicationId application_id | grep -B4 -A10 "Type rfNews"
randomForest 4.6-14
Type rfNews() to see new features/changes/bug fixes.
Wishlist (formerly TODO):

* Implement the new scheme of handling classwt in classification.

* Use more compact storage of proximity matrix.

* Allow case weights by using the weights in sampling?

========================================================================
Changes in 4.6-14:
```

# Usa el catálogo de AWS Glue Data Catalog con Spark en Amazon EMR
<a name="emr-spark-glue"></a>

Con la versión 5.8.0 o posterior de Amazon EMR, puedes configurar Spark para que utilice el catálogo de datos de AWS Glue como metaalmacén de Apache Hive. Recomendamos esta configuración cuando necesites un metastore de Hive persistente o uno de Hive compartido por distintos clústeres, servicios, aplicaciones o cuentas. AWS 

Con Amazon EMR versión 6.5.0 o posterior, puedes configurar Spark para que utilice el catálogo de datos de AWS Glue con Apache Iceberg.

Con la versión 7.5.0 o posterior de Amazon EMR, puedes configurar Spark para que utilice el catálogo de datos de AWS Glue como su catálogo REST de Iceberg.

AWS Glue es un servicio de extracción, transformación y carga (ETL) totalmente gestionado que permite clasificar los datos, limpiarlos, enriquecerlos y moverlos de forma fiable entre varios almacenes de datos de forma sencilla y rentable. El catálogo de datos de AWS Glue proporciona un repositorio de metadatos unificado en una variedad de fuentes y formatos de datos, y se integra con Amazon EMR, así como con Amazon RDS, Amazon Redshift, Redshift Spectrum, Athena y cualquier aplicación compatible con el metaalmacén de Apache Hive. AWS Los rastreadores de Glue pueden deducir automáticamente el esquema a partir de los datos de origen en Amazon S3 y almacenar los metadatos asociados en el catálogo de datos. Para obtener más información sobre el catálogo de datos, consulte Cómo [rellenar el catálogo de datos de AWS Glue](https://docs.aws.amazon.com/glue/latest/dg/populate-data-catalog.html) en la *Guía del desarrollador de AWS Glue*.

Se aplican cargos separados por AWS Glue. Hay una tarifa mensual para almacenar y acceder a los metadatos del catálogo de datos, una tarifa por hora que se factura por minuto para los trabajos de ETL de AWS Glue y el tiempo de ejecución del rastreador, y una tarifa por hora que se factura por minuto para cada terminal de desarrollo aprovisionado. El Catálogo de datos le permite almacenar hasta un millón de objetos sin cargo alguno. Si almacena más de un millón de objetos, se le cobrará 1 USD por cada 100 000 objetos que sobrepasen esa cifra. En el Catálogo de datos, se consideran objetos las tablas, las particiones y las bases de datos. Para obtener más información, consulte [Precios de Glue](https://aws.amazon.com/glue/pricing).

**importante**  
Si creó tablas con Amazon Athena o Amazon Redshift Spectrum antes del 14 de agosto de 2017, las bases de datos y las tablas se almacenan en un catálogo gestionado por Athena, que es independiente del catálogo de datos de Glue. AWS Para integrar Amazon EMR con estas tablas, debe actualizar al catálogo de datos de AWS Glue. Para obtener más información, consulte [Actualización al catálogo de datos de AWS Glue](https://docs.aws.amazon.com/athena/latest/ug/glue-upgrade.html) en la Guía del *usuario de Amazon Athena*.

## Especificar AWS Glue Data Catalog como metastore de Apache Hive
<a name="emr-spark-glue-configure"></a>

Puedes especificar el catálogo de datos de AWS Glue como metastore mediante la Consola de administración de AWS API AWS CLI, o Amazon EMR. Cuando utiliza la CLI o la API, utiliza la clasificación de configuración de Spark para especificar el catálogo de datos. Además, con Amazon EMR 5.16.0 y versiones posteriores, puede usar la clasificación de configuración para especificar un catálogo de datos en otro. Cuenta de AWS Cuando utiliza la consola, puede especificar el Catálogo de datos mediante **Opciones avanzadas** u **Opciones rápidas**.

**nota**  
La opción de usar AWS Glue Data Catalog también está disponible con Zeppelin porque Zeppelin se instala con los componentes de Spark.

------
#### [ Console ]

**Para especificar AWS Glue Data Catalog como el metaalmacén de Apache Hive con la nueva consola**

1. [Inicie sesión en y abra la Consola de administración de AWS consola de Amazon EMR en https://console.aws.amazon.com /emr.](https://console.aws.amazon.com/emr)

1. En el panel de navegación izquierdo, en **Amazon EMR en EC2**, elija **Clústeres** y, a continuación, elija **Crear clúster**.

1. En **Paquete de aplicaciones**, seleccione **Spark** o **Personalizado**. Si personaliza el clúster, asegúrese de seleccionar Zeppelin o Spark como una de sus aplicaciones.

1. En **Configuración del Catálogo de datos de AWS Glue**, seleccione la casilla **Usar para metadatos de la tabla de Spark**.

1. Elija cualquier otra opción que se aplique a su clúster. 

1. Para lanzar el clúster, elija **Crear clúster**.

------
#### [ AWS CLI ]

**Para especificar el catálogo de datos de AWS Glue como el metaalmacén de Apache Hive con el AWS CLI**

Para obtener más información sobre cómo especificar una clasificación de configuración mediante la AWS CLI API de Amazon EMR, consulte. [Configuración de aplicaciones](emr-configure-apps.md)
+ Especifique el valor de `hive.metastore.client.factory.class` utilizando la clasificación `spark-hive-site` que se muestra en el ejemplo siguiente:

  ```
  [
    {
      "Classification": "spark-hive-site",
      "Properties": {
        "hive.metastore.client.factory.class": "com.amazonaws.glue.catalog.metastore.AWSGlueDataCatalogHiveClientFactory"
      }
    }
  ]
  ```

  Para especificar un catálogo de datos en una AWS cuenta diferente, añada la `hive.metastore.glue.catalogid` propiedad tal y como se muestra en el siguiente ejemplo. Sustituya `acct-id` por la cuenta de AWS del Catálogo de datos.

  ```
  [
    {
      "Classification": "spark-hive-site",
      "Properties": {
        "hive.metastore.client.factory.class": "com.amazonaws.glue.catalog.metastore.AWSGlueDataCatalogHiveClientFactory",
        "hive.metastore.glue.catalogid": "acct-id"
      }
    }
  ]
  ```

------

## Especificar AWS Glue Data Catalog como catálogo de Apache Iceberg
<a name="emr-spark-glue-configure-iceberg"></a>

Puedes especificar el catálogo de datos de AWS Glue como la implementación del catálogo de Apache Iceberg o el punto final del catálogo REST de Apache Iceberg, mediante la Consola de administración de AWS API Amazon EMR o en la AWS CLI configuración de tiempo de ejecución de sesión de Spark. Cuando utiliza la CLI o la API, utiliza la clasificación de configuración de Spark para especificar el catálogo de datos. Para obtener más información, consulte [Especificar el catálogo de datos de AWS Glue como el catálogo de Apache Iceberg](https://docs.aws.amazon.com/emr/latest/ReleaseGuide/emr-spark-glue.html#emr-spark-glue-configure-iceberg).

## Permisos de IAM
<a name="emr-hive-glue-permissions"></a>

El perfil de instancia EC2 de un clúster debe tener permisos de IAM para las acciones de AWS Glue. Además, si habilita el cifrado de los objetos del catálogo de datos de AWS Glue, el rol también debe poder cifrar, descifrar y generar lo que AWS KMS key se utiliza para el cifrado.

### Permisos para las acciones de AWS Glue
<a name="emr-hive-glue-permissions-actions"></a>

Si utiliza el perfil de instancia de EC2 predeterminado para Amazon EMR, no se requiere ninguna acción. La política `AmazonElasticMapReduceforEC2Role` gestionada que se adjunta a la `EMR_EC2_DefaultRole` permite todas las acciones de AWS Glue necesarias. Sin embargo, si especifica un perfil y permisos de instancia EC2 personalizados, debe configurar las acciones de AWS Glue adecuadas. Utilice la política administrada `AmazonElasticMapReduceforEC2Role` como punto de partida. Para más información, consulte [Rol de servicio para instancias de EC2 del clúster (perfil de instancia de EC2)](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-iam-role-for-ec2.html) en la *Guía de administración de Amazon EMR.*

### Permisos para cifrar y descifrar AWS Glue Data Catalog
<a name="emr-hive-glue-permissions-encrypt"></a>

El perfil de instancia necesita permiso para cifrar y descifrar los datos con su clave. *No* es necesario configurar estos permisos si se cumplen las dos instrucciones siguientes:
+ Para activar el cifrado de los objetos del catálogo de datos de AWS Glue, utilice claves gestionadas para AWS Glue.
+ Usas un clúster que está en el mismo lugar Cuenta de AWS que el catálogo de datos de AWS Glue.

De lo contrario, debe agregar la siguiente instrucción a la política de permisos adjunta al perfil de instancia de EC2. 

Para obtener más información sobre el cifrado del catálogo de datos de AWS Glue, consulte [Cifrar el catálogo de datos](https://docs.aws.amazon.com/glue/latest/dg/encrypt-glue-data-catalog.html) en la *Guía para desarrolladores de AWS Glue*.

### Permisos basados en recursos
<a name="emr-hive-glue-permissions-resource"></a>

Si usa AWS Glue junto con Hive, Spark o Presto en Amazon EMR, AWS Glue admite políticas basadas en recursos para controlar el acceso a los recursos del catálogo de datos. Estos recursos incluyen bases de datos, tablas, conexiones y funciones definidas por el usuario. Para obtener más información, consulte [Políticas de recursos de AWS Glue](https://docs.aws.amazon.com/glue/latest/dg/glue-resource-policies.html) en la *Guía para desarrolladores de AWS Glue*.

Al utilizar políticas basadas en recursos para limitar el acceso a AWS Glue desde Amazon EMR, el principal que especifique en la política de permisos debe ser el ARN del rol asociado al perfil de instancia EC2 que se especifica al crear un clúster. Por ejemplo, para una política basada en recursos adjunta a un catálogo, puede especificar el ARN del rol para el rol de servicio predeterminado para las instancias EC2 del clúster, *EMR\$1EC2\$1DefaultRole* como`Principal`, utilizando el formato que se muestra en el siguiente ejemplo:

```
arn:aws:iam::acct-id:role/EMR_EC2_DefaultRole
```

*acct-id*Puede ser diferente del ID de la cuenta de AWS Glue. Esto permite el acceso desde clústeres de EMR en diferentes cuentas. Puede especificar varias entidades principales, cada una de ellas desde una cuenta diferente.

## Consideraciones a la hora de utilizar AWS Glue Data Catalog
<a name="emr-hive-glue-considerations-hive"></a>

Ten en cuenta lo siguiente cuando utilices AWS Glue Data Catalog como un metaalmacén de Apache Hive con Spark:
+ Una base de datos predeterminada sin un URI de ubicación genera errores al crear una tabla. Para solucionar este problema, utilice la cláusula `LOCATION` para especificar la ubicación de un bucket, como `s3://amzn-s3-demo-bucket1`, cuando utilice `CREATE TABLE`. Otra opción consiste en crear tablas dentro de una base de datos distinta de la base de datos predeterminada.
+ No se admite el cambio de nombre de las tablas desde AWS Glue.
+ Al crear una tabla de Hive sin especificar un valor de `LOCATION`, los datos de la tabla se almacenan en la ubicación especificada por la propiedad `hive.metastore.warehouse.dir`. De manera predeterminada, se trata de una ubicación en HDFS. Si otro clúster necesita acceder a la tabla, se produce un error a menos que tenga los permisos adecuados para el clúster que creó la tabla. Además, dado que el almacenamiento en HDFS es transitorio, si el clúster termina, se pierden los datos de la tabla y, por lo tanto, será necesario volver a crearla. Le recomendamos que especifique una `LOCATION` en Amazon S3 cuando cree una tabla Hive con AWS Glue. Como alternativa, puede utilizar la clasificación de configuración `hive-site` para especificar una ubicación en Amazon S3 para `hive.metastore.warehouse.dir`, que se aplica a todas las tablas de Hive. Si se crea una tabla en una ubicación de HDFS y el clúster que la creó sigue ejecutándose, puedes actualizar la ubicación de la tabla a Amazon S3 desde AWS Glue. Para obtener más información, consulte Cómo [trabajar con tablas en la consola de AWS Glue](https://docs.aws.amazon.com/glue/latest/dg/console-tables.html) en la *Guía para desarrolladores de AWS Glue*. 
+ No se admiten valores de partición que contengan comillas y apóstrofes, por ejemplo, `PARTITION (owner="Doe's").`
+ Las [estadísticas de columnas](https://cwiki.apache.org/confluence/display/Hive/StatsDev#StatsDev-ColumnStatistics) son compatibles con emr-5.31.0 y versiones posteriores.
+ No se admite el uso de la [autorización de Hive](https://cwiki.apache.org/confluence/display/Hive/LanguageManual+Authorization). Como alternativa, considere la posibilidad de utilizar [políticas basadas en recursos de AWS Glue](https://docs.aws.amazon.com/glue/latest/dg/glue-resource-policies.html). Para obtener más información, consulte [Uso de políticas basadas en recursos para Amazon EMR Access to Glue AWS](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-iam-roles-glue.html) Data Catalog.

Tenga en cuenta lo siguiente cuando utilice AWS Glue Data Catalog como catálogo REST de Apache Iceberg con Spark:
+ Si usa el catálogo de sesión de Spark con Iceberg, explicado en [Diferencias de configuración cuando usas Iceberg SparkCatalog y SparkSessionCatalog](emr-iceberg-use-spark-cluster.md#emr-iceberg-spark-catalog), debe configurar el Catálogo de datos de AWS Glue como metalmacén de Apache Hive y, además, configurar el Catálogo de datos de AWS Glue como catálogo REST de Apache Iceberg.
+ El punto final IRC de AWS Glue Data Catalog solo admite el esquema de autenticación Amazon SigV4. OAuth no es compatible. Para OAuth los usuarios, utilice el Centro de identidad de IAM para configurar el acceso. Consulte [Connecting Lake Formation with IAM Identity Center](https://docs.aws.amazon.com/lake-formation/latest/dg/connect-lf-identity-center.html).
+ El catálogo REST de AWS Glue Iceberg no admite todas las operaciones en código abierto.

# Trabajar con una jerarquía de varios catálogos en AWS Glue Data Catalog with Spark en Amazon EMR
<a name="emr-multi-catalog"></a>

Puede registrar su clúster de Amazon EMR para acceder al catálogo de datos de AWS Glue, que pone las tablas y otros recursos del catálogo a disposición de varios consumidores. AWS Glue Data Catalog admite una jerarquía de varios catálogos, que unifica los datos en los lagos de datos de Amazon S3. También proporciona una API del metastore de Hive y una API REST de Apache Iceberg de código abierto para acceder a los datos. Estas características están disponibles para Amazon EMR y otros servicios como Amazon Athena y Amazon Redshift.

## Cómo se organizan los recursos del catálogo
<a name="emr-lakehouse-org"></a>

Al crear recursos en el catálogo de datos de AWS Glue, puede acceder a ellos desde cualquier motor SQL que admita la API REST de Apache Iceberg o el metaalmacén de Hive. AWS Lake Formation gestiona los permisos.

En AWS Glue Data Catalog, los datos se organizan en una jerarquía lógica de catálogos, bases de datos y tablas:
+ **Catálogo**: contenedor lógico que contiene objetos de un almacén de datos, como esquemas o tablas. 
+ **Catálogo para almacenar tablas de Redshift Managed Storage (RMS)**: cuando administra catálogos para almacenar tablas RMS, puede acceder a esas tablas mediante Iceberg. 
+ **Base de datos**: organiza los objetos de datos de un catálogo, como tablas y vistas.
+ **Tablas y vistas**: objetos de datos de una base de datos que proporcionan una capa de abstracción con un esquema comprensible. Proporcionan una capa para acceder a datos en distintos formatos y ubicaciones.



## Configuración de un catálogo de datos para usarlo con Amazon EMR
<a name="emr-lakehouse-configuration"></a>

Para comenzar, debe configurar el catálogo para que admita las herramientas de Amazon EMR. El catálogo de datos de AWS Glue es compatible con Hive Metastore y con Iceberg REST. APIs 

**Configuración de Amazon EMR con un metalmacén de Hive**

 Para obtener información sobre cómo configurarlo, consulta la [compatibilidad del catálogo de datos de AWS Glue para trabajos de Spark](https://docs.aws.amazon.com/glue/latest/dg/aws-glue-programming-etl-glue-data-catalog-hive.html) en la Guía del usuario de AWS Glue. En este tema se describe cómo configurar el catálogo de datos de AWS Glue como un metaalmacén de Hive y hacer que esté disponible como punto final. Además, hay documentación de Amazon EMR disponible que muestra cómo especificar el catálogo de datos de AWS Glue como un metaalmacén de Spark, en Use [the AWS Glue Data Catalog como metastore de Apache Hive](https://docs.aws.amazon.com/emr/latest/ReleaseGuide/emr-spark-glue.html) para Spark.

## Permisos para acceder a los recursos del catálogo de datos de AWS Glue
<a name="emr-lakehouse-using-irc-prereqs"></a>

En esta sección, se describen los requisitos de políticas de IAM para usar las herramientas de Amazon EMR con datos del catálogo. Tras registrar el clúster en el catálogo de datos de AWS Glue, necesitará los siguientes permisos para descubrir la creación y los cambios en el catálogo de datos creado posteriormente: 
+ **pegamento: GetCatalog**
+ **pegamento: GetCatalogs**
+ **conjuntos: AssumeRole**
+ **conjuntos: TagSession**
+ **conjuntos: SetContext**
+ **conjuntos: SetSourceIdentity**

En la mayoría de los casos, recomendamos crear un rol de IAM y asignarle los permisos necesarios.

Además, para consultar datos del catálogo, usted debe establecer permisos para el catálogo mediante AWS Lake Formation. Para más información sobre cómo establecer permisos en catálogos de datos mediante AWS Lake Formation, consulte [Granting and revoking permissions on Data Catalog resources](https://docs.aws.amazon.com/lake-formation/latest/dg/granting-catalog-permissions.html).

Una vez que configure su clúster y defina los permisos sobre los objetos del catálogo, puede enviar trabajos para consultar y procesar datos.

## Configurar Spark para acceder a una jerarquía de varios catálogos en AWS Glue Data Catalog
<a name="emr-lakehouse-using-spark-access"></a>

Con EMR 7.5, puedes configurar Spark para que utilice la jerarquía multicálogos de AWS Glue. Una jerarquía de múltiples catálogos permite:
+ Lleve sus datos de Redshift Managed Storage (RMS), como tablas, vistas y vistas materializadas de los almacenes de datos de Amazon Redshift existentes, a Glue Data Catalog. AWS Puede consultar estos objetos desde EMR on EC2 y EMR sin servidor. 
+ Cree catálogos RMS, AWS Glue Data Catalog y almacene datos en RMS con ZeroETL y consulte los datos con motores de consulta compatibles con Iceberg.
+ Cree tablas Iceberg gestionadas en AWS Glue Data Catalog con una gestión de almacenamiento completa que incluye compactación, instantáneas y retención.

### Conexión con varios catálogos al iniciar una sesión de Spark
<a name="emr-iceberg-initialize-spark-session-spark"></a>

Los siguientes ejemplos muestran cómo usar Spark shell interactivo, Spark submit o Amazon EMR Notebooks para trabajar AWS con la jerarquía de múltiples catálogos de Glue.

------
#### [ spark-shell ]

1. Conéctese al nodo principal utilizando SSH. Para obtener más información, consulte [Conexión al nodo maestro mediante SSH](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-connect-master-node-ssh.html) en la *Guía de administración de Amazon EMR*.

1. Introduzca el siguiente comando para iniciar el shell de Spark. Para usar la PySpark carcasa, sustitúyala por. `spark-shell` `pyspark`

   ```
   spark-shell \
       --conf spark.sql.catalog.my_catalog=org.apache.iceberg.spark.SparkCatalog \
       --conf spark.sql.catalog.my_catalog.warehouse=s3://amzn-s3-demo-bucket/prefix/
       --conf spark.sql.catalog.my_catalog.type=glue \
       --conf spark.sql.catalog.my_catalog.glue.id=Glue RMS catalog ID \
       --conf spark.sql.defaultCatalog=my_catalog \
       --conf spark.sql.extensions=org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions
   ```

------
#### [ spark-submit ]

1. Conéctese al nodo principal utilizando SSH. Para obtener más información, consulte [Conexión al nodo maestro mediante SSH](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-connect-master-node-ssh.html) en la *Guía de administración de Amazon EMR*.

1. Ingrese el siguiente comando para iniciar la sesión de Spark para Spark.

   ```
   spark-submit \
   --conf spark.sql.catalog.my_catalog=org.apache.iceberg.spark.SparkCatalog \
   --conf spark.sql.catalog.my_catalog.warehouse=s3://amzn-s3-demo-bucket1/prefix \
   --conf spark.sql.catalog.my_catalog.type=glue \
   --conf spark.sql.catalog.my_catalog.glue.id=Glue RMS catalog ID \
   --conf spark.sql.defaultCatalog=my_catalog \
   --conf spark.sql.extensions=org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions
   ```

------
#### [ EMR Studio notebooks ]

Para iniciar una sesión de Spark con los Cuadernos de Amazon EMR, configure su sesión de Spark con el comando mágico `%%configure` de su cuaderno de Amazon EMR, como en el siguiente ejemplo. Para obtener más información, consulte [Usar la magia de Cuadernos de Amazon EMR](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-studio-magics.html#emr-magics) en la *Guía de administración de Amazon EMR*.

```
%%configure -f{
"conf":{
    "spark.sql.catalog.my_catalog":"org.apache.iceberg.spark.SparkCatalog",
    "spark.sql.catalog.my_catalog.type":"glue",
    "spark.sql.catalog.my_catalog.glue.id":"Glue RMS catalog ID",
    "spark.sql.catalog.my_catalog.warehouse":"s3://amzn-s3-demo-bucket1/prefix/",
    "spark.sql.defaultCatalog", "my_catalog",
    "spark.sql.extensions":"org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions"
    }
}
```

------
#### [ CLI ]

Para inicializar una sesión de Spark mediante la CLI, ejecute el siguiente ejemplo. Para obtener más información sobre cómo especificar una clasificación de configuración mediante la AWS CLI API de Amazon EMR, consulte [Configurar](https://docs.aws.amazon.com/emr/latest/ReleaseGuide/emr-configure-apps.html) aplicaciones.

```
[
  {
    "Classification": "spark-defaults",
    "Properties": {
      "spark.sql.catalog.my_catalog":"org.apache.iceberg.spark.SparkCatalog",
      "spark.sql.catalog.my_catalog.type":"glue",
      "spark.sql.catalog.my_catalog.glue.id":"Glue RMS catalog ID",
      "spark.sql.catalog.my_catalog.warehouse":"s3://amzn-s3-demo-bucket1/prefix/",
      "spark.sql.defaultCatalog", "my_catalog",
      "spark.sql.extensions":"org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions"
    }
  }
]
```

------

#### Inicie una sesión de Spark en Redshift Managed Storage con AWS Glue Data Catalog
<a name="considerations-multi-catalog-glue-connect"></a>

El siguiente ejemplo inicia una sesión de Spark con el Catálogo de datos de AWS Glue.

```
spark-sql \
  --conf spark.sql.catalog.rms=org.apache.iceberg.spark.SparkCatalog \
  --conf spark.sql.catalog.rms.type=glue \
  --conf spark.sql.catalog.rms.glue.id=Glue RMS catalog ID \
  --conf spark.sql.defaultCatalog=rms
  --conf spark.sql.extensions=org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions
```

El siguiente ejemplo inicializa una sesión de Spark con la API REST de Iceberg y Redshift Managed Storage with Glue AWS Data Catalog.

```
spark-sql \
  --conf spark.sql.catalog.rms=org.apache.iceberg.spark.SparkCatalog \
  --conf spark.sql.catalog.rms.type=rest \
  --conf spark.sql.catalog.rms.warehouse=glue RMS catalog ID \
  --conf spark.sql.catalog.rms.uri=Glue endpoint URI/iceberg \
  --conf spark.sql.catalog.rms.rest.sigv4-enabled=true \
  --conf spark.sql.catalog.rms.rest.signing-name=glue \
  --conf spark.sql.defaultCatalog=rms \
  --conf spark.sql.extensions=org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions
```

Para obtener más información sobre el uso de una jerarquía de catálogos múltiples de AWS Glue con Spark Iceberg, consulta [Usar un clúster de Iceberg](https://docs.aws.amazon.com/emr/latest/ReleaseGuide/emr-iceberg-use-spark-cluster.html) con Spark.

## Consideraciones y limitaciones para una configuración con varios catálogos
<a name="considerations-multi-catalog"></a>
+ Una jerarquía de varios catálogos no admite el metalmacén de Apache Hive.
+ Una jerarquía de varios catálogos con Apache Iceberg no permite recurrir al metalmacén de Apache Hive cuando se usa `SparkSessionCatalog`.
+ Los clústeres de EMR en EC2 con rol de tiempo de ejecución no admiten jerarquías de varios catálogos.
+ Los EMR en los clústeres de EC2 habilitados AWS Lake Formation no admiten la jerarquía de varios catálogos.

# Configurar Spark
<a name="emr-spark-configure"></a>

Puede configurar [Spark en Amazon EMR](https://aws.amazon.com/elasticmapreduce/details/spark/) con clasificaciones de configuración. Para obtener más información sobre cómo las clasificaciones de configuración, consulte [Configuración de aplicaciones](emr-configure-apps.md).

Entre las clasificaciones de configuración para Spark en Amazon EMR se incluyen los siguientes:
+ **`spark`**: establece la propiedad `maximizeResourceAllocation` en true o false. Si es true, Amazon EMR configura automáticamente las propiedades `spark-defaults` en función de la configuración de hardware del clúster. Para obtener más información, consulte [Uso de `maximizeResourceAllocation`](#emr-spark-maximizeresourceallocation).
+ **`spark-defaults`**: establece los valores del archivo `spark-defaults.conf`. Para obtener más información, consulte [Spark configuration](https://spark.apache.org/docs/latest/configuration.html) en la documentación de Spark.
+ **`spark-env`**: establece los valores del archivo `spark-env.sh`. Para obtener más información, consulte [Environment variables](https://spark.apache.org/docs/latest/configuration.html#environment-variables) en la documentación de Spark.
+ **`spark-hive-site`**: establece los valores del archivo `hive-site.xml` para Spark.
+ **`spark-log4j`**: (versión 6.7.x y anteriores de Amazon EMR) establece los valores del archivo `log4j.properties`. Para obtener más información, consulte el archivo [log4j.properties.template](https://github.com/apache/spark/blob/branch-3.2/conf/log4j.properties.template) en GitHub.
+ **`spark-log4j2`**: (versión 6.8.0 y posteriores de Amazon EMR) establece los valores del archivo `log4j2.properties`. Para obtener más información, consulte el archivo [log4j2.properties.template](https://github.com/apache/spark/blob/v3.3.0/conf/log4j2.properties.template) en GitHub.
+ **`spark-metrics`**: establece los valores del archivo `metrics.properties`. Para conocer la configuración y obtener más información, consulte el archivo [metrics.properties.template](https://github.com/apache/spark/blob/master/conf/metrics.properties.template) en GitHub y [Metrics](https://spark.apache.org/docs/latest/monitoring.html#metrics) en la documentación de Spark.

**nota**  
Si va a migrar cargas de trabajo de Spark a Amazon EMR desde otra plataforma, le recomendamos que pruebe las cargas de trabajo con los [Valores predeterminados de Spark establecidos por Amazon EMR](#spark-defaults) antes de agregar configuraciones personalizadas. La mayoría de los clientes observan mejoras de rendimiento con nuestra configuración predeterminada.

**Topics**
+ [Valores predeterminados de Spark establecidos por Amazon EMR](#spark-defaults)
+ [Configuración de la recopilación de elementos no utilizados de Spark en Amazon EMR 6.1.0](#spark-gc-config)
+ [Uso de `maximizeResourceAllocation`](#emr-spark-maximizeresourceallocation)
+ [Configuración del comportamiento de retirada de nodos](#spark-decommissioning)
+ [Variable de ThriftServer entorno Spark](#spark-thriftserver)
+ [Cambio de la configuración predeterminada de Spark](#spark-change-defaults)
+ [Migración de Apache Log4j 1.x a Log4j 2.x](#spark-migrate-logj42)

## Valores predeterminados de Spark establecidos por Amazon EMR
<a name="spark-defaults"></a>

En la siguiente tabla, se muestra cómo Amazon EMR establece valores los predeterminados en `spark-defaults` que afectan a las aplicaciones.


**Valores predeterminados de Spark establecidos por Amazon EMR**  

| Opción | Description (Descripción) | Predeterminado | 
| --- | --- | --- | 
| spark.executor.memory | Cantidad de memoria que utilizar por proceso de ejecutor. Por ejemplo: `1g`, `2g`. |  Esta configuración se determina según los tipos de instancias principales y de tareas del clúster.   | 
| spark.executor.cores | El número de núcleos que se va a utilizar en cada ejecutor. | Esta configuración se determina según los tipos de instancias principales y de tareas del clúster. | 
| spark.dynamicAllocation.enabled | Si se establece en true, utilice la asignación de recursos dinámica para escalar y reducir verticalmente el número de ejecutores registrados en una aplicación en función de la carga de trabajo. |  `true` (con la versión 4.4.0 y posteriores de Amazon EMR)  Amazon EMR configura automáticamente Spark Shuffle Service.   | 
| spark.sql.hive.advancedPartitionPredicatePushdown.enabled | Si se establece en true, se habilita la inserción avanzada de predicados de particiones en el metaalmacén de Hive. | true | 
| spark.sql.hive.stringLikePartitionPredicatePushdown.enabled | Inserta los filtros `startsWith`, `contains` y `endsWith` en el metaalmacén de Hive.  Glue no admite la inserción de predicados para `startsWith`, `contains` ni `endsWith`. Si utiliza el metaalmacén de Glue y detecta errores debido a la inserción de predicados para estas funciones, establezca esta configuración en `false`.   | true | 

## Configuración de la recopilación de elementos no utilizados de Spark en Amazon EMR 6.1.0
<a name="spark-gc-config"></a>

Al establecer configuraciones personalizadas de recopilación de elementos no utilizados con `spark.driver.extraJavaOptions` y `spark.executor.extraJavaOptions`, se produce un error en el lanzamiento del controlador o el ejecutor con Amazon EMR 6.1 debido a un conflicto de configuración de recopilación de elementos no utilizados con Amazon EMR 6.1.0. En el caso de Amazon EMR 6.1.0, la configuración predeterminada de recopilación de elementos no utilizados se establece mediante `spark.driver.defaultJavaOptions` y `spark.executor.defaultJavaOptions`. Esta configuración se aplica únicamente a Amazon EMR 6.1.0. Las opciones de JVM que no estén relacionadas con la recopilación de elementos no utilizados, como las que permiten configurar el registro (`-verbose:class`), todavía se pueden establecer mediante `extraJavaOptions`. Para obtener más información, consulte [Spark application properties](https://spark.apache.org/docs/latest/configuration.html#application-properties). 

## Uso de `maximizeResourceAllocation`
<a name="emr-spark-maximizeresourceallocation"></a>

Si quiere configurar los ejecutores para utilizar el máximo de recursos posible en cada nodo de un clúster, establezca `maximizeResourceAllocation` en `true` en la clasificación de configuración `spark`. La opción `maximizeResourceAllocation` es específica de Amazon EMR. Al habilitar `maximizeResourceAllocation`, Amazon EMR calcula el máximo de recursos de computación y de memoria disponibles para un ejecutor en una instancia del grupo de instancias principales. A continuación, establece la configuración `spark-defaults` correspondiente en función de los valores máximos calculados.

Amazon EMR calcula el máximo de recursos de computación y de memoria disponibles para un ejecutor basado en un tipo de instancia de la flota de instancias principales. Dado que cada flota de instancias puede tener distintos tipos y tamaños de instancias dentro de una flota, la configuración de ejecutor que utiliza Amazon EMR puede no ser la mejor para sus clústeres, por lo que no recomendamos utilizar la configuración predeterminada cuando se utilice la asignación máxima de recursos. Configure ajustes personalizados para los clústeres de su flota de instancias.

**nota**  
No debe utilizar la `maximizeResourceAllocation` opción en clústeres con otras aplicaciones distribuidas, por ejemplo. HBase Amazon EMR utiliza configuraciones de YARN personalizadas para las aplicaciones distribuidas, lo que puede entrar en conflicto con `maximizeResourceAllocation` y hacer que se produzcan errores en las aplicaciones de Spark.

A continuación, se muestra un ejemplo de una clasificación de configuración de Spark con la opción `maximizeResourceAllocation` establecida en `true`.

```
[
  {
    "Classification": "spark",
    "Properties": {
      "maximizeResourceAllocation": "true"
    }
  }
]
```


**Opciones configuradas en `spark-defaults` cuando `maximizeResourceAllocation`está habilitado**  

| Opción | Description (Descripción) | Valor | 
| --- | --- | --- | 
| spark.default.parallelism | Transformaciones como unir y paralelizar RDDs devuelven el número predeterminado de particiones cuando el usuario no lo establece. reduceByKey |  2X número de núcleos de CPU disponibles para contenedores de YARN.  | 
| spark.driver.memory | Cantidad de memoria que se utilizará para el proceso del controlador, es decir, dónde se SparkContext inicializa. (por ejemplo, 1 g, 2 g). |  El ajuste se configura en función de los tipos de instancia en el clúster. Sin embargo, dado que la aplicación del controlador de Spark puede ejecutarse en la instancia principal o en una de las instancias básicas (por ejemplo, en un cliente de YARN y modos de clústeres, respectivamente), esto se establece en función del más pequeño de los tipos de instancia de estos dos grupos de instancias.  | 
| spark.executor.memory | Cantidad de memoria que se va a utilizar por cada proceso de ejecutor, por ejemplo 1g, 2g. |  El ajuste se configura en función de los tipos de instancias secundarias y de tareas del clúster.   | 
| spark.executor.cores | El número de núcleos que se va a utilizar en cada ejecutor.  | El ajuste se configura en función de los tipos de instancias secundarias y de tareas del clúster.  | 
| spark.executor.instances |  El número de ejecutores. |  El ajuste se configura en función de los tipos de instancias secundarias y de tareas del clúster. Se define a menos que `spark.dynamicAllocation.enabled` defina explícitamente en true al mismo tiempo.  | 

## Configuración del comportamiento de retirada de nodos
<a name="spark-decommissioning"></a>

Con la versión 5.9.0 o una posterior de Amazon EMR, Spark en Amazon EMR incluye un conjunto de características para ayudar a garantizar que Spark gestione correctamente la terminación de los nodos debido a una solicitud de cambio de tamaño manual o de política de escalado automático. Amazon EMR implementa un mecanismo de lista de denegación en Spark que se basa en el mecanismo de retirada de YARN. Este mecanismo ayuda a evitar que se programen tareas nuevas en un nodo que se está retirando, al tiempo que permite que finalicen las tareas que ya se están ejecutando. Además, existen características para ayudar a recuperar los trabajos de Spark más rápido si se pierden bloques de reorganización cuando termina un nodo. El proceso de recálculo se activa antes, y está optimizado para realizarse más rápido, con menos reintentos de etapas, y se puede evitar que se produzcan errores en los trabajos debido a problemas de recuperación provocados por los bloques de reorganización que faltan.

**importante**  
La configuración `spark.decommissioning.timeout.threshold` se agregó en la versión 5.11.0 de Amazon EMR para mejorar la resiliencia de Spark cuando se utilizan instancias de spot. En las versiones anteriores, cuando un nodo utilizaba una instancia de spot y la instancia se terminaba debido al precio de puja, era posible que Spark no pudiera gestionar la terminación correctamente. Los tareas pueden fallar y los recálculos de reorganización pueden tardar mucho tiempo. Por este motivo, le recomendamos que utilice la versión 5.11.0 o posterior si utiliza instancias de spot.


**Configuración de la retirada de nodos de Spark**  

| Opción | Description (Descripción) | Predeterminado | 
| --- | --- | --- | 
|  `spark.blacklist.decommissioning.enabled`  |  Cuando se establece en `true`, Spark agrega a la lista de denegación los nodos que tienen el estado `decommissioning` en YARN. Spark no programa tareas nuevas en los ejecutores activos en ese nodo. A las tareas que se encuentran en ejecución se les permite completarse.  |  `true`  | 
|  `spark.blacklist.decommissioning.timeout`  |  Cantidad de tiempo que permanece en la lista de denegación un nodo cuyo estado es `decommissioning`. De forma predeterminada, este valor se establece en una hora, que también es el valor predeterminado de `yarn.resourcemanager.decommissioning.timeout`. Para asegurarse de que un nodo permanece en la lista de denegación durante todo su periodo de retirada, establezca un valor mayor o igual que `yarn.resourcemanager.decommissioning.timeout`. Cuando vence el tiempo de espera para la retirada, el nodo pasa al estado `decommissioned` y Amazon EMR no puede terminar la instancia de EC2 del nodo. Si hay alguna tarea en ejecución cuando finaliza el tiempo de espera, se pierde o se cancela y se reprograma en los ejecutores activos de los otros nodos.  |  `1h`  | 
|  `spark.decommissioning.timeout.threshold`  |  Disponible en la versión 5.11.0 o posteriores de Amazon EMR. Se especifica en segundos. Cuando un nodo pasa al estado Retirando, si el host lo va a retirar en un periodo de tiempo igual o menor que este valor, Amazon EMR no solo agrega el nodo a la lista de denegación, sino que también limpia el estado del host (según se especifique mediante `spark.resourceManager.cleanupExpiredHost`) sin necesidad de esperar a que el nodo cambie al estado Retirado. Esto permite que Spark gestione mejor las terminaciones de instancias de spot, ya que las instancias de spot se retiran dentro de un tiempo de espera de 20 segundos, independientemente del valor de `yarn.resourcemager.decommissioning.timeout`, que posiblemente no proporcione a los demás nodos tiempo suficiente para leer los archivos de reorganización.  |  `20s`  | 
|  `spark.resourceManager.cleanupExpiredHost`  |  Cuando se establece en `true`, Spark anula el registro de todos los datos almacenados en la memoria caché y los bloques de reorganización que se almacenan en ejecutores en los nodos que tienen el estado `decommissioned`. Esto acelera el proceso de recuperación.  |  `true`  | 
|  `spark.stage.attempt.ignoreOnDecommissionFetchFailure`  |  Cuando se establece en `true`, ayuda a evitar errores en las etapas de Spark y que al final el trabajo no se complete debido a un número excesivo de recuperaciones desde los nodos retirados. Los errores en las recuperaciones de los bloques de reorganización de un nodo con el estado `decommissioned` no cuentan para el cálculo del número máximo de errores de recuperación consecutivos.  | true | 

## Variable de ThriftServer entorno Spark
<a name="spark-thriftserver"></a>

Spark establece la variable de entorno Hive Thrift Server Port, `HIVE_SERVER2_THRIFT_PORT`, en 10 001.

## Cambio de la configuración predeterminada de Spark
<a name="spark-change-defaults"></a>

Puede cambiar la configuración predeterminada en `spark-defaults.conf` utilizando la clasificación de configuración `spark-defaults` al crear el clúster o el ajuste `maximizeResourceAllocation` en la clasificación de configuración `spark`.

Los siguientes procedimientos muestran cómo modificar los ajustes mediante la CLI o la consola.

**Para crear un clúster con el valor de spark.executor.memory definido en 2g mediante la CLI**
+ Cree un clúster con Spark instalado y el valor de `spark.executor.memory` establecido en 2g con el siguiente comando, que hace referencia a un archivo (`myConfig.json`) almacenado en Amazon S3.

  ```
  aws emr create-cluster --release-label emr-7.12.0 --applications Name=Spark \
  --instance-type m5.xlarge --instance-count 2 --service-role EMR_DefaultRole_V2 --ec2-attributes InstanceProfile=EMR_EC2_DefaultRole --configurations https://s3.amazonaws.com/amzn-s3-demo-bucket/myfolder/myConfig.json
  ```
**nota**  
Se incluyen caracteres de continuación de línea de Linux (\$1) para facilitar la lectura. Se pueden eliminar o utilizar en los comandos de Linux. En Windows, elimínelos o sustitúyalos por un signo de intercalación (^).

  `myConfig.json`:

  ```
  [
      {
        "Classification": "spark-defaults",
        "Properties": {
          "spark.executor.memory": "2G"
        }
      }
    ]
  ```

**Para crear un clúster con el valor de spark.executor.memory definido en 2g mediante la consola**

1. Vaya hasta la nueva consola de Amazon EMR y seleccione **Ir a la consola antigua** en el panel de navegación lateral. Para más información sobre lo que puede esperar al cambiar a la consola antigua, consulte [Uso de la consola antigua](https://docs.aws.amazon.com/emr/latest/ManagementGuide/whats-new-in-console.html#console-opt-in).

1. Elija **Crear clúster** e **Ir a las opciones avanzadas**.

1. Elija **Spark**. 

1. En **Edit software settings (Editar configuración de software)**, deje seleccionada la opción **Enter configuration (Escribir la configuración)** y especifique la siguiente configuración:

   ```
   classification=spark-defaults,properties=[spark.executor.memory=2G]
   ```

1. Seleccione otras opciones, elija **** y, a continuación, elija **Crear clúster**.

**Para configurar maximizeResourceAllocation**
+ Cree un clúster con Spark instalado y `maximizeResourceAllocation` establecido en true utilizando el AWS CLI archivo almacenado en Amazon S3`myConfig.json`, haciendo referencia a un archivo.

  ```
  aws emr create-cluster --release-label emr-7.12.0 --applications Name=Spark \
  --instance-type m5.xlarge --instance-count 2 --service-role EMR_DefaultRole_V2 --ec2-attributes InstanceProfile=EMR_EC2_DefaultRole --configurations https://s3.amazonaws.com/amzn-s3-demo-bucket/myfolder/myConfig.json
  ```
**nota**  
Se incluyen caracteres de continuación de línea de Linux (\$1) para facilitar la lectura. Se pueden eliminar o utilizar en los comandos de Linux. En Windows, elimínelos o sustitúyalos por un signo de intercalación (^).

  `myConfig.json`:

  ```
  [
    {
      "Classification": "spark",
      "Properties": {
        "maximizeResourceAllocation": "true"
      }
    }
  ]
  ```

**nota**  
Con la versión 5.21.0 y posteriores de Amazon EMR, puede anular las configuraciones de clúster y especificar las clasificaciones de configuración adicionales para cada grupo de instancias en un clúster en ejecución. Para ello, utilice la consola Amazon EMR, el AWS Command Line Interface (AWS CLI) o el AWS SDK. Para obtener más información, consulte [Suministrar una configuración para un grupo de instancias en un clúster en ejecución](https://docs.aws.amazon.com/emr/latest/ReleaseGuide/emr-configure-apps-running-cluster.html).

## Migración de Apache Log4j 1.x a Log4j 2.x
<a name="spark-migrate-logj42"></a>

Las versiones 3.2.x y anteriores de [Apache Spark](https://aws.amazon.com/emr/features/spark/) utilizan la versión heredada de Apache Log4j 1.x y el archivo `log4j.properties` para configurar Log4j en los procesos de Spark. Las versiones 3.3.0 y posteriores de Apache Spark utilizan Apache Log4j 2.x y el archivo `log4j2.properties` para configurar Log4j en los procesos de Spark.

Si ha configurado Apache Spark Log4j con una versión de Amazon EMR anterior a la 6.8.0, debe eliminar la clasificación de configuración `spark-log4j` heredada y completar la migración al formato de clave y clasificación de configuración `spark-log4j2` para poder actualizar a la versión 6.8.0 o posteriores de Amazon EMR. La clasificación `spark-log4j` heredada provoca un error `ValidationException` en la creación del clúster en las versiones 6.8.0 y posteriores de Amazon EMR. No se le cobrará nada en caso de un error relacionado con la incompatibilidad de Log4j, pero deberá eliminar la clasificación de configuración `spark-log4j` extinta para continuar.

Para obtener más información sobre la migración de Apache Log4j 1.x a Log4j 2.x, consulte [Apache Log4j Migration Guide](https://logging.apache.org/log4j/2.x/manual/migration.html) y [Spark Log4j 2 Template](https://github.com/apache/spark/blob/master/conf/log4j2.properties.template) en GitHub. 

**nota**  
Con Amazon EMR, Apache Spark usa un archivo `log4j2.properties` en lugar del archivo .xml descrito en [Apache Log4j Migration Guide](https://logging.apache.org/log4j/2.x/manual/migration.html). Además, no recomendamos utilizar el método de puente de Log4j 1.x para llevar a cabo la conversión a Log4j 2.x. 

# ¿Qué es el agente de solución de problemas de Apache Spark para Amazon EMR?
<a name="spark-troubleshoot"></a>

## Introducción
<a name="spark-troubleshooting-agent-intro"></a>

El agente de solución de problemas de Apache Spark para Amazon EMR es una función de IA conversacional que simplifica la solución de problemas de las aplicaciones de Apache Spark en Amazon EMR, Glue AWS y Amazon Notebooks. SageMaker La solución de problemas tradicional de Spark requiere un análisis manual exhaustivo de los registros, las métricas de rendimiento y los patrones de error para identificar las causas principales y corregir el código. El agente simplifica este proceso mediante indicaciones en lenguaje natural, análisis automatizados de la carga de trabajo y recomendaciones de código inteligentes.

Puede utilizar el agente para solucionar problemas PySpark y errores de las aplicaciones de Scala. El agente analiza los trabajos fallidos, identifica los cuellos de botella en el rendimiento y proporciona recomendaciones prácticas y correcciones de código, a la vez que le da el control total sobre las decisiones de implementación.

**nota**  
El agente de solución de problemas de Apache Spark está disponible sin coste adicional como parte de Amazon EMR. El agente solo proporciona análisis y recomendaciones. Solo paga por los recursos de Amazon EMR que utiliza al ejecutar las aplicaciones para validar las correcciones recomendadas.

## Información general de la arquitectura
<a name="spark-troubleshooting-agent-architecture"></a>

El agente de solución de problemas tiene tres componentes principales: un asistente de IA compatible con MCP en el entorno de desarrollo para la interacción, el [proxy MCP](https://github.com/aws/mcp-proxy-for-aws), AWS que gestiona la comunicación y la autenticación seguras entre el cliente y los AWS servicios, y el servidor MCP remoto de Amazon SageMaker Unified Studio, `(preview)` que proporciona herramientas especializadas de solución de problemas de Spark para Amazon EMR, Glue AWS y Amazon Notebooks. SageMaker Este diagrama ilustra cómo interactúa con el servidor MCP remoto de Amazon SageMaker Unified Studio a través de su asistente de IA.

![\[Arquitectura del agente de solución de problemas de Spark.\]](http://docs.aws.amazon.com/es_es/emr/latest/ReleaseGuide/images/spark-troubleshooting-agent-architecture.png)


El asistente de IA organizará la solución de problemas mediante las herramientas especializadas proporcionadas por el servidor MCP siguiendo estos pasos:
+ **Extracción de funciones y creación de contexto:** el agente recopila y analiza automáticamente los datos de telemetría de tu aplicación Spark, incluidos los registros del servidor de historial de Spark, los ajustes de configuración y las trazas de errores. Extrae las métricas clave de rendimiento, los patrones de uso de los recursos y las señales de error para crear un perfil de contexto completo que permita solucionar problemas de forma inteligente.
+ **Analizador de causas fundamentales y motor de recomendaciones de GenAI:** el agente aprovecha los modelos de IA y la base de conocimientos de Spark para correlacionar las funciones extraídas e identificar las causas fundamentales de los problemas o fallos de rendimiento. Proporciona información de diagnóstico y análisis de los errores en la ejecución de la aplicación de Spark.
+ **Recomendación sobre el código de GenAI Spark:** Basándose en el análisis de la causa raíz del paso anterior, el agente analiza los patrones de código existentes e identifica las operaciones ineficientes que requieren correcciones de código para los fallos de las aplicaciones. Proporciona recomendaciones prácticas que incluyen modificaciones específicas del código, ajustes de configuración y mejoras arquitectónicas con ejemplos concretos.

**Topics**
+ [Introducción](#spark-troubleshooting-agent-intro)
+ [Información general de la arquitectura](#spark-troubleshooting-agent-architecture)
+ [Configuración del agente de solución de problemas](spark-troubleshooting-agent-setup.md)
+ [Uso del agente de solución de problemas](spark-troubleshooting-using-troubleshooting-agent.md)
+ [Características y capacidades](spark-troubleshooting-features.md)
+ [Solución de problemas y preguntas y respuestas](spark-troubleshooting-agent-troubleshooting.md)
+ [El flujo de trabajo del agente de solución de problemas de Spark](spark-troubleshooting-agent-workflow.md)
+ [Ejemplos rápidos](spark-troubleshooting-agent-prompt-examples.md)
+ [Configuración de roles de IAM](spark-troubleshooting-agent-iam-setup.md)
+ [Uso de las herramientas de solución de problemas de](spark-troubleshooting-agent-using-tools.md)
+ [Configuración de puntos de enlace de VPC de interfaz para Amazon Unified Studio MCP SageMaker](spark-troubleshooting-agent-vpc-endpoints.md)
+ [Procesamiento entre regiones para el agente de solución de problemas de Apache Spark](spark-troubleshooting-cross-region-processing.md)
+ [Registro de llamadas MCP de Amazon SageMaker Unified Studio mediante AWS CloudTrail](spark-troubleshooting-cloudtrail-integration.md)
+ [Mejoras en el servicio para los agentes de Apache Spark](spark-agents-service-improvements.md)

# Configuración del agente de solución de problemas
<a name="spark-troubleshooting-agent-setup"></a>

**nota**  
El agente de solución de problemas de Apache Spark utiliza la inferencia entre regiones para procesar las solicitudes en lenguaje natural y generar respuestas. Para obtener más información, consulte. [Procesamiento entre regiones para el agente de solución de problemas de Apache Spark](spark-troubleshooting-cross-region-processing.md) El servidor MCP de Amazon SageMaker Unified Studio se encuentra en versión preliminar y está sujeto a cambios.

## Requisitos previos
<a name="spark-troubleshooting-agent-prerequisites"></a>

Antes de comenzar nuestro proceso de configuración para la integración con la CLI de Kiro, asegúrese de tener lo siguiente instalado en su estación de trabajo:
+  [Instalar AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) 
+  [Instale Python 3.10\$1](https://www.python.org/downloads/release/python-3100/) 
+  [Instale el administrador de `uv` paquetes para [MCP](https://github.com/aws/mcp-proxy-for-aws?tab=readme-ov-file)](https://docs.astral.sh/uv/getting-started/installation/) Proxy para AWS
+  [Instale Kiro CLI](https://kiro.dev/docs/cli/) 
+ AWS credenciales locales configuradas (mediante [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-configure.html), variables de entorno o funciones de IAM): para operaciones locales, como la carga de artefactos de trabajo actualizados para la ejecución de trabajos de validación de EMR.

## Recursos de configuración
<a name="spark-troubleshooting-agent-setup-resources"></a>

Puede usar una AWS CloudFormation plantilla para configurar el recurso para el servidor MCP. Estas plantillas son ejemplos que debe modificar para satisfacer sus requisitos. La plantilla crea los siguientes recursos para el proceso de solución de problemas:

1. Función de IAM que tiene permisos para llamar al servidor MCP y los permisos necesarios para el proceso de solución de problemas en la plataforma seleccionada.

Elija uno de los botones **Lanzar pila** de la siguiente tabla. Esto lanza la pila en la AWS CloudFormation consola de la región correspondiente.


| Region | Lanzar | 
| --- | --- | 
| Este de EE. UU. (Ohio) |  [https://console.aws.amazon.com/cloudformation/home?region=us-east-2#/stacks/new?templateURL=https%3A%2F%2Fsmus-mcp-cfn-template-prod-us-east-2.s3.us-east-2.amazonaws.com%2Fcloudformation%2Fspark-troubleshooting-mcp-setup.yaml&stackName=spark-troubleshooting-mcp-setup](https://console.aws.amazon.com/cloudformation/home?region=us-east-2#/stacks/new?templateURL=https%3A%2F%2Fsmus-mcp-cfn-template-prod-us-east-2.s3.us-east-2.amazonaws.com%2Fcloudformation%2Fspark-troubleshooting-mcp-setup.yaml&stackName=spark-troubleshooting-mcp-setup)  | 
| Este de EE. UU. (Norte de Virginia) |  [https://console.aws.amazon.com/cloudformation/home?region=us-east-1#/stacks/new?templateURL=https%3A%2F%2Fsmus-mcp-cfn-template-prod-us-east-1.s3.us-east-1.amazonaws.com%2Fcloudformation%2Fspark-troubleshooting-mcp-setup.yaml&stackName=spark-troubleshooting-mcp-setup](https://console.aws.amazon.com/cloudformation/home?region=us-east-1#/stacks/new?templateURL=https%3A%2F%2Fsmus-mcp-cfn-template-prod-us-east-1.s3.us-east-1.amazonaws.com%2Fcloudformation%2Fspark-troubleshooting-mcp-setup.yaml&stackName=spark-troubleshooting-mcp-setup)  | 
| Oeste de EE. UU. (Oregón) |  [https://console.aws.amazon.com/cloudformation/home?region=us-west-2#/stacks/new?templateURL=https%3A%2F%2Fsmus-mcp-cfn-template-prod-us-west-2.s3.us-west-2.amazonaws.com%2Fcloudformation%2Fspark-troubleshooting-mcp-setup.yaml&stackName=spark-troubleshooting-mcp-setup](https://console.aws.amazon.com/cloudformation/home?region=us-west-2#/stacks/new?templateURL=https%3A%2F%2Fsmus-mcp-cfn-template-prod-us-west-2.s3.us-west-2.amazonaws.com%2Fcloudformation%2Fspark-troubleshooting-mcp-setup.yaml&stackName=spark-troubleshooting-mcp-setup)  | 
| Asia-Pacífico (Tokio) |  [https://console.aws.amazon.com/cloudformation/home?region=ap-northeast-1#/stacks/new?templateURL=https%3A%2F%2Fsmus-mcp-cfn-template-prod-ap-northeast-1.s3.ap-northeast-1.amazonaws.com%2Fcloudformation%2Fspark-troubleshooting-mcp-setup.yaml&stackName=spark-troubleshooting-mcp-setup](https://console.aws.amazon.com/cloudformation/home?region=ap-northeast-1#/stacks/new?templateURL=https%3A%2F%2Fsmus-mcp-cfn-template-prod-ap-northeast-1.s3.ap-northeast-1.amazonaws.com%2Fcloudformation%2Fspark-troubleshooting-mcp-setup.yaml&stackName=spark-troubleshooting-mcp-setup)  | 
| Europa (Irlanda) |  [https://console.aws.amazon.com/cloudformation/home?region=eu-west-1#/stacks/new?templateURL=https%3A%2F%2Fsmus-mcp-cfn-template-prod-eu-west-1.s3.eu-west-1.amazonaws.com%2Fcloudformation%2Fspark-troubleshooting-mcp-setup.yaml&stackName=spark-troubleshooting-mcp-setup](https://console.aws.amazon.com/cloudformation/home?region=eu-west-1#/stacks/new?templateURL=https%3A%2F%2Fsmus-mcp-cfn-template-prod-eu-west-1.s3.eu-west-1.amazonaws.com%2Fcloudformation%2Fspark-troubleshooting-mcp-setup.yaml&stackName=spark-troubleshooting-mcp-setup)  | 
| Asia-Pacífico (Singapur) |  [https://console.aws.amazon.com/cloudformation/home?region=ap-southeast-1#/stacks/new?templateURL=https%3A%2F%2Fsmus-mcp-cfn-template-prod-ap-southeast-1.s3.ap-southeast-1.amazonaws.com%2Fcloudformation%2Fspark-troubleshooting-mcp-setup.yaml&stackName=spark-troubleshooting-mcp-setup](https://console.aws.amazon.com/cloudformation/home?region=ap-southeast-1#/stacks/new?templateURL=https%3A%2F%2Fsmus-mcp-cfn-template-prod-ap-southeast-1.s3.ap-southeast-1.amazonaws.com%2Fcloudformation%2Fspark-troubleshooting-mcp-setup.yaml&stackName=spark-troubleshooting-mcp-setup)  | 
| Asia-Pacífico (Sídney) |  [https://console.aws.amazon.com/cloudformation/home?region=ap-southeast-2#/stacks/new?templateURL=https%3A%2F%2Fsmus-mcp-cfn-template-prod-ap-southeast-2.s3.ap-southeast-2.amazonaws.com%2Fcloudformation%2Fspark-troubleshooting-mcp-setup.yaml&stackName=spark-troubleshooting-mcp-setup](https://console.aws.amazon.com/cloudformation/home?region=ap-southeast-2#/stacks/new?templateURL=https%3A%2F%2Fsmus-mcp-cfn-template-prod-ap-southeast-2.s3.ap-southeast-2.amazonaws.com%2Fcloudformation%2Fspark-troubleshooting-mcp-setup.yaml&stackName=spark-troubleshooting-mcp-setup)  | 
| Canadá (centro) |  [https://console.aws.amazon.com/cloudformation/home?region=ca-central-1#/stacks/new?templateURL=https%3A%2F%2Fsmus-mcp-cfn-template-prod-ca-central-1.s3.ca-central-1.amazonaws.com%2Fcloudformation%2Fspark-troubleshooting-mcp-setup.yaml&stackName=spark-troubleshooting-mcp-setup](https://console.aws.amazon.com/cloudformation/home?region=ca-central-1#/stacks/new?templateURL=https%3A%2F%2Fsmus-mcp-cfn-template-prod-ca-central-1.s3.ca-central-1.amazonaws.com%2Fcloudformation%2Fspark-troubleshooting-mcp-setup.yaml&stackName=spark-troubleshooting-mcp-setup)  | 
| América del Sur (São Paulo) |  [https://console.aws.amazon.com/cloudformation/home?region=sa-east-1#/stacks/new?templateURL=https%3A%2F%2Fsmus-mcp-cfn-template-prod-sa-east-1.s3.sa-east-1.amazonaws.com%2Fcloudformation%2Fspark-troubleshooting-mcp-setup.yaml&stackName=spark-troubleshooting-mcp-setup](https://console.aws.amazon.com/cloudformation/home?region=sa-east-1#/stacks/new?templateURL=https%3A%2F%2Fsmus-mcp-cfn-template-prod-sa-east-1.s3.sa-east-1.amazonaws.com%2Fcloudformation%2Fspark-troubleshooting-mcp-setup.yaml&stackName=spark-troubleshooting-mcp-setup)  | 
| Europa (Fráncfort) |  [https://console.aws.amazon.com/cloudformation/home?region=eu-central-1#/stacks/new?templateURL=https%3A%2F%2Fsmus-mcp-cfn-template-prod-eu-central-1.s3.eu-central-1.amazonaws.com%2Fcloudformation%2Fspark-troubleshooting-mcp-setup.yaml&stackName=spark-troubleshooting-mcp-setup](https://console.aws.amazon.com/cloudformation/home?region=eu-central-1#/stacks/new?templateURL=https%3A%2F%2Fsmus-mcp-cfn-template-prod-eu-central-1.s3.eu-central-1.amazonaws.com%2Fcloudformation%2Fspark-troubleshooting-mcp-setup.yaml&stackName=spark-troubleshooting-mcp-setup)  | 
| Europa (Estocolmo) |  [https://console.aws.amazon.com/cloudformation/home?region=eu-north-1#/stacks/new?templateURL=https%3A%2F%2Fsmus-mcp-cfn-template-prod-eu-north-1.s3.eu-north-1.amazonaws.com%2Fcloudformation%2Fspark-troubleshooting-mcp-setup.yaml&stackName=spark-troubleshooting-mcp-setup](https://console.aws.amazon.com/cloudformation/home?region=eu-north-1#/stacks/new?templateURL=https%3A%2F%2Fsmus-mcp-cfn-template-prod-eu-north-1.s3.eu-north-1.amazonaws.com%2Fcloudformation%2Fspark-troubleshooting-mcp-setup.yaml&stackName=spark-troubleshooting-mcp-setup)  | 
| Europa (Londres) |  [https://console.aws.amazon.com/cloudformation/home?region=eu-west-2#/stacks/new?templateURL=https%3A%2F%2Fsmus-mcp-cfn-template-prod-eu-west-2.s3.eu-west-2.amazonaws.com%2Fcloudformation%2Fspark-troubleshooting-mcp-setup.yaml&stackName=spark-troubleshooting-mcp-setup](https://console.aws.amazon.com/cloudformation/home?region=eu-west-2#/stacks/new?templateURL=https%3A%2F%2Fsmus-mcp-cfn-template-prod-eu-west-2.s3.eu-west-2.amazonaws.com%2Fcloudformation%2Fspark-troubleshooting-mcp-setup.yaml&stackName=spark-troubleshooting-mcp-setup)  | 
| Europa (París) |  [https://console.aws.amazon.com/cloudformation/home?region=eu-west-3#/stacks/new?templateURL=https%3A%2F%2Fsmus-mcp-cfn-template-prod-eu-west-3.s3.eu-west-3.amazonaws.com%2Fcloudformation%2Fspark-troubleshooting-mcp-setup.yaml&stackName=spark-troubleshooting-mcp-setup](https://console.aws.amazon.com/cloudformation/home?region=eu-west-3#/stacks/new?templateURL=https%3A%2F%2Fsmus-mcp-cfn-template-prod-eu-west-3.s3.eu-west-3.amazonaws.com%2Fcloudformation%2Fspark-troubleshooting-mcp-setup.yaml&stackName=spark-troubleshooting-mcp-setup)  | 
| Asia-Pacífico (Seúl) |  [https://console.aws.amazon.com/cloudformation/home?region=ap-northeast-2#/stacks/new?templateURL=https%3A%2F%2Fsmus-mcp-cfn-template-prod-ap-northeast-2.s3.ap-northeast-2.amazonaws.com%2Fcloudformation%2Fspark-troubleshooting-mcp-setup.yaml&stackName=spark-troubleshooting-mcp-setup](https://console.aws.amazon.com/cloudformation/home?region=ap-northeast-2#/stacks/new?templateURL=https%3A%2F%2Fsmus-mcp-cfn-template-prod-ap-northeast-2.s3.ap-northeast-2.amazonaws.com%2Fcloudformation%2Fspark-troubleshooting-mcp-setup.yaml&stackName=spark-troubleshooting-mcp-setup)  | 
| Asia-Pacífico (Mumbai) |  [https://console.aws.amazon.com/cloudformation/home?region=ap-south-1#/stacks/new?templateURL=https%3A%2F%2Fsmus-mcp-cfn-template-prod-ap-south-1.s3.ap-south-1.amazonaws.com%2Fcloudformation%2Fspark-troubleshooting-mcp-setup.yaml&stackName=spark-troubleshooting-mcp-setup](https://console.aws.amazon.com/cloudformation/home?region=ap-south-1#/stacks/new?templateURL=https%3A%2F%2Fsmus-mcp-cfn-template-prod-ap-south-1.s3.ap-south-1.amazonaws.com%2Fcloudformation%2Fspark-troubleshooting-mcp-setup.yaml&stackName=spark-troubleshooting-mcp-setup)  | 

**Diríjase a la página de especificar los detalles** de la pila e introduzca el **nombre de la pila**. Introduzca información adicional en **Parámetros**. Proporcione la siguiente información y proceda a crear la pila.
+ **TroubleshootingRoleName**- Nombre del rol de IAM que se va a crear para las operaciones de solución de problemas
+ **Habilitar EMREC2**: habilita los permisos de solución de problemas de EMR-EC2 (predeterminado: true)
+ **Habilitar EMRServerless**: habilite los permisos de solución de problemas sin servidor de EMR (predeterminado: true)
+ **EnableGlue**- Habilita los permisos de solución de problemas de Glue (predeterminado: true)
+ **CloudWatchKmsKeyArn**- (Opcional) ARN de la clave KMS existente para el cifrado de CloudWatch registros (solo EMR sin servidor, déjelo en blanco para el cifrado predeterminado)

También puede descargar y revisar [la CloudFormation plantilla](https://github.com/aws-samples/aws-emr-utilities/blob/03c20fece616de23ec0ea5389f0113a5bc65fc3a/utilities/apache-spark-agents/spark-troubleshooting-agent-cloudformation/spark-troubleshooting-mcp-setup.yaml), especificar las opciones anteriores e iniciar la plantilla usted mismo con los comandos CloudFormation CLI; consulte un ejemplo a continuación:

```
# deploy the stack with CloudFormation CLI commands
aws cloudformation deploy \
  --template-file spark-troubleshooting-mcp-setup.yaml \
  --stack-name spark-troubleshooting-mcp-setup \
  --region <your Spark MCP server launch region> \
  --capabilities CAPABILITY_NAMED_IAM \
  --parameter-overrides \
    TroubleshootingRoleName=spark-troubleshooting-role


# retrieve the 1-line instruction to set the local environment variables, which will be used for the following MCP server configuration
aws cloudformation describe-stacks \
  --stack-name spark-troubleshooting-mcp-setup \
  --region <your Spark MCP server launch region> \
  --query "Stacks[0].Outputs[?OutputKey=='ExportCommand'].OutputValue" \
  --output text
```

Abra la pestaña Salidas (o extráigala del comando CLI CloudFormation describe-stacks anterior) y copie la instrucción de 1 línea de la salida para configurar CloudFormation las variables de entorno y, a continuación, ejecútela en su entorno local. Ejemplo de instrucción de 1 línea:

```
export SMUS_MCP_REGION=<your mcp server launch region> && export IAM_ROLE=arn:aws:iam::111122223333:role/spark-troubleshooting-role-xxxxxx
```

A continuación, ejecute el siguiente comando de forma local para configurar el perfil de IAM y el servidor MCP:

```
# Step 1: Configure AWS CLI Profile
aws configure set profile.smus-mcp-profile.role_arn ${IAM_ROLE}
aws configure set profile.smus-mcp-profile.source_profile <AWS CLI Profile to assume the IAM role - ex: default>
aws configure set profile.smus-mcp-profile.region ${SMUS_MCP_REGION}

# Step 2: if you are using kiro CLI, use the following command to add the MCP configuration
# Add Spark Troubleshooting MCP Server
kiro-cli-chat mcp add \
    --name "sagemaker-unified-studio-mcp-troubleshooting" \
    --command "uvx" \
    --args "[\"mcp-proxy-for-aws@latest\",\"https://sagemaker-unified-studio-mcp.${SMUS_MCP_REGION}.api.aws/spark-troubleshooting/mcp\", \"--service\", \"sagemaker-unified-studio-mcp\", \"--profile\", \"smus-mcp-profile\", \"--region\", \"${SMUS_MCP_REGION}\", \"--read-timeout\", \"180\"]" \
    --timeout 180000 \
    --scope global
    
# Add Spark Code Recommendation MCP Server
kiro-cli-chat mcp add \
    --name "sagemaker-unified-studio-mcp-code-rec" \
    --command "uvx" \
    --args "[\"mcp-proxy-for-aws@latest\",\"https://sagemaker-unified-studio-mcp.${SMUS_MCP_REGION}.api.aws/spark-code-recommendation/mcp\", \"--service\", \"sagemaker-unified-studio-mcp\", \"--profile\", \"smus-mcp-profile\", \"--region\", \"${SMUS_MCP_REGION}\", \"--read-timeout\", \"180\"]" \
    --timeout 180000 \
    --scope global
```

Esto debería actualizarse `~/.kiro/settings/mcp.json` para incluir la configuración del servidor MCP que se muestra a continuación.

```
{
  "mcpServers": {
    "sagemaker-unified-studio-mcp-troubleshooting": {
      "type": "stdio",
      "command": "uvx",
      "args": [
        "mcp-proxy-for-aws@latest",
        "https://sagemaker-unified-studio-mcp.us-east-1.api.aws/spark-troubleshooting/mcp",
        "--service",
        "sagemaker-unified-studio-mcp",
        "--profile",
        "smus-mcp-profile",
        "--region",
        "us-east-1",
        "--read-timeout",
        "180"
      ],
      "timeout": 180000,
      "disabled": false
    },
    "sagemaker-unified-studio-mcp-code-rec": {
      "type": "stdio",
      "command": "uvx",
      "args": [
        "mcp-proxy-for-aws@latest",
        "https://sagemaker-unified-studio-mcp.us-east-1.api.aws/spark-code-recommendation/mcp",
        "--service",
        "sagemaker-unified-studio-mcp",
        "--profile",
        "smus-mcp-profile",
        "--region",
        "us-east-1",
        "--read-timeout",
        "180"
      ],
      "timeout": 180000,
      "disabled": false
    }
  }
}
```

Consulte [Interfaces compatibles](spark-troubleshooting-using-troubleshooting-agent.md#supported-interfaces) la guía de configuración para diferentes clientes MCP como Kiro, Cline y. GitHub CoPilot

# Uso del agente de solución de problemas
<a name="spark-troubleshooting-using-troubleshooting-agent"></a>

## Modos de implementación compatibles
<a name="supported-deployment-modes"></a>

El agente de solución de problemas de Apache Spark para Amazon EMR admite capacidades de análisis integrales para cargas de trabajo de Spark fallidas, que incluyen el diagnóstico automático de errores, la identificación de cuellos de botella en el rendimiento, recomendaciones de código y sugerencias prácticas para mejorar el rendimiento de las aplicaciones en el siguiente modo de implementación de Spark:
+ EMR en EC2
+ EMR sin servidor
+ AWS Glue

Consulte [Características y capacidades](spark-troubleshooting-features.md) para comprender las características, capacidades y limitaciones detalladas.

## Interfaces compatibles
<a name="supported-interfaces"></a>

### Solución de problemas de celdas en Amazon SageMaker Notebooks
<a name="troubleshooting-sagemaker-notebooks"></a>

Una demostración de la experiencia de solución de problemas con Amazon SageMaker Notebooks. En caso de avería en una celda de un portátil, puedes solicitar al agente de Amazon SageMaker Notebook que solucione el problema y solicite el análisis y, posteriormente, una posible corrección del código si el error se debe a un código, haciendo clic en el `Fix with AI` botón.

[![AWS Videos](http://img.youtube.com/vi/https://www.youtube.com/embed/btW8hwio0tE/0.jpg)](http://www.youtube.com/watch?v=https://www.youtube.com/embed/btW8hwio0tE)


### Solución de problemas de aplicaciones Glue y EMR Spark con Kiro CLI
<a name="troubleshooting-glue-emr-applications"></a>

Inicie Kiro CLI o su asistente de IA y verifique las herramientas cargadas para el proceso de solución de problemas.

```
...
 sagemaker-unified-studio-mcp-code-rec (MCP)
 - spark_code_recommendation    not trusted
 
 sagemaker-unified-studio-mcp-troubleshooting (MCP)
 - analyze_spark_workload       not trusted
...
```

Ahora estás listo para iniciar el flujo de trabajo del agente de solución de problemas de Spark.

Una demostración de la experiencia de solución de problemas con Kiro CLI. Simplemente puede iniciar el proceso de solución de problemas con el siguiente mensaje:

```
Analyze my Glue job. The job name is "xxx" and the job run id is "xxx"
```

[![AWS Videos](http://img.youtube.com/vi/https://www.youtube.com/embed/YLwV_EenJXY/0.jpg)](http://www.youtube.com/watch?v=https://www.youtube.com/embed/YLwV_EenJXY)


### Integración con otros clientes de MCP
<a name="integration-other-mcp-clients"></a>

La configuración descrita en también se [Configuración del agente de solución de problemas](spark-troubleshooting-agent-setup.md) puede utilizar en otros clientes MCP y IDEs para conectarse al servidor MCP administrado:
+ **Integración con Cline**: para usar el servidor MCP con Cline, modifique `cline_mcp_settings.json` y añada la configuración anterior. Consulte la [documentación de Cline](https://docs.cline.bot/mcp/configuring-mcp-servers) para obtener más información sobre cómo administrar la configuración del MCP.
+ **Integración con Claude Code** Para utilizar el servidor MCP con Claude Code, modifique el archivo de configuración para incluir la configuración MCP. La ruta del archivo varía en función del sistema operativo. Consulte [ https://code.claude.com/docs/en/mcp](https://code.claude.com/docs/en/mcp) para obtener información detallada sobre la configuración.
+ **Integración con GitHub Copilot**: para utilizar el servidor MCP con GitHub Copilot, siga las instrucciones de [ https://docs.github.com/en/copilot/how-tos/provide-context/use-mcp/extend- copilot-chat-with-mcp](https://docs.github.com/en/copilot/how-tos/provide-context/use-mcp/extend-copilot-chat-with-mcp) para modificar el archivo de configuración correspondiente y siga las instrucciones de cada IDE para activar la configuración.

# Características y capacidades
<a name="spark-troubleshooting-features"></a>

## Plataformas admitidas
<a name="supported-platforms"></a>
+ **Lenguajes**: aplicaciones Python y Scala Spark
+ **Plataformas de destino**: Amazon EMR, EMR Serverless y Glue AWS 

## Cómo funciona
<a name="how-it-works"></a>

Cuando tu aplicación Spark falla, puedes usar el agente de solución de problemas para investigar automáticamente qué ha fallado. Analiza los registros de eventos, los mensajes de error y el uso de recursos de Spark para identificar el problema exacto, ya sea que el ejecutor de Spark se quede sin memoria, un error de configuración o un error de código.

Cuando le pides a un mensaje en lenguaje natural que analice tu carga de trabajo en Spark, el agente se conecta a los recursos de tu plataforma y extrae funciones (entre las que se incluyen los registros de eventos de Spark, los planes de consultas, los cronogramas de los ejecutores, el seguimiento de los registros, las configuraciones y las métricas):
+ En EMR-EC2: se conecta a la interfaz de usuario persistente de [EMR](https://docs.aws.amazon.com/emr/latest/ManagementGuide/app-history-spark-UI.html) para el clúster
+ On Glue: crea el contexto de la [interfaz de usuario de Spark](https://docs.aws.amazon.com/glue/latest/dg/monitor-spark-ui-jobs.html) de Glue Studio para el trabajo
+ [En EMR-Serverless: se conecta a EMR-Serverless Spark History Server para realizar el trabajo](https://docs.aws.amazon.com/emr-serverless/latest/APIReference/API_GetDashboardForJobRun.html)
+ El agente también analiza las trazas de la pila de errores y los detalles de configuración para proporcionarte información útil.

En el caso de las cargas de trabajo fallidas, obtendrá una explicación clara de la causa raíz y pasos específicos para solucionarla. Si el agente detecta un problema relacionado con el código, proporciona automáticamente recomendaciones de código para mostrarle exactamente qué es lo que debe cambiar en el código. También puedes solicitar sugerencias a nivel de código directamente en cualquier momento sin necesidad de realizar un análisis completo.

## Regiones disponibles
<a name="available-regions"></a>

El agente de solución de problemas de Spark está disponible en las siguientes regiones:
+ **Asia-Pacífico**: Tokio (ap-northeast-1), Seúl (ap-northeast-2), Singapur (ap-southeast-1), Sídney (ap-southeast-2) y Bombay (ap-south-1)
+ **América del Norte**: Canadá (ca-central-1)
+ **Europa**: Estocolmo (eu-north-1), Irlanda (eu-west-1), Londres (eu-west-2), París (eu-west-3) y Frankfurt (eu-central-1)
+ **América del Sur**: São Paulo (sa-east-1)
+ **Estados Unidos**: norte de Virginia (us-east-1), Ohio (us-east-2) y Oregón (us-west-2)

## Alcance de la solución de problemas de Spark y requisitos de usuario
<a name="scope-requirements"></a>
+ **Estados de carga de trabajo de Spark compatibles**: las herramientas solo admitirán respuestas para cargas de trabajo de Spark fallidas.
+ **Interfaz de usuario persistente de EMR:** al analizar las cargas de trabajo de Amazon EMR-EC2, la herramienta de análisis intentará conectarse a la interfaz de usuario persistente de EMR para recuperar la información clave de Spark. [Las consideraciones sobre la interfaz de usuario persistente de EMR se documentan aquí.](https://docs.aws.amazon.com/emr/latest/ManagementGuide/app-history-spark-UI.html#app-history-spark-UI-limitations)
+ **Interfaz de usuario de Glue Studio Spark**: al analizar las cargas de trabajo de AWS Glue, la herramienta de análisis intentará recuperar la información clave de Spark analizando los registros de eventos de Spark del usuario de Amazon S3. El tamaño máximo permitido del registro de eventos de Spark está documentado [aquí](https://docs.aws.amazon.com/glue/latest/dg/monitor-spark-ui-jobs.html): 512 MB y 2 GB para los registros sucesivos.
+ **Recomendaciones de código:** solo se admite para las cargas de trabajo Amazon EMR-EC2 y AWS Glue para cargas de trabajo PySpark 
+ **Recursos regionales:** el agente de solución de problemas de Spark es regional y utiliza los recursos de EMR subyacentes de esa región para el proceso de solución de problemas. No se admite la solución de problemas entre regiones.

# Solución de problemas y preguntas y respuestas
<a name="spark-troubleshooting-agent-troubleshooting"></a>

## Resolución de problemas
<a name="spark-troubleshooting-common-issues"></a>

El mensaje de error del agente de solución de problemas de Spark está disponible de diferentes maneras para los distintos clientes de MCP. En esta página, enumeramos una guía general sobre los problemas más comunes que pueden aparecer al utilizar el agente de solución de problemas de Apache Spark para Amazon EMR.

Temas
+ [Error: el servidor MCP no se pudo cargar](#mcp-server-failed-to-load)
+ [Observación: carga lenta de la herramienta](#slow-tool-loading)
+ [Error: la invocación de la herramienta falló debido a un error de aceleración](#throttling-error)
+ [Error: la herramienta responde con un error de usuario](#user-error)
+ [Error: la herramienta responde con un error interno](#internal-error)

### Error: el servidor MCP no se pudo cargar
<a name="mcp-server-failed-to-load"></a>
+ Compruebe que las configuraciones de MCP estén configuradas correctamente.
+ **Valide la sintaxis JSON**:
  + Asegúrese de que su JSON sea válido sin errores de sintaxis
  + Comprueba si faltan comas, comillas o corchetes
+ Compruebe sus AWS credenciales locales y compruebe que la política del rol de IAM de MCP esté configurada correctamente.
+ Ejecute /mcp para comprobar la disponibilidad del servidor MCP, por si acaso `Kiro-CLI`

### Observación: carga lenta de la herramienta
<a name="slow-tool-loading"></a>
+ Las herramientas pueden tardar unos segundos en cargarse la primera vez que se inicie el servidor.
+ Si las herramientas no aparecen, intenta reiniciar el chat.
+ Ejecute `/tools` el comando para verificar la disponibilidad de la herramienta.
+ Ejecute `/mcp` si el servidor se inicia sin errores.

### Error: la invocación de la herramienta falló debido a un error de aceleración
<a name="throttling-error"></a>
+ Si ha alcanzado el límite de servicio, espere unos segundos para ejecutar una invocación a la herramienta si aparece la excepción de limitación.

### Error: la herramienta responde con un error de usuario
<a name="user-error"></a>
+ AccessDeniedException - compruebe el mensaje de error y solucione el problema de los permisos.
+ InvalidInputException - compruebe el mensaje de error y corrija los parámetros de entrada de la herramienta.
+ ResourceNotFoundException - compruebe el mensaje de error y corrija el parámetro de entrada como referencia del recurso.

### Error: la herramienta responde con un error interno
<a name="internal-error"></a>
+ Si lo ve`The service is handling high-volume requests`, vuelva a intentar invocar la herramienta en unos segundos.
+ Si aparece, documenta el identificador del análisis, el nombre de la herramienta, cualquier mensaje de error disponible en el registro del mcp o la respuesta de la herramienta y, si lo deseas, el historial de conversaciones saneado, y `INTERNAL SERVICE EXCEPTION` ponte en contacto con el servicio de asistencia. AWS 

## Preguntas y respuestas
<a name="spark-troubleshooting-qa"></a>

### 1. ¿Debo habilitar la configuración de «confianza» para las herramientas de forma predeterminada?
<a name="qa-trust-setting"></a>

Al principio, no active la configuración de «confianza» de forma predeterminada para todas las llamadas a las herramientas y utilice un entorno de compilación versionado para git cuando acepte recomendaciones de código. Revisa la ejecución de cada herramienta para entender qué cambios se están realizando.

### 2. ¿Cuáles son los ejemplos más comunes de instrucciones para aprovechar las herramientas de solución de problemas?
<a name="qa-example-prompts"></a>

Consulte los ejemplos de [Ejemplos rápidos](spark-troubleshooting-agent-prompt-examples.md) instrucciones sobre cómo aprovechar las herramientas de solución de problemas.

### 3. ¿Qué datos se transmiten al LLM y cómo se gestionan?
<a name="qa-data-transmitted-to-llm"></a>

Los datos y archivos de los clientes permanecen en AWS la región elegida y no se transmiten entre regiones. Cuando el agente opera en una región que utiliza la inferencia global entre regiones de Amazon Bedrock, el servicio puede dirigir las solicitudes a la región más cercana con capacidad disponible en función de la demanda. En esos casos, solo se transmiten los metadatos extraídos de los registros de los clientes y los resultados de las inferencias procesados, no los datos o archivos subyacentes de los clientes. Todos los datos se enmascaran con la PII antes de enviarlos al LLM para su procesamiento, tanto si la inferencia se produce dentro de la misma región como si se envía a otra región. Para obtener más información sobre cómo funciona la inferencia entre regiones y qué regiones se ven afectadas, consulte. [Procesamiento entre regiones para el agente de solución de problemas de Apache Spark](spark-troubleshooting-cross-region-processing.md)

# El flujo de trabajo del agente de solución de problemas de Spark
<a name="spark-troubleshooting-agent-workflow"></a>

Para iniciar el proceso de solución de problemas, necesitarás acceder a los identificadores de la aplicación Spark defectuosa que se ejecutan en plataformas compatibles (EMR-EC2, EMR Serverless, AWS Glue o Amazon Data Notebooks). SageMaker La aplicación debe tener registros accesibles, un servidor de historial de Spark y detalles de configuración. Asegúrese de tener los permisos necesarios para acceder a los recursos de la plataforma y a los metadatos de la aplicación. Una vez establecidos estos requisitos, puede enviar un mensaje como el siguiente para iniciar el flujo de trabajo de solución de problemas:

```
Analyze my EMR step execution failure, EMR id <step-id> with cluster id <cluster-id>
```

En este punto, el agente organizará la solución de problemas mediante herramientas especializadas. El flujo de trabajo sigue estos pasos:

1. **Extracción de funciones y creación de contexto**: el agente recopila y analiza automáticamente los datos de telemetría de tu aplicación Spark, incluidos los registros del History Server, los ajustes de configuración y las trazas de errores. Verás que la herramienta recopila información sobre las métricas de rendimiento, los patrones de uso de los recursos y las firmas de fallos.

1. **Análisis e identificación de la causa raíz**: el agente aprovecha los modelos de IA y la base de conocimientos de Spark para correlacionar las funciones extraídas e identificar las causas fundamentales de los problemas o fallos de rendimiento. Recibirás:
   + **Información sobre el análisis**: detalles técnicos sobre lo que el agente descubrió y analizó.
   + **Causa raíz**: explicación clara de lo que salió mal y por qué.
   + **Evaluación inicial**: ya sea que el problema esté relacionado con el código, la configuración o los recursos, se proporcionarán algunas directrices y análisis generales para mitigarlo.

1. **Recomendaciones de código** (si corresponde): si el análisis identifica problemas relacionados con el código en función de la clasificación de errores, el agente puede sugerirle que utilice la herramienta de recomendación de código para ofrecer recomendaciones específicas con el fin de implementar la corrección de código recomendada con el código exacto y sugerencias de reemplazo. before/after 

El proceso de solución de problemas es iterativo: puedes continuar la conversación para profundizar en problemas específicos. También puedes usar las herramientas de forma interactiva en nuestro departamento local de desarrollo de código de Spark para corregir los errores de código o mejorar tu código de forma continua.

# Ejemplos rápidos
<a name="spark-troubleshooting-agent-prompt-examples"></a>

Esta es una lista de ejemplos de mensajes rápidos que se pueden utilizar en la experiencia de solución de problemas.

## 1. Solucione el error de ejecución de un trabajo de Spark
<a name="troubleshoot-job-failure"></a>

Solución de problemas de EMR en EC2:

```
Troubleshoot my EMR-EC2 step with id s-xxxxxxxxxxxx on cluster j-xxxxxxxxxxxxx
```

Solución de problemas de Glue Job:

```
Troubleshoot my Glue job with job run id jr_xxxxxxxxxxxxxxxxxxxxxxxxxxxx and job name test_job
```

Solución de problemas de EMR Serverless:

```
Troubleshoot my EMR-Serverless job run with application id 00xxxxxxxx and job run id 00xxxxxxxx
```

## 2. Solicitud de recomendación de corrección de código
<a name="request-code-fix"></a>

Solicite una recomendación de corrección de código para EMR en un trabajo de EC2:

```
Recommend code fix for my EMR-EC2 step with id s-STEP_ID on cluster j-CLUSTER_ID
```

Solicite una recomendación de corrección de código para el trabajo de Glue:

```
Recommend code fix for my Glue job with job run id jr_JOB_RUN_ID and job name test_job
```

# Configuración de roles de IAM
<a name="spark-troubleshooting-agent-iam-setup"></a>

La CloudFormation pila de instrucciones de configuración automatiza la configuración de los roles de IAM por usted. Si desea ejecutarlo manualmente, siga las instrucciones que aparecen a continuación:

## Configuración del rol de IAM para el servidor MCP
<a name="iam-role-mcp-server"></a>

Para acceder al servidor MCP gestionado por SMUS, se requiere un rol de IAM con la siguiente política en línea:

```
{
    "Version": "2012-10-17",		 	 	 
    "Statement": [
        {
            "Sid": "AllowUseSagemakerUnifiedStudioMcpServer",
            "Effect": "Allow",
            "Action": [
                "sagemaker-unified-studio-mcp:InvokeMcp",
                "sagemaker-unified-studio-mcp:CallReadOnlyTool",
                "sagemaker-unified-studio-mcp:CallPrivilegedTool"
            ],
            "Resource": [
                "*"
            ]
        }
    ]
}
```

En los siguientes pasos, crearemos un perfil para este rol. La cuenta que asuma este rol para obtener las credenciales debe agregarse a la política de asumir el rol.

```
{
  "Version": "2012-10-17",		 	 	 
  "Statement": [
    {
      "Sid": "AllowAccountToAssumeRole",
      "Effect": "Allow",
      "Principal": { "AWS": "arn:aws:iam::<accountId>:root" },
      "Action": "sts:AssumeRole"
    }
  ]
}
```

## Permisos adicionales por modo de implementación (EMR-EC2/EMR-S/Glue)
<a name="additional-permissions"></a>

### Aplicaciones EMR-EC2
<a name="emr-ec2-permissions"></a>

```
{
    "Version": "2012-10-17",		 	 	 
    "Statement": [
        {
            "Sid": "EMREC2ReadAccess",
            "Effect": "Allow",
            "Action": [
                "elasticmapreduce:DescribeCluster",
                "elasticmapreduce:DescribeStep",
                "elasticmapreduce:ListSteps",
                "elasticmapreduce:ListClusters",
                "elasticmapreduce:DescribeJobFlows"
            ],
            "Resource": [
                "*"
            ]
        },
        {
            "Sid": "EMRS3LogAccess",
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:ListBucket"
            ],
            "Resource": "*"
        },
        {
            "Sid": "EMRPersistentApp",
            "Effect": "Allow",
            "Action": [
                "elasticmapreduce:CreatePersistentAppUI",
                "elasticmapreduce:DescribePersistentAppUI",
                "elasticmapreduce:GetPersistentAppUIPresignedURL"
            ],
            "Resource": [
                "*"
            ]
        }
    ]
}
```

### Trabajos de Glue
<a name="glue-permissions"></a>

```
{
    "Version": "2012-10-17",		 	 	 
    "Statement": [
        {
            "Sid": "GlueReadAccess",
            "Effect": "Allow",
            "Action": [
                "glue:GetJob",
                "glue:GetJobRun",
                "glue:GetJobRuns",
                "glue:GetJobs",
                "glue:BatchGetJobs"
            ],
            "Resource": [
                "arn:aws:glue:*:<account id>:job/*"
            ]
        },
        {
            "Sid": "GlueCloudWatchLogsAccess",
            "Effect": "Allow",
            "Action": [
                "logs:GetLogEvents",
                "logs:FilterLogEvents"
            ],
            "Resource": [
                "arn:aws:logs:*:<account id>:log-group:/aws/glue/*"
            ]
        },
        {
            "Sid": "GlueSparkWebUI",
            "Effect": "Allow",
            "Action": [
                "glue:RequestLogParsing",
                "glue:GetLogParsingStatus",
                "glue:GetEnvironment",
                "glue:GetStage",
                "glue:GetStages",
                "glue:GetStageFiles",
                "glue:BatchGetStageFiles",
                "glue:GetStageAttempt",
                "glue:GetStageAttemptTaskList",
                "glue:GetStageAttemptTaskSummary",
                "glue:GetExecutors",
                "glue:GetExecutorsThreads",
                "glue:GetStorage",
                "glue:GetStorageUnit",
                "glue:GetQueries",
                "glue:GetQuery",
                "glue:GetDashboardUrl"
            ],
            "Resource": [
                "arn:aws:glue:*:<account id>:job/*"
            ]
        },
        {
            "Sid": "GluePassRoleAccess",
            "Effect": "Allow",
            "Action": "iam:PassRole",
            "Resource": "*",
            "Condition": {
                "StringLike": {
                    "iam:PassedToService": "glue.amazonaws.com"
                }
            }
        }
    ]
}
```

### Aplicaciones EMR sin servidor
<a name="emr-serverless-permissions"></a>

```
{
    "Version": "2012-10-17",		 	 	 
    "Statement": [
        {
            "Sid": "EMRServerlessReadAccess",
            "Effect": "Allow",
            "Action": [
                "emr-serverless:GetJobRun",
                "emr-serverless:GetApplication",
                "emr-serverless:ListApplications",
                "emr-serverless:ListJobRuns",
                "emr-serverless:ListJobRunAttempts",
                "emr-serverless:GetDashboardForJobRun",
                "emr-serverless:ListTagsForResource"
            ],
            "Resource": [
                "*"
            ]
        },
        {
            "Sid": "EMRServerlessCloudWatchLogsAccess",
            "Effect": "Allow",
            "Action": [
                "logs:GetLogEvents",
                "logs:FilterLogEvents"
            ],
            "Resource": [
                "arn:aws:logs:*:<account id>:log-group:/aws/emr-serverless/*"
            ]
        },
        {
            "Sid": "EMRServerlessS3LogsAccess",
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:ListBucket"
            ],
            "Resource": "*"
        }
    ]
}
```

### Permisos de KMS: registros CloudWatch
<a name="kms-permissions"></a>

Si los CloudWatch registros están cifrados con una CMK, agregue la siguiente política para que el servicio pueda leer los registros de las aplicaciones sin servidor de EMR.

```
{
    "Effect": "Allow",
    "Action": [
        "kms:Decrypt",
        "kms:DescribeKey"
    ],
    "Resource": "arn:aws:kms:<region>:<account-id>:key/<cw-logs-cmk-id>"
}
```

# Uso de las herramientas de solución de problemas de
<a name="spark-troubleshooting-agent-using-tools"></a>

## Herramientas de solución de problemas disponibles
<a name="available-tools"></a>

El servicio MCP proporciona diferentes herramientas para el agente de solución de problemas de Spark. Las principales herramientas son las siguientes:


| Nombre de la herramienta | Categoría de herramienta | Description (Descripción) | 
| --- | --- | --- | 
| analyze\$1spark\$1workload | Análisis de la causa raíz | Proporciona una solución detallada de problemas para las cargas de trabajo fallidas de Apache Spark | 
| spark\$1code\$1recommendation | Recomendación de corrección de código | Proporciona recomendaciones de código de Apache Spark para trabajos fallidos | 

# Configuración de puntos de enlace de VPC de interfaz para Amazon Unified Studio MCP SageMaker
<a name="spark-troubleshooting-agent-vpc-endpoints"></a>

Puede establecer una conexión privada entre su VPC y el servicio MCP de Amazon SageMaker Unified Studio mediante la creación de un punto de enlace de *VPC* de interfaz. Los puntos de enlace de la interfaz funcionan con [Amazon VPC](https://aws.amazon.com/vpc/), lo que le permite acceder de forma privada al servidor MCP de su VPC sin necesidad de una puerta de enlace a Internet, un dispositivo NAT, una conexión VPN o una conexión. Las instancias de su VPC no necesitan direcciones IP públicas para comunicarse con el servicio MCP y el tráfico entre su VPC y el servicio MCP no sale de la red de Amazon.

Cada punto final de la interfaz está representado por una o más [interfaces de red elásticas en las](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-eni.html) subredes de la VPC. Para obtener más información, consulte los [puntos de conexión de VPC de interfaz en la Guía](https://docs.aws.amazon.com/vpc/latest/userguide/vpce-interface.html) del usuario de Amazon *VPC*.

## Paso 1: Crear un punto de enlace de VPC de interfaz para Amazon SageMaker Unified Studio MCP
<a name="create-vpc-endpoint"></a>

Puede crear un punto de enlace de VPC para el servicio MCP de Amazon SageMaker Unified Studio mediante la consola de Amazon VPC o la. AWS CLI Para obtener más información, consulte [Creación de un punto de conexión de interfaz](https://docs.aws.amazon.com/vpc/latest/userguide/vpce-interface.html#create-interface-endpoint) en la *Guía del usuario de Amazon VPC*.

Cree un punto de enlace de VPC para Amazon SageMaker Unified Studio MCP con el siguiente nombre de servicio:
+ com.amazonaws. *<aws-region>*. sagemaker-unified-studio-mcp

Si habilita el DNS privado para el punto final, puede realizar solicitudes de API a Amazon SageMaker Unified Studio MCP utilizando su nombre de DNS predeterminado para la región, por ejemplo, `sagemaker-unified-studio-mcp.us-east-1.api.aws`

Para más información, consulte [Acceso a un servicio a través de un punto de conexión de interfaz](https://docs.aws.amazon.com/vpc/latest/userguide/vpce-interface.html#access-service-though-endpoint) en la *Guía del usuario de Amazon VPC*.

## Paso 2: Crear una política de puntos de conexión de VPC para Amazon SageMaker Unified Studio MCP
<a name="create-vpc-endpoint-policy"></a>

Puede adjuntar una política de punto final a su punto de enlace de VPC que controle el acceso al MCP de Amazon SageMaker Unified Studio. La política especifica la siguiente información:
+ La entidad principal que puede realizar acciones.
+ Las acciones que se pueden realizar.
+ Los recursos en los que se pueden llevar a cabo las acciones.

Para más información, consulte [Control del acceso a los servicios con puntos de enlace de la VPC](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-endpoints-access.html) en la *Guía del usuario de Amazon VPC*.

### Ejemplo: política de punto final de VPC para permitir el acceso del MCP a un rol de IAM específico
<a name="vpc-endpoint-policy-example"></a>

El siguiente es un ejemplo de una política de puntos de conexión para el acceso al MCP de Amazon SageMaker Unified Studio. Cuando se adjunta a un punto final, esta política otorga acceso a las acciones de MCP de Amazon SageMaker Unified Studio enumeradas para un rol principal de IAM específico en todos los recursos.

```
{
  "Version": "2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::ACCOUNT-ID:role/YourRoleName"
      },
      "Action": [
        "sagemaker-unified-studio-mcp:InvokeMcp",
        "sagemaker-unified-studio-mcp:CallReadOnlyTool",
        "sagemaker-unified-studio-mcp:CallPrivilegedTool"
      ],
      "Resource": "*"
    }
  ]
}
```

## Paso 3: Probar su VPC
<a name="test-vpc-endpoint"></a>

El `curl` comando valida la conectividad de end-to-end red desde la red de VPC (EC2) al punto final de la VPC mediante una solicitud. HTTP/HTTPS Una respuesta curl al recibir un mensaje del servidor MCP confirma que la ruta de red completa funciona.

### Método 1: con el DNS privado activado (recomendado)
<a name="test-private-dns-enabled"></a>

```
curl https://sagemaker-unified-studio-mcp.us-east-1.api.aws/spark-troubleshooting/mcp
```

### Método 2: sin el DNS privado habilitado
<a name="test-private-dns-disabled"></a>

```
curl -k https://vpce-0069xxxx-ejwhxxx.sagemaker-unified-studio-mcp.us-east-1.vpce.amazonaws.com/spark-troubleshooting/mcp
```

**nota**  
El `-k` indicador omite la verificación del certificado SSL debido a la falta de coincidencia del nombre de host entre el nombre DNS del punto final de la VPC y el nombre común (CN) del certificado.

En ambos casos, el comando curl devuelve una respuesta:. `{"Message":"...."}` Al volver con un mensaje, se comprueba que la conectividad de la ruta de red con el punto final de la VPC del servicio MCP es correcta.

## Paso 4: Comience a usar el punto final de VPC MCP
<a name="use-vpc-endpoint"></a>

Una vez que haya verificado la conexión, puede seguir los pasos para configurar el MCP in. [Configuración del agente de solución de problemas](spark-troubleshooting-agent-setup.md) Solo tiene que utilizar el punto de conexión de VPC privado en su configuración de MCP.

# Procesamiento entre regiones para el agente de solución de problemas de Apache Spark
<a name="spark-troubleshooting-cross-region-processing"></a>

El agente de solución de problemas de Apache Spark utiliza la inferencia entre regiones para procesar las solicitudes en lenguaje natural y generar respuestas. Con la inferencia entre regiones, el agente enruta automáticamente la solicitud de inferencia para optimizar el rendimiento, maximizar los recursos informáticos disponibles y la disponibilidad del modelo, y ofrecer la mejor experiencia al cliente. El tipo de inferencia entre regiones que se utilice depende de la región en la que se ejecute el agente de solución de problemas de Apache Spark. En la mayoría de las regiones, el agente selecciona la región óptima dentro de su zona geográfica para procesar sus solicitudes de inferencia. Sin embargo, en algunas regiones, una solicitud de inferencia realizada por el agente se envía de forma segura a todos los recursos informáticos disponibles en todas las regiones comerciales del mundo. AWS 

## Inferencia entre regiones
<a name="cross-region-inference-overview"></a>

El agente de solución de problemas de Apache Spark funciona con Amazon Bedrock y utiliza la inferencia entre regiones para distribuir el tráfico entre distintas AWS regiones a fin de mejorar el rendimiento y la fiabilidad de las inferencias del modelo de lenguaje grande (LLM).

Si bien las inferencias entre regiones no cambian el lugar en el que se alojan la aplicación Spark, la experiencia de resolución de problemas o el lugar en el que se almacenan los datos, es posible que las solicitudes de entrada y los resultados de salida se transmitan a distintas regiones para su procesamiento. Todos los datos se transmiten cifrados a través de la red segura de Amazon.

El uso de la inferencia entre regiones no conlleva ningún coste adicional.

## Regiones compatibles para la inferencia entre regiones
<a name="supported-regions-cross-region"></a>

 **Regiones que utilizan la inferencia geográfica entre regiones** 

En la mayoría de las regiones, las solicitudes de inferencia entre regiones se guardan en AWS las regiones que forman parte de la misma zona geográfica en la que se ejecuta el agente de solución de problemas de Apache Spark. Por ejemplo, una solicitud realizada por el agente en la región EE.UU. Este (Norte de Virginia) se envía únicamente a AWS las regiones dentro de la geografía de los Estados Unidos. En la siguiente tabla se describen las regiones a las que se pueden dirigir sus solicitudes en función de la zona geográfica en la que se originaron:


| Geografía compatible | Regiones de inferencia | 
| --- | --- | 
|  Estados Unidos  |  EE.UU. Este (Norte de Virginia) (us-East-1), EE.UU. Oeste (Oregón) (us-west-2), EE.UU. Este (Ohio) (us-East-2), EE.UU. Oeste (Norte de California) (us-west-1)  | 
|  Europa  |  Europa (Fráncfort) (eu-central-1), Europa (Irlanda) (eu-west-1), Europa (París) (eu-west-3), Europa (Estocolmo) (eu-north-1), Europa (Londres) (eu-west-2)  | 
|  Asia Pacífico  |  Asia Pacífico (Tokio) (ap-northeast-1), Asia Pacífico (Seúl) (ap-northeast-2), Asia Pacífico (Mumbai) (ap-south-1)  | 

### Regiones que utilizan la inferencia global entre regiones
<a name="global-cross-region-inference"></a>

**importante**  
Las siguientes AWS regiones utilizan la inferencia global entre regiones. Si utilizas el agente de solución de problemas de Apache Spark en estas regiones, es posible que tus solicitudes se transmitan de todo el mundo a otras AWS regiones para su procesamiento de inferencias a fin de optimizar el rendimiento y la disponibilidad:  
América del Sur (São Paulo) (sa-east-1)
Asia-Pacífico (Singapur) (ap-southeast-1)
Asia-Pacífico (Sídney) (ap-southeast-2)
Canadá (centro) (ca-central-1)

# Registro de llamadas MCP de Amazon SageMaker Unified Studio mediante AWS CloudTrail
<a name="spark-troubleshooting-cloudtrail-integration"></a>

El servidor MCP de Amazon SageMaker Unified Studio está integrado con AWS CloudTrail un servicio que proporciona un registro de las acciones realizadas por un usuario, un rol o un AWS servicio en el servidor MCP de Amazon SageMaker Unified Studio. CloudTrail captura todas las llamadas a la API del servidor MCP de Amazon SageMaker Unified Studio como eventos. Las llamadas capturadas incluyen llamadas al servidor MCP de Amazon SageMaker Unified Studio y llamadas de código a otras AWS operaciones durante la ejecución de la herramienta desde el servidor MCP de SageMaker Unified Studio. Si crea una ruta, puede habilitar la entrega continua de CloudTrail eventos a un bucket de Amazon S3, incluidos los eventos para el servidor MCP de Amazon SageMaker Unified Studio. Si no configura una ruta, podrá ver los eventos más recientes en la CloudTrail consola, en el **historial** de eventos. Con la información recopilada por CloudTrail, puede determinar la solicitud que se realizó al servidor MCP de Amazon SageMaker Unified Studio, la dirección IP desde la que se realizó la solicitud, quién la realizó, cuándo se realizó y detalles adicionales.

Para obtener más información CloudTrail, consulte la [Guía del AWS CloudTrail usuario](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/).

## Información sobre el servidor MCP de Amazon SageMaker Unified Studio en CloudTrail
<a name="sagemaker-mcp-info-in-cloudtrail"></a>

CloudTrail está activado en su AWS cuenta al crear la cuenta. Cuando se produce una actividad en el servidor MCP de Amazon SageMaker Unified Studio, esa actividad se registra en un CloudTrail evento junto con otros eventos de AWS servicio en el **historial** de eventos. Puede ver, buscar y descargar los eventos recientes en su AWS cuenta. Para obtener más información, consulte [Visualización de eventos con el historial de CloudTrail eventos](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/view-cloudtrail-events.html).

Para obtener un registro continuo de los eventos de su AWS cuenta, incluidos los eventos del servidor MCP de SageMaker Unified Studio, cree un registro. Un rastro permite CloudTrail entregar archivos de registro a un bucket de Amazon S3. De forma predeterminada, cuando crea una ruta en la consola, la ruta se aplica a todas AWS las regiones. La ruta registra los eventos de todas las regiones de la AWS partición y envía los archivos de registro al bucket de Amazon S3 que especifique. Además, puede configurar otros AWS servicios para analizar más a fondo los datos de eventos recopilados en los CloudTrail registros y actuar en función de ellos. Para más información, consulte los siguientes temas:
+ [Introducción a la creación de registros de seguimiento](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-create-and-update-a-trail.html)
+ [CloudTrail servicios e integraciones compatibles](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-aws-service-specific-topics.html)
+ [Configuración de las notificaciones de Amazon SNS para CloudTrail](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/configure-sns-notifications-for-cloudtrail.html)
+ [Recibir archivos de CloudTrail registro de varias regiones](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html) y [recibir archivos de CloudTrail registro de varias cuentas](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-receive-logs-from-multiple-accounts.html)

Todas las invocaciones a las herramientas del servidor MCP de SageMaker Unified Studio y las llamadas a la API a AWS los servicios durante la ejecución de la herramienta quedan registradas por. CloudTrail Por ejemplo, las llamadas a las distintas herramientas y las llamadas de AWS servicio realizadas desde las herramientas generan entradas en los archivos de CloudTrail registro.

Cada entrada de registro o evento contiene información sobre quién generó la solicitud. La información de identidad del usuario lo ayuda a determinar lo siguiente:
+ Si la solicitud se realizó con las credenciales raíz o del usuario de IAM.
+ Si la solicitud se realizó con credenciales de seguridad temporales de un rol o fue un usuario federado.
+ Si la solicitud la realizó otro AWS servicio.

Para obtener más información, consulte el [elemento userIdentity de CloudTrail ](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-event-reference-user-identity.html).

## Descripción de las entradas de los archivos de registro del servidor MCP de Amazon SageMaker Unified Studio
<a name="understanding-mcp-log-entries"></a>

Un rastro es una configuración que permite la entrega de eventos como archivos de registro a un bucket de Amazon S3 que usted especifique. CloudTrail Los archivos de registro contienen una o más entradas de registro. Un evento representa una solicitud única de cualquier fuente e incluye información sobre la acción solicitada, la fecha y la hora de la acción, los parámetros de la solicitud, etc. CloudTrail Los archivos de registro no son un registro ordenado de las llamadas a la API pública, por lo que no aparecen en ningún orden específico.

En el siguiente ejemplo, se muestra una entrada de CloudTrail registro que demuestra la `CallTool` acción.

```
{
    "eventVersion": "1.09",
    "userIdentity": {
        ...
    },
    "eventTime": "...",
    "eventSource": "sagemaker-unified-studio-mcp.amazonaws.com",
    "eventName": "CallPrivilegedTool",
    "awsRegion": "us-east-1",
    "sourceIPAddress": "...",
    "userAgent": "...",
    "requestParameters": {
        "id": 1,
        "method": "tools/call",
        "params": {
            "name": "generate_spark_upgrade_plan",
            "arguments": "***",
            "_meta": {
                "progressToken": 1
            }
        },
        "jsonrpc": "2.0"
    },
    "responseElements": {
        "result": {
            "content": "***",
            "structuredContent": "***",
            "isError": false
        },
        "id": 1,
        "jsonrpc": "2.0"
    },
    "requestID": "12345678-1234-1234-1234-123456789012",
    "eventID": "87654321-4321-4321-4321-210987654321",
    "readOnly": false,
    "eventType": "AwsMcpEvent",
    "managementEvent": true,
    "recipientAccountId": "123456789012",
    "eventCategory": "Management"
}
```

El siguiente ejemplo muestra una entrada de CloudTrail registro que demuestra la `AddJobFlowSteps` acción del MCP de Amazon SageMaker Unified Studio durante la invocación de una herramienta de actualización.

```
{
    "eventVersion": "1.11",
    "userIdentity": {
        "type": "AssumedRole",
        "principalId": "...",
        "arn": "...",
        "accountId": "123456789012",
        "accessKeyId": "...",
        "sessionContext": {
            ...
        },
        "invokedBy": "sagemaker-unified-studio-mcp.amazonaws.com"
    },
    "eventTime": "...",
    "eventSource": "elasticmapreduce.amazonaws.com",
    "eventName": "AddJobFlowSteps",
    "awsRegion": "us-east-1",
    "sourceIPAddress": "sagemaker-unified-studio-mcp.amazonaws.com",
    "userAgent": "sagemaker-unified-studio-mcp.amazonaws.com",
    "requestParameters": {
        "jobFlowId": "j-2PY4KXXXXXX63",
        "steps": [
            ...
        ]
    },
    "responseElements": {
        "stepIds": [
            ...
        ]
    },
    "requestID": "12345678-1234-1234-1234-123456789013",
    "eventID": "87654321-4321-4321-4321-210987654322",
    "readOnly": false,
    "eventType": "AwsApiCall",
    "managementEvent": true,
    "recipientAccountId": "123456789012",
    "sharedEventID": "12345678-1234-1234-1234-123456789012",
    "vpcEndpointId": "sagemaker-unified-studio-mcp.amazonaws.com",
    "vpcEndpointAccountId": "sagemaker-unified-studio-mcp.amazonaws.com",
    "eventCategory": "Management"
}
```

# Mejoras en el servicio para los agentes de Apache Spark
<a name="spark-agents-service-improvements"></a>

El agente de Apache Spark para Amazon EMR puede utilizar el contenido, por ejemplo, para ayudar al agente a dar mejores respuestas a preguntas frecuentes, solucionar problemas operativos o realizar tareas de depuración.

## Contenido que AWS puede utilizarse para mejorar el servicio
<a name="content-used-for-improvement"></a>
+ Sus solicitudes en lenguaje natural y respuestas generadas por los agentes de Apache Spark para Amazon EMR, AWS Glue y Amazon Notebooks SageMaker 

## Contenido que AWS no se utiliza para mejorar el servicio
<a name="content-not-used-for-improvement"></a>
+ Código que escribes tú mismo para las aplicaciones de Spark
+ SageMaker Contexto y metadatos del cuaderno
+ Datos del catálogo de datos de AWS Glue u otras fuentes de datos

Solo los empleados de Amazon tendrán acceso a los datos. Su confianza, la privacidad y la seguridad del contenido de los clientes son nuestra máxima prioridad y garantizamos que nuestro uso cumpla con nuestros compromisos con usted. Para obtener más información, consulte Preguntas frecuentes sobre la privacidad de datos de .

## ¿Cómo excluirse
<a name="how-to-opt-out"></a>

Para excluirse de la recopilación de datos para los agentes de Apache Spark, configure una política de exclusión de los servicios de IA en AWS Organizations for Amazon SageMaker Unified Studio MCP Service. Para obtener más información, consulte [Políticas de exclusión de los servicios de IA](https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_policies_ai-opt-out.html) en la *Guía del usuario de AWS Organizations*.

Al configurar una política de exclusión de los servicios de IA, tiene los siguientes efectos:
+ AWS eliminará los datos que recopiló y almacenó para mejorar el servicio antes de excluirse (si los hubiera).
+ Una vez que opte por no participar, ya no AWS recopilará ni almacenará estos datos.
+ AWS ya no utilizará su contenido para mejorar el servicio.

# Optimización del desempeño de Spark
<a name="emr-spark-performance"></a>

Amazon EMR proporciona múltiples características de optimización del rendimiento para Spark. En este tema se explica cada característica de optimización en detalle.

Para obtener más información acerca de cómo definir la configuración de Spark, consulte [Configurar Spark](emr-spark-configure.md).

## Ejecución de consultas adaptativas
<a name="emr-spark-performance-aqe"></a>

La ejecución de consultas adaptativas es un marco para reoptimizar los planes de consultas en función de las estadísticas del tiempo de ejecución. A partir de Amazon EMR 5.30.0, las siguientes optimizaciones de ejecución de consultas adaptativas de Apache Spark 3 están disponibles en el tiempo de ejecución de Apache Amazon EMR para Spark 2.
+ Conversión de unión adaptativa
+ Fusión adaptativa de particiones aleatorias

**Conversión de unión adaptativa**

La conversión por combinación adaptativa mejora el rendimiento de las consultas al convertir sort-merge-join las operaciones en broadcast-hash-joins operaciones basadas en el tamaño del tiempo de ejecución de las etapas de la consulta. Broadcast-hash-joinstienden a funcionar mejor cuando un lado de la unión es lo suficientemente pequeño como para transmitir su salida de manera eficiente entre todos los ejecutores, lo que evita la necesidad de mezclar el intercambio y ordenar ambos lados de la combinación. La conversión adaptativa de uniones amplía la gama de casos en los que Spark funciona automáticamente. broadcast-hash-joins

Esta característica está habilitada de forma predeterminada. Para deshabilitarla, puede establecer `spark.sql.adaptive.enabled` en `false`, lo que también deshabilita el marco de ejecución de consultas adaptativas. Spark decide convertir a en sort-merge-join a broadcast-hash-join cuando la estadística del tamaño del tiempo de ejecución de uno de los lados de la unión no supera `spark.sql.autoBroadcastJoinThreshold` el valor predeterminado de 10.485.760 bytes (10 MiB).

**Fusión adaptativa de particiones aleatorias**

La fusión adaptativa de particiones aleatorias mejora el rendimiento de las consultas al fusionar pequeñas particiones aleatorias contiguas para evitar la sobrecarga que supone tener demasiadas tareas pequeñas. Esto le permite configurar un mayor número de particiones aleatorias iniciales por adelantado, que luego se reduce en tiempo de ejecución hasta el tamaño deseado, lo que aumenta las posibilidades de tener particiones aleatorias distribuidas de manera más uniforme.

Esta característica está habilitada de forma predeterminada a menos que `spark.sql.shuffle.partitions` se establezca de forma explícita. Para habilitarla, se puede establecer `spark.sql.adaptive.coalescePartitions.enabled` en `true`. Tanto el número inicial de particiones aleatorias como el tamaño de las particiones de destino se pueden ajustar con las propiedades `spark.sql.adaptive.coalescePartitions.minPartitionNum` y `spark.sql.adaptive.advisoryPartitionSizeInBytes`, respectivamente. Consulta la siguiente tabla para obtener más información sobre las propiedades de Spark relacionadas con esta característica.


**Propiedades de las particiones de la fusión adaptativa de Spark**  

| Propiedad | Predeterminado | Description (Descripción) | 
| --- | --- | --- | 
|  `spark.sql.adaptive.coalescePartitions.enabled`  |  true, a menos que `spark.sql.shuffle.partitions` se establezca de forma explícita  |  Si el valor es true y spark.sql.adaptive.enabled es true, Spark fusiona las particiones aleatorias contiguas según el tamaño de destino (especificado mediante `spark.sql.adaptive.advisoryPartitionSizeInBytes`) para evitar demasiadas tareas pequeñas.  | 
|  `spark.sql.adaptive.advisoryPartitionSizeInBytes`  | 64 MB |  Tamaño recomendado en bytes de la partición aleatoria al fusionarse. Esta configuración solo tiene efecto cuando `spark.sql.adaptive.enabled` y `spark.sql.adaptive.coalescePartitions.enabled` son `true`.  | 
|  `spark.sql.adaptive.coalescePartitions.minPartitionNum`  | 25 |  Número mínimo de particiones aleatorias después de la fusión. Esta configuración solo tiene efecto cuando `spark.sql.adaptive.enabled` y `spark.sql.adaptive.coalescePartitions.enabled` son `true`.  | 
|  `spark.sql.adaptive.coalescePartitions.initialPartitionNum`  | 1 000 |  Número inicial de particiones aleatorias antes de la fusión. Esta configuración solo tiene efecto cuando `spark.sql.adaptive.enabled` y `spark.sql.adaptive.coalescePartitions.enabled` son `true`.  | 

## Eliminación dinámica de particiones
<a name="emr-spark-performance-dynamic"></a>

La reducción dinámica de particiones mejora el rendimiento seleccionando con mayor precisión particiones específicas de una tabla que deben leerse y procesarse para una consulta específica. Al reducir la cantidad de datos leídos y procesados, se ahorra bastante tiempo en la ejecución de trabajos. Con Amazon EMR 5.26.0, esta característica está habilitada de forma predeterminada. Con Amazon EMR 5.24.0 y 5.25.0, puede establecer la propiedad `spark.sql.dynamicPartitionPruning.enabled` de Spark desde Spark o al crear clústeres para habilitar esta característica. 


**Propiedades de las particiones de la eliminación dinámica de particiones de Spark**  

| Propiedad | Valor predeterminado | Description (Descripción) | 
| --- | --- | --- | 
|  `spark.sql.dynamicPartitionPruning.enabled`  |  `true`  |  Si es true, habilite la eliminación dinámica de particiones.  | 
|  `spark.sql.optimizer.dynamicPartitionPruning.enforceBroadcastReuse`  |  `true`  |  Si es `true`, Spark realiza una comprobación preventiva antes de ejecutar las consultas para garantizar que la reutilización de los intercambios de transmisiones en filtros de eliminación dinámica no se vea afectada por reglas de preparación posteriores (como las reglas de columnas definidas por el usuario). Cuando la reutilización se ve afectada y esta configuración es `true`, Spark elimina los filtros de eliminación dinámica afectados para evitar problemas de rendimiento y corrección. Pueden surgir problemas de corrección cuando el intercambio de transmisión del filtro de eliminación dinámica ofrece resultados diferentes e incoherentes a partir del intercambio de transmisión de la operación de unión correspondiente. Definir esta configuración en `false` debe hacerse con precaución, ya que permite evitar situaciones como, por ejemplo, cuando la reutilización se ve afectada por reglas de columnas definidas por el usuario. Cuando la ejecución de consultas adaptativas está habilitada, siempre se aplica la reutilización de transmisiones.  | 

Esta optimización mejora las capacidades existentes de Spark 2.4.2, que solo admiten la postergación de predicados estáticos que se pueden resolver durante la planificación.

A continuación, se muestran ejemplos de postergación de predicados estáticos en Spark 2.4.2.

```
partition_col = 5

partition_col IN (1,3,5)

partition_col between 1 and 3

partition_col = 1 + 3
```

La reducción dinámica de particiones permite que el motor de Spark deduzca de forma dinámica durante el tiempo de ejecución qué particiones deben leerse y cuáles pueden eliminarse de forma segura. Por ejemplo, la siguiente consulta implica dos tablas: la tabla `store_sales` que contiene todas las ventas totales para todas las tiendas y se particiona por región y la tabla `store_regions` que contiene un mapeo de las regiones de cada país. Las tablas contienen datos sobre tiendas distribuidas por todo el mundo, pero solo realizan consultas en los datos de América del Norte.

```
select ss.quarter, ss.region, ss.store, ss.total_sales 
from store_sales ss, store_regions sr
where ss.region = sr.region and sr.country = 'North America'
```

Sin la reducción de particiones dinámicas, esta consulta leerá todas las regiones antes de filtrar el subconjunto de regiones que coinciden con los resultados de la subconsulta. Con la reducción dinámica de particiones, esta consulta leerá y procesará solo las particiones de las regiones que se devuelven en la subconsulta. Esto ahorra tiempo y recursos ya que lee menos datos del almacenamiento y procesa menos registros.

## Aplanamiento de subconsultas escalares
<a name="emr-spark-performance-flatten"></a>

Esta optimización mejora el rendimiento de las consultas que tienen subconsultas escalares a través de la misma tabla. Con Amazon EMR 5.26.0, esta característica está habilitada de forma predeterminada. Con Amazon EMR 5.24.0 y 5.25.0, puede establecer la propiedad `spark.sql.optimizer.flattenScalarSubqueriesWithAggregates.enabled` de Spark desde Spark o al crear clústeres para habilitarlo. Cuando esta propiedad se establece en true, el optimizador de consultas aplana subconsultas escalares de agregación que utilizan la misma relación en caso posible. Las consultas escalares se aplanan empujando cualquier predicado presente en la subconsulta en las funciones de agregación y, a continuación, realiza una agregación, con todas las funciones de agregación, por relación.

A continuación se presenta un ejemplo de una consulta que se beneficiará de esta optimización.

```
select (select avg(age) from students                    /* Subquery 1 */
                 where age between 5 and 10) as group1,
       (select avg(age) from students                    /* Subquery 2 */
                 where age between 10 and 15) as group2,
       (select avg(age) from students                    /* Subquery 3 */
                 where age between 15 and 20) as group3
```

La optimización vuelve a escribir la consulta anterior como:

```
select c1 as group1, c2 as group2, c3 as group3
from (select avg (if(age between 5 and 10, age, null)) as c1,
             avg (if(age between 10 and 15, age, null)) as c2,
             avg (if(age between 15 and 20, age, null)) as c3 from students);
```

Tenga en cuenta que la consulta reescrita lee la tabla solo una vez, y los predicados de las tres subconsultas se envían a la función `avg`.

## DISTINCT antes de INTERSECT
<a name="emr-spark-performance-distinct"></a>

Esta optimización optimiza uniones cuando se utiliza INTERSECT. Con Amazon EMR 5.26.0, esta característica está habilitada de forma predeterminada. Con Amazon EMR 5.24.0 y 5.25.0, puede establecer la propiedad `spark.sql.optimizer.distinctBeforeIntersect.enabled` de Spark desde Spark o al crear clústeres para habilitarlo. Las consultas con INTERSECT se convierten automáticamente para utilizar una semiunión pendiente. Cuando esta propiedad se establece en true, el optimizador de consultas coloca el operador DISTINCT en los elementos secundarios de INTERSECT si detecta que el operador DISTINCT puede hacer que el polo izquierdo se una a en lugar de a. BroadcastHashJoin SortMergeJoin

A continuación se presenta un ejemplo de una consulta que se beneficiará de esta optimización.

```
(select item.brand brand from store_sales, item
     where store_sales.item_id = item.item_id)
intersect
(select item.brand cs_brand from catalog_sales, item 
     where catalog_sales.item_id = item.item_id)
```

Sin habilitar esta propiedad `spark.sql.optimizer.distinctBeforeIntersect.enabled`, la consulta se reescribirá tal y como se indica a continuación.

```
select distinct brand from
  (select item.brand brand from store_sales, item
     where store_sales.item_id = item.item_id)
left semi join
   (select item.brand cs_brand from catalog_sales, item 
     where catalog_sales.item_id = item.item_id)
 on brand <=> cs_brand
```

Cuando se habilita esta propiedad `spark.sql.optimizer.distinctBeforeIntersect.enabled`, la consulta se reescribirá tal y como se indica a continuación.

```
select brand from
  (select distinct item.brand brand from store_sales, item
     where store_sales.item_id = item.item_id)
left semi join
   (select distinct item.brand cs_brand from catalog_sales, item 
     where catalog_sales.item_id = item.item_id)
 on brand <=> cs_brand
```

## Unión de filtros de Bloom
<a name="emr-spark-performance-bloom"></a>

Esta optimización puede mejorar el rendimiento de algunas uniones efectuando un filtrado previo de un lado de una unión mediante un [filtro de Bloom](https://en.wikipedia.org/wiki/Bloom_filter) generado a partir de los valores del otro lado de la unión. Con Amazon EMR 5.26.0, esta característica está habilitada de forma predeterminada. Con Amazon EMR 5.25.0, puede establecer la propiedad de Spark `spark.sql.bloomFilterJoin.enabled` en `true` desde Spark o al crear clústeres para habilitar esta característica.

A continuación se muestra un ejemplo de consulta que puede beneficiarse de un filtro de Bloom.

```
select count(*)
from sales, item
where sales.item_id = item.id
and item.category in (1, 10, 16)
```

Cuando esta característica está habilitada, el filtro de Bloom se crea a partir de todos los identificadores de elemento cuya categoría se encuentra en el conjunto de categorías que se están consultando. Durante el análisis de la tabla de ventas, el filtro de Bloom se utiliza para determinar qué ventas corresponden a artículos que definitivamente no están en el conjunto definido por el filtro de Bloom. De este modo, estas ventas identificadas pueden excluirse lo antes posible.

## Reordenación de unión optimizada
<a name="emr-spark-performance-join-reorder"></a>

Esta optimización puede mejorar el rendimiento de las consultas al reordenar las uniones en las que intervienen tablas con filtros. Con Amazon EMR 5.26.0, esta característica está habilitada de forma predeterminada. Con Amazon EMR 5.25.0, puede establecer el parámetro de configuración `spark.sql.optimizer.sizeBasedJoinReorder.enabled` de Spark en true para habilitar esta característica. El comportamiento predeterminado en Spark es unir las tablas de izquierda a derecha, como se indica en la consulta. Esta estrategia puede perder oportunidades para ejecutar primero uniones más pequeñas con filtros, con el fin de beneficiarse de uniones más costosas más tarde. 

La consulta de ejemplo que aparece a continuación informa de todos los artículos devueltos de todas las tiendas de un país. Sin la reordenación de unión optimizada, Spark une primero las dos tablas grandes `store_sales` y `store_returns`; a continuación, las une con `store` y, finalmente, con `item`.

```
select ss.item_value, sr.return_date, s.name, i.desc, 
from store_sales ss, store_returns sr, store s, item i
where ss.id = sr.id and ss.store_id = s.id and ss.item_id = i.id
and s.country = 'USA'
```

Con la reordenación de unión optimizada, Spark primero une `store_sales` con `store`, ya que `store` tiene un filtro y es más pequeño que `store_returns` y `broadcastable`. Luego Spark se une con `store_returns` y, finalmente, con `item`. Si `item` tuviera un filtro y se pudiera emitir, también se podría usar en la reordenación, lo que provocaría que `store_sales` se uniera con `store`, después con `item` y, finalmente, con `store_returns`.

# Almacenamiento en caché de fragmentos de resultados de Spark
<a name="emr-spark-fragment-result-caching"></a>

La versión 6.6.0 y posteriores de Amazon EMR incluyen la característica opcional Almacenamiento en caché de fragmentos de resultados de Spark, que almacena en caché automáticamente los fragmentos de resultados. Estos fragmentos de resultados forman parte de los resultados de subárboles de consultas que se almacenan en el bucket de Amazon S3 que elija. Los fragmentos de resultados de las consultas almacenados se reutilizan en las siguientes ejecuciones de consultas, lo que se traduce en consultas más rápidas.

El Almacenamiento en caché de fragmentos de resultados analiza las consultas de Spark y almacena en caché los fragmentos de resultados aptos en la ubicación de S3 que especifique. En las siguientes ejecuciones de consultas, los fragmentos de resultados de consultas que se pueden utilizar se detectan automáticamente y se recuperan de S3. El Almacenamiento en caché de fragmentos de resultados es diferente del almacenamiento en caché de conjuntos de resultados, en el que las consultas posteriores tienen que coincidir exactamente con la consulta original para obtener resultados de la caché. Cuando se utiliza para consultas que se dirigen repetidamente a un subconjunto estático de los datos, el Almacenamiento en caché de fragmentos de resultados acelera considerablemente el rendimiento.

Considere la siguiente consulta, que cuenta los pedidos hasta el año 2022:

```
select
    l_returnflag,
    l_linestatus,
    count(*) as count_order
from
    lineitem
where
    l_shipdate <= current_date
    and year(l_shipdate) == '2022'
group by
    l_returnflag,
    l_linestatus
```

A medida que pasa el tiempo, esta consulta debe ejecutarse todos los días para informar sobre las ventas totales del año. Sin el Almacenamiento en caché de fragmentos de resultados, los resultados de todos los días del año deberán volver a calcularse todos los días. La consulta se volverá más lenta con el tiempo y será más lenta al final del año, cuando sea necesario volver a calcular los 365 días de resultados.

 Al activar el Almacenamiento en caché de fragmentos de resultados, se utilizan los resultados de todos los días anteriores del año guardados en la caché. Cada día, la característica debe volver a calcular los resultados de un solo día. Una vez que la característica calcula el fragmento de resultados, lo almacena en caché. Como resultado, los tiempos de consultas con la caché habilitada son rápidos y constantes para cada consulta posterior. 

## Habilitación del Almacenamiento en caché de fragmentos de resultados de Spark
<a name="enable-fragment-caching"></a>

Para habilitar el Almacenamiento en caché de fragmentos de resultados de Spark, lleve a cabo los siguientes pasos:

1. Cree un depósito de caché en Amazon S3 y autorice el read/write acceso a EMRFS. Para obtener más información, consulte [Autorización de acceso a los datos de EMRFS en Amazon S3](emr-plan-credentialsprovider.md).

1. Establezca la configuración de Spark de Amazon EMR para habilitar la característica.

   ```
   spark.subResultCache.enabled = true
   spark.subResultCache.fs.root.path = s3://&example-s3-bucket;/cache_dir/
   ```

1. Habilite la administración del ciclo de vida de S3 para que el bucket limpie automáticamente los archivos de caché.

1. Si lo desea, configure las maxBufferSize propiedades reductionRationThreshold y para ajustar aún más la función.

   ```
   spark.sql.subResultCache.reductionRatioThreshold
   spark.sql.subResultCache.maxBufferSize
   ```

## Consideraciones al utilizar el Almacenamiento en caché de fragmentos de resultados
<a name="frag-caching-considerations"></a>

El ahorro de costos al utilizar los resultados ya almacenados en caché en Amazon S3 en lugar de volver a calcularlos aumenta con el número de veces que se pueden utilizar los mismos resultados almacenados en caché. Las consultas con análisis de tablas de gran tamaño seguidas de filtros o agregaciones de hash que reduzcan el tamaño de los resultados en un factor mínimo de 8 (es decir, una proporción de al menos 8:1 entre tamaño de entrada y resultados) son las que más se beneficiarán de esta característica. Cuanto mayor sea la proporción de reducción entre la entrada y los resultados, mayor será la relación entre costos y beneficios. Las consultas con proporciones de reducción más bajas, pero que contengan pasos costosos de computación entre el análisis de la tabla y el filtro o las agregaciones, también se beneficiarán, siempre que el costo de producir los resultados sea mayor que el costo de obtenerlos de Amazon S3. De forma predeterminada, el Almacenamiento en caché de fragmentos de resultados solo se aplica cuando detecta que la proporción de reducción será de al menos 8:1. 

Cuando las consultas reutilizan repetidamente los resultados almacenados en caché, las ventajas de esta característica son mayores. Las consultas en intervalos continuos e incrementales son buenos ejemplos. Por ejemplo, una consulta continua de 30 días que ya se haya ejecutado durante 29 días solo necesitaría extraer una trigésima parte de los datos de destino de su origen de entrada original y utilizaría fragmentos de resultados almacenados en caché de los 29 días anteriores. Una consulta de intervalo incremental se beneficia aún más, ya que el inicio del intervalo permanece fijo: cada vez que se invoca la consulta, un porcentaje menor del procesamiento requerirá la lectura del origen de entrada.

A continuación se indican algunas consideraciones adicionales a la hora de utilizar el Almacenamiento en caché de fragmentos de resultados:
+ Las consultas que no se dirijan a los mismos datos con los mismos fragmentos de consulta tendrán una tasa de aciertos de caché baja, por lo que no se beneficiarán de esta característica.
+ Las consultas con proporciones de reducción bajas que no contengan pasos de computación costosos darán como resultado resultados almacenados en caché que son aproximadamente tan caros de leer como de procesar inicialmente.
+ La primera consulta siempre mostrará una regresión menor debido al costo de escribir en la caché.
+ La característica Almacenamiento en caché de fragmentos de resultados funciona exclusivamente con archivos Parquet. No se admite ningún otro formato de archivo.
+ Los búferes de la característica Almacenamiento en caché de fragmentos de resultados solo intentarán almacenar en caché los análisis con tamaños de división de archivos de 128 MB o más. Con la configuración predeterminada de Spark, el Almacenamiento en caché de fragmentos de resultados se deshabilitará si el tamaño del análisis (el tamaño total de todos los archivos que se analizan) dividido por el número de núcleos ejecutores es inferior a 128 MB. Cuando se establezca alguna de las configuraciones de Spark que se enumeran a continuación, el tamaño de división de archivos será:

  ```
  min(maxPartitionBytes, max(openCostInBytes, scan size / minPartitionNum))
  ```
  + spark.sql. leafNodeDefaultParalelismo (el valor predeterminado es spark.default.parallelism)
  + spark.sql.files. minPartitionNum (el valor predeterminado es spark.sql. leafNodeDefaultParalelismo)
  + spark.sql.files. openCostInBytes
  + spark.sql.files. maxPartitionBytes
+ La característica Almacenamiento en caché de fragmentos de resultados almacena en caché según la granularidad de la partición de RDD. La proporción de reducción descrita anteriormente, que de forma predeterminada es 8:1, se evalúa por partición de RDD. Las cargas de trabajo con proporciones de reducción por RDD superiores e inferiores a 8:1 pueden obtener menores ventajas de rendimiento que las cargas de trabajo con proporciones de reducción por RDD que son sistemáticamente inferiores a 8:1.
+ La característica Almacenamiento en caché de fragmentos de resultados utiliza un búfer de escritura de 16 MB de forma predeterminada para cada partición de RDD que se almacena en caché. Si se van a almacenar en caché más de 16 MB por partición de RDD, el costo de determinar que no es posible realizar una escritura puede provocar una regresión del rendimiento.
+ Si bien de forma predeterminada el Almacenamiento en caché de fragmentos de resultados no intentará almacenar en caché los resultados de las particiones de RDD con una proporción de reducción inferior a 8:1 y limitará su búfer de escritura a 16 MB, ambos valores se pueden ajustar mediante las siguientes configuraciones:

  ```
  spark.sql.subResultCache.reductionRatioThreshold (default: 8.0)
  spark.sql.subResultCache.maxBufferSize (default: 16MB, max: 64MB)
  ```
+ Varios clústeres que utilizan la misma versión de Amazon EMR pueden compartir la misma ubicación de caché. Para garantizar la exactitud de los resultados, el Almacenamiento en caché de fragmentos de resultados no utilizará los resultados almacenados en caché escritos por distintas versiones de Amazon EMR.
+ El almacenamiento en caché de fragmentos de resultados se desactivará automáticamente en los casos de uso de Spark Streaming o cuando se RecordServer utilice Apache Ranger o AWS Lake Formation se utilice.
+ La caché de fragmentos de resultados read/writes utiliza buckets EMRFS/ S3A y Amazon S3. Las opciones de cifrado admitidas incluyen CSE (solo con EMRFS), SSE-S3 y SSE-KMS. Como referencia, S3A ofrece una implementación de Hadoop que permite que un clúster lea y escriba datos hacia y desde Amazon S3. El soporte para S3A está disponible desde la versión 7.4.0 de Amazon EMR.

# Uso de Nvidia RAPIDS Accelerator de Nvidia para Spark
<a name="emr-spark-rapids"></a>

Con la versión 6.2.0 y posteriores de Amazon EMR, puede utilizar el complemento [RAPIDS Accelerator para Apache Spark](https://docs.nvidia.com/spark-rapids/user-guide/latest/overview.html) para acelerar Spark mediante tipos de instancias de unidades de procesamiento gráfico (GPU) de EC2. RAPIDS Accelerator acelerará mediante GPU sus canalizaciones de ciencia de datos de Apache Spark 3.0 sin cambios de código y acelerará el procesamiento de datos y el entrenamiento de modelos, a la vez que reducirá considerablemente los costos de infraestructura.

En las siguientes secciones lo guiaremos a través de la configuración de su clúster de EMR para usar el complemento Spark-RAPIDS para Spark.

## Elección de tipos de instancias
<a name="emr-spark-rapids-instancetypes"></a>

Para usar el complemento Spark-RAPIDS de Nvidia para Spark, los grupos de instancias principales y de tareas deben usar tipos de instancias de GPU de EC2 que cumplan con los [requisitos de hardware](https://nvidia.github.io/spark-rapids/) de Spark-RAPIDS. Para ver una lista completa de los tipos de instancias de GPU compatibles con Amazon EMR, consulte [Tipos de instancias admitidos](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-supported-instance-types.html) en la *Guía de administración de Amazon EMR*. El tipo de instancia del grupo de instancias principal puede ser de tipo GPU o no, pero no se admiten los tipos de instancias de ARM.

## Definición de las configuraciones de aplicaciones para un clúster
<a name="emr-spark-rapids-appconfig"></a>

**1. Permitir que Amazon EMR instale los complementos en su nuevo clúster**

Para instalar los complementos, proporcione la siguiente configuración al crear el clúster:

```
{
	"Classification":"spark",
	"Properties":{
		"enableSparkRapids":"true"
	}
}
```

**2. Configurar YARN para usar GPU**

Para obtener más información sobre cómo usar GPU en YARN, consulte [Using GPU on YARN](https://hadoop.apache.org/docs/r3.2.1/hadoop-yarn/hadoop-yarn-site/UsingGpus.html) en la documentación de Apache Hadoop. En los siguientes ejemplos, se muestran ejemplos de configuraciones de YARN para las versiones 6.x y 7.x de Amazon EMR:

------
#### [ Amazon EMR 7.x ]

**Ejemplo de configuración de YARN para Amazon EMR 7.x**

```
{
    "Classification":"yarn-site",
    "Properties":{
        "yarn.nodemanager.resource-plugins":"yarn.io/gpu",
        "yarn.resource-types":"yarn.io/gpu",
        "yarn.nodemanager.resource-plugins.gpu.allowed-gpu-devices":"auto",
        "yarn.nodemanager.resource-plugins.gpu.path-to-discovery-executables":"/usr/bin",
        "yarn.nodemanager.linux-container-executor.cgroups.mount":"true",
        "yarn.nodemanager.linux-container-executor.cgroups.mount-path":"/spark-rapids-cgroup",
        "yarn.nodemanager.linux-container-executor.cgroups.hierarchy":"yarn",
        "yarn.nodemanager.container-executor.class":"org.apache.hadoop.yarn.server.nodemanager.LinuxContainerExecutor"
    }
},{
    "Classification":"container-executor",
    "Properties":{
        
    },
    "Configurations":[
        {
            "Classification":"gpu",
            "Properties":{
                "module.enabled":"true"
            }
        },
        {
            "Classification":"cgroups",
            "Properties":{
                "root":"/spark-rapids-cgroup",
                "yarn-hierarchy":"yarn"
            }
        }
    ]
}
```

------
#### [ Amazon EMR 6.x ]

**Ejemplo de configuración de YARN para Amazon EMR 6.x**

```
{
    "Classification":"yarn-site",
    "Properties":{
        "yarn.nodemanager.resource-plugins":"yarn.io/gpu",
        "yarn.resource-types":"yarn.io/gpu",
        "yarn.nodemanager.resource-plugins.gpu.allowed-gpu-devices":"auto",
        "yarn.nodemanager.resource-plugins.gpu.path-to-discovery-executables":"/usr/bin",
        "yarn.nodemanager.linux-container-executor.cgroups.mount":"true",
        "yarn.nodemanager.linux-container-executor.cgroups.mount-path":"/sys/fs/cgroup",
        "yarn.nodemanager.linux-container-executor.cgroups.hierarchy":"yarn",
        "yarn.nodemanager.container-executor.class":"org.apache.hadoop.yarn.server.nodemanager.LinuxContainerExecutor"
    }
},{
    "Classification":"container-executor",
    "Properties":{
        
    },
    "Configurations":[
        {
            "Classification":"gpu",
            "Properties":{
                "module.enabled":"true"
            }
        },
        {
            "Classification":"cgroups",
            "Properties":{
                "root":"/sys/fs/cgroup",
                "yarn-hierarchy":"yarn"
            }
        }
    ]
}
```

------

**3. Configurar Spark para usar RAPIDS**

Estas son las configuraciones necesarias para que Spark pueda usar el complemento RAPIDS:

```
{
	"Classification":"spark-defaults",
	"Properties":{
		"spark.plugins":"com.nvidia.spark.SQLPlugin",
		"spark.executor.resource.gpu.discoveryScript":"/usr/lib/spark/scripts/gpu/getGpusResources.sh",
		"spark.executor.extraLibraryPath":"/usr/local/cuda/targets/x86_64-linux/lib:/usr/local/cuda/extras/CUPTI/lib64:/usr/local/cuda/compat/lib:/usr/local/cuda/lib:/usr/local/cuda/lib64:/usr/lib/hadoop/lib/native:/usr/lib/hadoop-lzo/lib/native:/docker/usr/lib/hadoop/lib/native:/docker/usr/lib/hadoop-lzo/lib/native"
	}
}
```

XGBoost4La [biblioteca J-Spark](https://xgboost.readthedocs.io/en/latest/jvm/xgboost4j_spark_tutorial.html) de la XGBoost documentación también está disponible cuando el complemento Spark RAPIDS está activado en el clúster. Puedes usar la siguiente configuración para integrarla XGBoost con tu trabajo de Spark:

```
{
	"Classification":"spark-defaults",
	"Properties":{
		"spark.submit.pyFiles":"/usr/lib/spark/jars/xgboost4j-spark_3.0-1.4.2-0.3.0.jar"
	}
}
```

Para obtener más configuraciones de Spark que pueda usar para ajustar un clúster de EMR acelerado mediante GPU, consulte [Rapids Accelerator for Apache Spark tuning guide](https://docs.nvidia.com/spark-rapids/user-guide/latest/tuning-guide.html) en la documentación de Nvidia.github.io.

**4. Configurar el programador de capacidad de YARN**

`DominantResourceCalculator` debe configurarse para habilitar la programación y el aislamiento de GPU. Para obtener más información, consulte [Using GPU on YARN](https://hadoop.apache.org/docs/r3.2.1/hadoop-yarn/hadoop-yarn-site/UsingGpus.html) en la documentación de Apache Hadoop.

```
{
	"Classification":"capacity-scheduler",
	"Properties":{
		"yarn.scheduler.capacity.resource-calculator":"org.apache.hadoop.yarn.util.resource.DominantResourceCalculator"
	}
}
```

**5. Crear un archivo JSON para incluir todas las configuraciones**

Puede crear un archivo JSON que contenga la configuración para usar el complemento RAPIDS para su clúster de Spark. Proporcione el archivo más adelante, al lanzar el clúster.

Puede almacenar el archivo de forma local o en &S3. Para obtener más información sobre cómo proporcionar configuraciones de aplicaciones para sus clústeres, consulte [Configuración de aplicaciones](emr-configure-apps.md).

Utilice los siguientes archivos de ejemplo como plantillas para crear sus propias configuraciones.

------
#### [ Amazon EMR 7.x ]

**Archivo `my-configurations.json` de ejemplo para Amazon EMR 7.x**

```
[
    {
        "Classification":"spark",
        "Properties":{
            "enableSparkRapids":"true"
        }
    },
    {
        "Classification":"yarn-site",
        "Properties":{
            "yarn.nodemanager.resource-plugins":"yarn.io/gpu",
            "yarn.resource-types":"yarn.io/gpu",
            "yarn.nodemanager.resource-plugins.gpu.allowed-gpu-devices":"auto",
            "yarn.nodemanager.resource-plugins.gpu.path-to-discovery-executables":"/usr/bin",
            "yarn.nodemanager.linux-container-executor.cgroups.mount":"true",
            "yarn.nodemanager.linux-container-executor.cgroups.mount-path":"/spark-rapids-cgroup",
            "yarn.nodemanager.linux-container-executor.cgroups.hierarchy":"yarn",
            "yarn.nodemanager.container-executor.class":"org.apache.hadoop.yarn.server.nodemanager.LinuxContainerExecutor"
        }
    },
    {
        "Classification":"container-executor",
        "Properties":{
            
        },
        "Configurations":[
            {
                "Classification":"gpu",
                "Properties":{
                    "module.enabled":"true"
                }
            },
            {
                "Classification":"cgroups",
                "Properties":{
                    "root":"/spark-rapids-cgroup",
                    "yarn-hierarchy":"yarn"
                }
            }
        ]
    },
    {
        "Classification":"spark-defaults",
        "Properties":{
            "spark.plugins":"com.nvidia.spark.SQLPlugin",
            "spark.executor.resource.gpu.discoveryScript":"/usr/lib/spark/scripts/gpu/getGpusResources.sh",
            "spark.executor.extraLibraryPath":"/usr/local/cuda/targets/x86_64-linux/lib:/usr/local/cuda/extras/CUPTI/lib64:/usr/local/cuda/compat/lib:/usr/local/cuda/lib:/usr/local/cuda/lib64:/usr/lib/hadoop/lib/native:/usr/lib/hadoop-lzo/lib/native:/docker/usr/lib/hadoop/lib/native:/docker/usr/lib/hadoop-lzo/lib/native",
            "spark.submit.pyFiles":"/usr/lib/spark/jars/xgboost4j-spark_3.0-1.4.2-0.3.0.jar",
            "spark.rapids.sql.concurrentGpuTasks":"1",
            "spark.executor.resource.gpu.amount":"1",
            "spark.executor.cores":"2",
            "spark.task.cpus":"1",
            "spark.task.resource.gpu.amount":"0.5",
            "spark.rapids.memory.pinnedPool.size":"0",
            "spark.executor.memoryOverhead":"2G",
            "spark.locality.wait":"0s",
            "spark.sql.shuffle.partitions":"200",
            "spark.sql.files.maxPartitionBytes":"512m"
        }
    },
    {
        "Classification":"capacity-scheduler",
        "Properties":{
            "yarn.scheduler.capacity.resource-calculator":"org.apache.hadoop.yarn.util.resource.DominantResourceCalculator"
        }
    }
]
```

------
#### [ Amazon EMR 6.x ]

**Archivo `my-configurations.json` de ejemplo para Amazon EMR 6.x**

```
[
    {
        "Classification":"spark",
        "Properties":{
            "enableSparkRapids":"true"
        }
    },
    {
        "Classification":"yarn-site",
        "Properties":{
            "yarn.nodemanager.resource-plugins":"yarn.io/gpu",
            "yarn.resource-types":"yarn.io/gpu",
            "yarn.nodemanager.resource-plugins.gpu.allowed-gpu-devices":"auto",
            "yarn.nodemanager.resource-plugins.gpu.path-to-discovery-executables":"/usr/bin",
            "yarn.nodemanager.linux-container-executor.cgroups.mount":"true",
            "yarn.nodemanager.linux-container-executor.cgroups.mount-path":"/sys/fs/cgroup",
            "yarn.nodemanager.linux-container-executor.cgroups.hierarchy":"yarn",
            "yarn.nodemanager.container-executor.class":"org.apache.hadoop.yarn.server.nodemanager.LinuxContainerExecutor"
        }
    },
    {
        "Classification":"container-executor",
        "Properties":{
            
        },
        "Configurations":[
            {
                "Classification":"gpu",
                "Properties":{
                    "module.enabled":"true"
                }
            },
            {
                "Classification":"cgroups",
                "Properties":{
                    "root":"/sys/fs/cgroup",
                    "yarn-hierarchy":"yarn"
                }
            }
        ]
    },
    {
        "Classification":"spark-defaults",
        "Properties":{
            "spark.plugins":"com.nvidia.spark.SQLPlugin",
            "spark.executor.resource.gpu.discoveryScript":"/usr/lib/spark/scripts/gpu/getGpusResources.sh",
            "spark.executor.extraLibraryPath":"/usr/local/cuda/targets/x86_64-linux/lib:/usr/local/cuda/extras/CUPTI/lib64:/usr/local/cuda/compat/lib:/usr/local/cuda/lib:/usr/local/cuda/lib64:/usr/lib/hadoop/lib/native:/usr/lib/hadoop-lzo/lib/native:/docker/usr/lib/hadoop/lib/native:/docker/usr/lib/hadoop-lzo/lib/native",
            "spark.submit.pyFiles":"/usr/lib/spark/jars/xgboost4j-spark_3.0-1.4.2-0.3.0.jar",
            "spark.rapids.sql.concurrentGpuTasks":"1",
            "spark.executor.resource.gpu.amount":"1",
            "spark.executor.cores":"2",
            "spark.task.cpus":"1",
            "spark.task.resource.gpu.amount":"0.5",
            "spark.rapids.memory.pinnedPool.size":"0",
            "spark.executor.memoryOverhead":"2G",
            "spark.locality.wait":"0s",
            "spark.sql.shuffle.partitions":"200",
            "spark.sql.files.maxPartitionBytes":"512m"
        }
    },
    {
        "Classification":"capacity-scheduler",
        "Properties":{
            "yarn.scheduler.capacity.resource-calculator":"org.apache.hadoop.yarn.util.resource.DominantResourceCalculator"
        }
    }
]
```

------

## Adición de una acción de arranque para el clúster
<a name="emr-spark-rapids-bootstrap"></a>

Para obtener más información sobre cómo proporcionar scripts de acciones de arranque al crear el clúster, consulte [Conceptos básicos de las acciones de arranque](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-plan-bootstrap.html#bootstrapUses) en la *Guía de administración de Amazon EMR.*

En los siguientes scripts de ejemplo, se muestra cómo crear un archivo de acciones de arranque para Amazon EMR 6.x y 7.x:

------
#### [ Amazon EMR 7.x ]

**Archivo `my-bootstrap-action.sh` de ejemplo para Amazon EMR 7.x**

Para utilizar YARN con el fin de administrar los recursos de GPU con las versiones 7.x de Amazon EMR, debe realizar el montaje de forma manual de CGroup v1 en el clúster. Puede hacerlo con un script de acción de arranque, como se muestra en este ejemplo.

```
#!/bin/bash
set -ex
 
sudo mkdir -p /spark-rapids-cgroup/devices
sudo mount -t cgroup -o devices cgroupv1-devices /spark-rapids-cgroup/devices
sudo chmod a+rwx -R /spark-rapids-cgroup
```

------
#### [ Amazon EMR 6.x ]

**Archivo `my-bootstrap-action.sh` de ejemplo para Amazon EMR 6.x**

Para las versiones 6.x de Amazon EMR, debe abrir los permisos de CGroup para YARN en el clúster. Puede hacerlo con un script de acciones de arranque, como se muestra en este ejemplo.

```
#!/bin/bash
set -ex
 
sudo chmod a+rwx -R /sys/fs/cgroup/cpu,cpuacct
sudo chmod a+rwx -R /sys/fs/cgroup/devices
```

------

## Lanzamiento del clúster
<a name="emr-spark-rapids-launchcluster"></a>

El último paso consiste en lanzar el clúster con las configuraciones de clúster mencionadas anteriormente. A continuación, se muestra un comando de ejemplo para lanzar un clúster desde la CLI de Amazon EMR:

```
 aws emr create-cluster \
--release-label emr-7.12.0 \
--applications Name=Hadoop Name=Spark \
--service-role EMR_DefaultRole_V2 \
--ec2-attributes KeyName=my-key-pair,InstanceProfile=EMR_EC2_DefaultRole \
--instance-groups InstanceGroupType=MASTER,InstanceCount=1,InstanceType=m4.4xlarge \                 
                  InstanceGroupType=CORE,InstanceCount=1,InstanceType=g4dn.2xlarge \    
                  InstanceGroupType=TASK,InstanceCount=1,InstanceType=g4dn.2xlarge \
--configurations file:///my-configurations.json \
--bootstrap-actions Name='My Spark Rapids Bootstrap action',Path=s3://amzn-s3-demo-bucket/my-bootstrap-action.sh
```

# Acceso al intérprete de comandos de Spark
<a name="emr-spark-shell"></a>

El intérprete de comandos de Spark se basa en el Scala REPL (Read-Eval-Print-Loop). Le permite crear programas de Spark de forma interactiva y enviar trabajos al marco. Para acceder al intérprete de comandos de Spark, puede conectarse al nodo principal con SSH e invocar `spark-shell`. Para obtener más información sobre cómo conectarse al nodo principal, consulte [Conectarse al nodo principal mediante SSH](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-connect-master-node-ssh.html) en la *Guía de administración de Amazon EMR*. En los siguientes ejemplos se utilizan registros de acceso de Apache HTTP Server almacenados en Amazon S3.

**nota**  
El bucket de estos ejemplos está disponible para los clientes que pueden acceder a la región Este de EE. UU. (Norte de Virginia).

 Por defecto, el shell Spark crea su propio [SparkContext](https://spark.apache.org/docs/1.3.1/api/scala/index.html#org.apache.spark.SparkContext)objeto llamado`sc`. Puedes usar este contexto si es necesario en el REPL. sqlContexttambién está disponible en la carcasa y es un [HiveContext](https://spark.apache.org/docs/latest/api/scala/index.html#org.apache.spark.sql.hive.HiveContext). 

**Example Uso del intérprete de comandos de Spark para contar cuántas veces aparece una cadena en un archivo almacenado en Amazon S3**  
En este ejemplo, se utiliza `sc` para leer un archivo de texto almacenado en Amazon S3.  

```
scala> sc
res0: org.apache.spark.SparkContext = org.apache.spark.SparkContext@404721db

scala> val textFile = sc.textFile("s3://elasticmapreduce/samples/hive-ads/tables/impressions/dt=2009-04-13-08-05/ec2-0-51-75-39.amazon.com.rproxy.govskope.ca-2009-04-13-08-05.log")
```
Spark crea el textFile y la [estructura de datos](https://spark.apache.org/docs/latest/programming-guide.html#resilient-distributed-datasets-rdds) asociada. A continuación, el ejemplo determina la cantidad de líneas en el archivo de registro con la cadena "cartoonnetwork.com":  

```
scala> val linesWithCartoonNetwork = textFile.filter(line => line.contains("cartoonnetwork.com")).count()
linesWithCartoonNetwork: org.apache.spark.rdd.RDD[String] = MapPartitionsRDD[2] at filter at <console>:23
<snip>
<Spark program runs>
scala> linesWithCartoonNetwork
res2: Long = 9
```

**Example Uso del intérprete de comandos de Spark basado en Python para contar cuántas veces aparece una cadena en un archivo almacenado en Amazon S3**  
Spark también incluye un shell basado en Python, `pyspark`, que puede utilizar para crear prototipos de programas de Spark escritos en Python. Al igual que con`spark-shell`, invoke `pyspark` en el nodo principal; también tiene el mismo [SparkContext](https://spark.apache.org/docs/latest/api/python/reference/api/pyspark.SparkContext.html#pyspark.SparkContext)objeto.   

```
>>> sc
<pyspark.context.SparkContext object at 0x7fe7e659fa50>
>>> textfile = sc.textFile("s3://elasticmapreduce/samples/hive-ads/tables/impressions/dt=2009-04-13-08-05/ec2-0-51-75-39.amazon.com.rproxy.govskope.ca-2009-04-13-08-05.log")
```
Spark crea el textFile y la [estructura de datos](https://spark.apache.org/docs/latest/programming-guide.html#resilient-distributed-datasets-rdds) asociada. A continuación, el ejemplo determina la cantidad de líneas en el archivo de registro con la cadena "cartoonnetwork.com".  

```
>>> linesWithCartoonNetwork = textfile.filter(lambda line: "cartoonnetwork.com" in line).count()
15/06/04 17:12:22 INFO lzo.GPLNativeCodeLoader: Loaded native gpl library from the embedded binaries
15/06/04 17:12:22 INFO lzo.LzoCodec: Successfully loaded & initialized native-lzo library [hadoop-lzo rev EXAMPLE]
15/06/04 17:12:23 INFO fs.EmrFileSystem: Consistency disabled, using com.amazon.ws.emr.hadoop.fs.s3n.S3NativeFileSystem as filesystem implementation
<snip>
<Spark program continues>
>>> linesWithCartoonNetwork
9
```

# Utilice Amazon SageMaker Spark para el aprendizaje automático
<a name="emr-spark-sagemaker"></a>

Cuando se utiliza la versión 5.11.0 y posteriores de Amazon EMR, el componente `aws-sagemaker-spark-sdk` se instala junto con Spark. [Este componente instala Amazon SageMaker Spark y las dependencias asociadas para la integración de Spark con Amazon. SageMaker](https://aws.amazon.com/sagemaker/) Tenga en cuenta que el componente `aws-sagemaker-spark-sdk` no está disponible a partir de la versión 7.x de Amazon EMR. Puedes usar Amazon SageMaker Spark para crear canalizaciones de aprendizaje automático (ML) de Spark mediante Amazon SageMaker Stages. Para obtener más información, consulta el [README de Amazon SageMaker Spark](https://github.com/aws/sagemaker-spark/blob/master/README.md) sobre el GitHub [uso de Apache Spark con Amazon SageMaker](https://docs.aws.amazon.com/sagemaker/latest/dg/apache-spark.html) en la *Guía para SageMaker desarrolladores de Amazon*.

# Escritura de una aplicación de Spark
<a name="emr-spark-application"></a>

Las aplicaciones de [Spark](https://aws.amazon.com/big-data/what-is-spark/) se pueden escribir en Scala, Java o Python. Hay varios ejemplos de aplicaciones de Spark en el tema [Spark examples](https://spark.apache.org/examples.html) en la documentación de Apache Spark. El ejemplo Estimación de Pi que se muestra a continuación en las tres aplicaciones compatibles de forma nativa. También puede ver ejemplos completos en `$SPARK_HOME/examples` y en [GitHub](https://github.com/apache/spark/tree/master/examples/src/main). Para obtener más información sobre cómo compilar JARs para Spark, consulta el tema de [inicio rápido](https://spark.apache.org/docs/latest/quick-start.html) en la documentación de Apache Spark.

## Scala
<a name="emr-spark-application-scala"></a>

Para evitar problemas de compatibilidad con Scala, le sugerimos que utilice las dependencias de Spark para la versión correcta de Scala cuando compile una aplicación de Spark para un clúster de Amazon EMR. La versión de Scala que debe usar depende de la versión de Spark instalada en el clúster. Por ejemplo, la versión 5.30.1 de Amazon EMR usa Spark 2.4.5, que se basa en Scala 2.11. Si su clúster utiliza la versión 5.30.1 de Amazon EMR, utilice las dependencias de Spark para Scala 2.11. Para obtener más información sobre las versiones de Scala que utiliza Spark, consulte la [documentación de Apache Spark](https://spark.apache.org/documentation.html).

```
package org.apache.spark.examples
import scala.math.random
import org.apache.spark._

/** Computes an approximation to pi */
object SparkPi {
  def main(args: Array[String]) {
    val conf = new SparkConf().setAppName("Spark Pi")
    val spark = new SparkContext(conf)
    val slices = if (args.length > 0) args(0).toInt else 2
    val n = math.min(100000L * slices, Int.MaxValue).toInt // avoid overflow
    val count = spark.parallelize(1 until n, slices).map { i =>
      val x = random * 2 - 1
      val y = random * 2 - 1
      if (x*x + y*y < 1) 1 else 0
    }.reduce(_ + _)
    println("Pi is roughly " + 4.0 * count / n)
    spark.stop()
  }
}
```

## Java
<a name="emr-spark-application-java"></a>

```
package org.apache.spark.examples;

import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaRDD;
import org.apache.spark.api.java.JavaSparkContext;
import org.apache.spark.api.java.function.Function;
import org.apache.spark.api.java.function.Function2;

import java.util.ArrayList;
import java.util.List;

/** 
 * Computes an approximation to pi
 * Usage: JavaSparkPi [slices]
 */
public final class JavaSparkPi {

  public static void main(String[] args) throws Exception {
    SparkConf sparkConf = new SparkConf().setAppName("JavaSparkPi");
    JavaSparkContext jsc = new JavaSparkContext(sparkConf);

    int slices = (args.length == 1) ? Integer.parseInt(args[0]) : 2;
    int n = 100000 * slices;
    List<Integer> l = new ArrayList<Integer>(n);
    for (int i = 0; i < n; i++) {
      l.add(i);
    }

    JavaRDD<Integer> dataSet = jsc.parallelize(l, slices);

    int count = dataSet.map(new Function<Integer, Integer>() {
      @Override
      public Integer call(Integer integer) {
        double x = Math.random() * 2 - 1;
        double y = Math.random() * 2 - 1;
        return (x * x + y * y < 1) ? 1 : 0;
      }
    }).reduce(new Function2<Integer, Integer, Integer>() {
      @Override
      public Integer call(Integer integer, Integer integer2) {
        return integer + integer2;
      }
    });

    System.out.println("Pi is roughly " + 4.0 * count / n);

    jsc.stop();
  }
}
```

## Python
<a name="emr-spark-application-spark27"></a>

```
import argparse
import logging
from operator import add
from random import random

from pyspark.sql import SparkSession

logger = logging.getLogger(__name__)
logging.basicConfig(level=logging.INFO, format="%(levelname)s: %(message)s")


def calculate_pi(partitions, output_uri):
    """
    Calculates pi by testing a large number of random numbers against a unit circle
    inscribed inside a square. The trials are partitioned so they can be run in
    parallel on cluster instances.

    :param partitions: The number of partitions to use for the calculation.
    :param output_uri: The URI where the output is written, typically an Amazon S3
                       bucket, such as 's3://example-bucket/pi-calc'.
    """

    def calculate_hit(_):
        x = random() * 2 - 1
        y = random() * 2 - 1
        return 1 if x**2 + y**2 < 1 else 0

    tries = 100000 * partitions
    logger.info(
        "Calculating pi with a total of %s tries in %s partitions.", tries, partitions
    )
    with SparkSession.builder.appName("My PyPi").getOrCreate() as spark:
        hits = (
            spark.sparkContext.parallelize(range(tries), partitions)
            .map(calculate_hit)
            .reduce(add)
        )
        pi = 4.0 * hits / tries
        logger.info("%s tries and %s hits gives pi estimate of %s.", tries, hits, pi)
        if output_uri is not None:
            df = spark.createDataFrame([(tries, hits, pi)], ["tries", "hits", "pi"])
            df.write.mode("overwrite").json(output_uri)


if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument(
        "--partitions",
        default=2,
        type=int,
        help="The number of parallel partitions to use when calculating pi.",
    )
    parser.add_argument(
        "--output_uri", help="The URI where output is saved, typically an S3 bucket."
    )
    args = parser.parse_args()

    calculate_pi(args.partitions, args.output_uri)
```

# Mejora del rendimiento de Spark con Amazon S3
<a name="emr-spark-s3-performance"></a>

Amazon EMR ofrece características para ayudar a optimizar el rendimiento cuando se utiliza Spark para consultar, leer y escribir datos guardados en Amazon S3.

[S3 Select](https://aws.amazon.com/blogs/aws/s3-glacier-select/) puede mejorar el rendimiento de las consultas para archivos JSON y CSV en algunas aplicaciones al “delegar” el procesamiento en Amazon S3.

El compilador optimizado para EMRFS para S3 es una alternativa a la [OutputCommitter](https://hadoop.apache.org/docs/current/api/org/apache/hadoop/mapreduce/OutputCommitter.html)clase, que utiliza la función de cargas multiparte de EMRFS para mejorar el rendimiento al escribir archivos Parquet en Amazon S3 mediante Spark y Datasets. DataFrames

**Topics**
+ [Uso de S3 Select con Spark para mejorar el rendimiento de las consultas](emr-spark-s3select.md)
+ [CHISPA EMR MagicCommitProtocol](emr-spark-magic-commit-protocol.md)
+ [Uso del confirmador optimizado para S3 de EMRFS](emr-spark-s3-optimized-committer.md)
+ [Uso del protocolo de confirmación optimizado para S3 de EMRFS](emr-spark-s3-optimized-commit-protocol.md)
+ [Reintento de solicitudes de Amazon S3 con EMRFS](emr-spark-emrfs-retry.md)

# Uso de S3 Select con Spark para mejorar el rendimiento de las consultas
<a name="emr-spark-s3select"></a>

**importante**  
Amazon S3 Select ya no está disponible para los nuevos clientes. Los clientes actuales de Amazon S3 Select pueden seguir utilizando la característica de la forma habitual. [Más información](https://aws.amazon.com/blogs/storage/how-to-optimize-querying-your-data-in-amazon-s3/) 

Con la versión 5.17.0 y posteriores de Amazon EMR, puede usar [S3 Select](https://aws.amazon.com/blogs/aws/s3-glacier-select/) con Spark en Amazon EMR. *S3 Select* permite que las aplicaciones recuperen únicamente un subconjunto de datos de un objeto. Para Amazon EMR, el clúster “delega” en Amazon S3 el trabajo de computación de filtrar grandes conjuntos de datos para su procesamiento, lo que puede mejorar el rendimiento en algunas aplicaciones y reduce la cantidad de datos transferidos entre Amazon EMR y Amazon S3.

S3 Select es compatible con los archivos JSON y CSV si se utilizan los valores `s3selectCSV` y `s3selectJSON` para especificar el formato de los datos. Para obtener más información y ejemplos, consulta [Especificación de S3 Select en el código](#emr-spark-s3select-specify).

## ¿S3 Select es adecuado para mi aplicación?
<a name="emr-spark-s3select-apps"></a>

Le recomendamos que realice un análisis comparativo sus aplicaciones con y sin S3 Select para ver si su uso puede ser adecuado para su aplicación.

Utilice las siguientes directrices para determinar si la aplicación es candidata a utilizar S3 Select:
+ La consulta filtra más de la mitad del conjunto de datos original.
+ La conexión de red entre Amazon S3 y el clúster de Amazon EMR tiene una buena velocidad de transferencia y ancho de banda disponible. Amazon S3 no comprime las respuestas HTTP, por lo que es probable que el tamaño de la respuesta aumente en el caso de los archivos de entrada comprimidos.

## Consideraciones y limitaciones
<a name="emr-spark-s3select-considerations"></a>
+ No se admiten el cifrado del servidor de Amazon S3 con claves de cifrado proporcionadas por el cliente (SSE-C) ni el cifrado del cliente. 
+ No se admite la propiedad `AllowQuotedRecordDelimiters`. Si se especifica esta propiedad, se producirá un error en la consulta.
+ Solo se admiten archivos CSV y JSON en formato UTF-8. No se admiten las líneas múltiples. CSVs
+ Solo se admiten los archivos sin comprimir o gzip.
+ No se admiten opciones de JSON y CSV en Spark como, por ejemplo `nanValue`, `positiveInf`, `negativeInf` y las opciones relacionadas con los registros dañados (por ejemplo, failfast y el modo dropmalformed).
+ El uso de comas (,) dentro de los decimales no se admite. Por ejemplo, `10,000` no se admite, pero sí se admite `10000`.
+ No se admiten los caracteres de comentario en la última línea.
+ Las líneas vacías al final de un archivo no se procesan.
+ Los siguientes filtros no se delegan en Amazon S3:
  + Funciones de agregación como `COUNT()` y `SUM()`.
  + Filtros que aplican `CAST()` a un atributo. Por ejemplo, `CAST(stringColumn as INT) = 1`.
  + Filtros con un atributo que es un objeto o es complejo. Por ejemplo, `intArray[1] = 1, objectColumn.objectNumber = 1`.
  + Filtros cuyo valor no es un valor literal. Por ejemplo, `intColumn1 = intColumn2`
  + Solo se admiten los [tipos de datos compatibles con S3 Select](https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-glacier-select-sql-reference-data-types.html) con las limitaciones que se especifican.

## Especificación de S3 Select en el código
<a name="emr-spark-s3select-specify"></a>

Los siguientes ejemplos muestran cómo especificar S3 Select para CSV mediante Scala, SQL, R y PySpark. Puede utilizar S3 Select para JSON de la misma manera. Para obtener una lista de las opciones, sus valores predeterminados y sus limitaciones, consulte [Opciones](#emr-spark-s3select-specify-options).

------
#### [ PySpark ]

```
spark
  .read
  .format("s3selectCSV") // "s3selectJson" for Json
  .schema(...) // optional, but recommended
  .options(...) // optional
  .load("s3://path/to/my/datafiles")
```

------
#### [ R ]

```
read.df("s3://path/to/my/datafiles", "s3selectCSV", schema, header = "true", delimiter = "\t")
```

------
#### [ Scala ]

```
spark
  .read
  .format("s3selectCSV") // "s3selectJson" for Json
  .schema(...) // optional, but recommended
  .options(...) // optional. Examples:  
  // .options(Map("quote" -> "\'", "header" -> "true")) or
  // .option("quote", "\'").option("header", "true")
  .load("s3://path/to/my/datafiles")
```

------
#### [ SQL ]

```
CREATE TEMPORARY VIEW MyView (number INT, name STRING) USING s3selectCSV OPTIONS (path "s3://path/to/my/datafiles", header "true", delimiter "\t")
```

------

### Opciones
<a name="emr-spark-s3select-specify-options"></a>

Las siguientes opciones están disponibles cuando se utilizan `s3selectCSV` y `s3selectJSON`. Si no se especifican, se usarán los valores predeterminados.

#### Opciones con S3selectCSV
<a name="emr-spark-s3select-specify-options-csv"></a>


| Opción | Predeterminado | De uso | 
| --- | --- | --- | 
|  `compression`  |  `"none"`  |  Indica si se utiliza la compresión. `"gzip"` es la única opción admitida además de `"none"`.  | 
|  `delimiter`  |  ","  |  Especifica el delimitador de campo.  | 
|  `quote`  |  `'\"'`  |  Especifica el carácter de comillas. No es posible especificar una cadena vacía. Si lo hace, se mostrará un error que indica que el XML no tiene el formato correcto.  | 
|  `escape`  |  `'\\'`  |  Especifica el carácter de escape.  | 
|  `header`  |  `"false"`  |  `"false"` especifica que no existe ningún encabezado. `"true"` especifica que hay un encabezado en la primera línea. Solo se admiten los encabezados en la primera línea, y no se admiten las líneas vacías antes del encabezado.  | 
|  comentario  |  `"#"`  |  Especifica el carácter de comentario. El indicador de comentario no se puede deshabilitar. En otras palabras, no se admite el valor `\u0000`.  | 
|  `nullValue`  |  ""  |    | 

#### Opciones con S3selectJSON
<a name="emr-spark-s3select-specify-options-json"></a>


| Opción | Predeterminado | De uso | 
| --- | --- | --- | 
|  `compression`  |  `"none"`  |  Indica si se utiliza la compresión. `"gzip"` es la única opción admitida además de `"none"`.  | 
|  `multiline`  |  "false"  |  `"false"` especifica que el JSON está en el formato `LINES` de S3 Select, lo que significa que cada línea de los datos de entrada contiene un único objeto JSON. `"true"` especifica que el JSON está en el formato `DOCUMENT` de S3 Select, lo que significa que un objeto JSON pueden abarcar varias líneas en los datos de entrada.  | 

# CHISPA EMR MagicCommitProtocol
<a name="emr-spark-magic-commit-protocol"></a>

A partir de la versión 6.15.0 de EMR, MagicCommitProtocol se convierte en la opción predeterminada FileCommitProtocol para Spark cuando se utiliza el sistema de archivos S3A.

## MagicCommitProtocol
<a name="magic-commit-protocol"></a>

 MagicCommitProtocol Se trata de una implementación alternativa a la [FileCommitProtocol](https://dlcdn.apache.org/spark/docs/2.4.2/api/java/org/apache/spark/internal/io/FileCommitProtocol.html)que está optimizada para escribir archivos con EMR Spark en Amazon S3 cuando se utiliza el sistema de archivos S3A. Este protocolo busca mejorar el rendimiento de las aplicaciones al evitar operaciones de cambio de nombre en Amazon S3 durante las fases de confirmación del trabajo y de las tareas.

 MagicCommitProtocol Es la FileCommitProtocol implementación predeterminada que usa Spark cuando se ejecuta en Amazon Elastic Map Reduce (EMR) cuando se utiliza el sistema de archivos S3A. Utiliza MagicCommitProtocol internamente el [MagicV2Committer](https://docs.aws.amazon.com/emr/latest/ReleaseGuide/s3a-magicv2-committer.html) para realizar las escrituras de archivos en Amazon S3.

En el caso de las operaciones de inserción estática, graba MagicCommitProtocol los archivos en la ubicación de salida del trabajo durante la fase de confirmación de la tarea. En cambio, en operaciones de inserción dinámica con sobrescritura, los archivos generados por los intentos de tarea solo aparecen en la ubicación de salida cuando el trabajo se confirma. Esto se logra mediante la exportación de metadatos de confirmación hacia el controlador de Spark durante la llamada de confirmación de la tarea.

## Habilitando MagicCommitProtocol
<a name="enabling-magic-commit-protocol"></a>

 MagicCommitProtocol Está habilitado de forma predeterminada para Spark que se ejecuta en Amazon Elastic Map Reduce (EMR) cuando se utiliza el sistema de archivos S3A.

Para usar el sistema de archivos S3A, puede hacer lo siguiente:

1. Especificar el esquema del archivo como `s3a://` al definir la tabla, partición o directorio.

1. Establecer la propiedad `fs.s3.impl=org.apache.hadoop.fs.s3a.S3AFileSystem` en el archivo core-site.xml.

## Deshabilitar el MagicCommitProtocol
<a name="disabling-magic-commit-protocol"></a>

1. Puede establecer la propiedad `spark.sql.execution.datasources.SQLEmrOptimizedCommitProtocol.leverageMagicCommitProtocol` en falso codificándola de forma rígida en un `SparkConf`, pasándola como un parámetro `--conf` en el intérprete de comandos de Spark o las herramientas `spark-submit` y `spark-sql`, o en `conf/spark-defaults.conf`. Para obtener más información, consulte [Spark configuration](https://spark.apache.org/docs/latest/configuration.html) en la documentación de Apache Spark.

   En el siguiente ejemplo, se muestra cómo deshabilitarla MagicCommitProtocol mientras se ejecuta un `spark-sql` comando.

   ```
   spark-sql \
     --conf spark.sql.execution.datasources.SQLEmrOptimizedCommitProtocol.leverageMagicCommitProtocol=false \
   -e "INSERT OVERWRITE TABLE target_table SELECT * FROM source_table;"
   ```

1. Utilice la clasificación de configuración `spark-defaults` para establecer la propiedad `spark.sql.execution.datasources.SQLEmrOptimizedCommitProtocol.leverageMagicCommitProtocol` en falso. Para obtener más información, consulte [Configuración de aplicaciones](https://docs.aws.amazon.com/emr/latest/ReleaseGuide/emr-configure-apps.html).

## MagicCommitProtocol consideraciones
<a name="magic-commit-considerations"></a>
+ En el caso de la inserción de particiones estáticas, en los ejecutores de Spark, se MagicCommitProtocol consume una pequeña cantidad de memoria por cada archivo escrito por un intento de tarea hasta que la tarea se confirma o se anula. En la mayoría de los trabajos, la cantidad de memoria consumida es insignificante. No requiere memoria adicional en el controlador de Spark.
+ En el caso de la inserción dinámica de particiones, en los controladores de Spark, se MagicCommitProtocol necesita memoria para almacenar la información de los metadatos de cada archivo confirmado hasta que el trabajo se confirme o se cancele. En la mayoría de los trabajos, la configuración de memoria predeterminada del controlador de Spark es insignificante.

  En los trabajos que tienen tareas de ejecución prolongada y que escriben un gran número de archivos, la memoria que consume el protocolo de confirmación puede ser apreciable y requerir algunos ajustes de la memoria asignada a Spark, especialmente a los ejecutores de Spark. Puede ajustar la memoria mediante la propiedad `spark.driver.memory` para los controladores de Spark y la propiedad `spark.executor.memory` para los ejecutores de Spark. Como pauta general, una sola tarea que escribe 100 000 archivos, normalmente requerirá 200 MB de memoria adicionales. Para obtener más información, consulte [Application properties](https://spark.apache.org/docs/latest/configuration.html#application-properties) en la documentación de configuración de Apache Spark.

# Uso del confirmador optimizado para S3 de EMRFS
<a name="emr-spark-s3-optimized-committer"></a>

El confirmador optimizado para S3 para EMRFS es una [OutputCommitter](https://hadoop.apache.org/docs/current/api/org/apache/hadoop/mapreduce/OutputCommitter.html)implementación alternativa que está optimizada para escribir archivos en Amazon S3 cuando se usa EMRFS. El confirmador optimizado para S3 de EMRFS mejora el rendimiento de las aplicaciones al evitar que se lleven a cabo operaciones de cambio de nombre y de listado en Amazon S3 durante las fases de confirmación de tareas y de trabajos. El confirmador está disponible con la versión 5.19.0 y posteriores de Amazon EMR y está habilitado de forma predeterminada con la versión 5.20.0 y posteriores de Amazon EMR. El confirmador se utiliza para los trabajos de Spark que utilizan Spark o Datasets. DataFrames A partir de Amazon EMR 6.4.0, este confirmador se puede utilizar para todos los formatos habituales, incluidos los formatos Parquet, ORC y basados en texto (incluidos CSV y JSON). En el caso de las versiones anteriores a Amazon EMR 6.4.0, solo se admite el formato Parquet. Existen circunstancias bajo las cuales no se utiliza el confirmador. Para obtener más información, consulte [Requisitos del confirmador optimizado para S3 de EMRFS](emr-spark-committer-reqs.md).

**Topics**
+ [Requisitos del confirmador optimizado para S3 de EMRFS](emr-spark-committer-reqs.md)
+ [El confirmador optimizado para S3 de EMRFS y las cargas multiparte](emr-spark-committer-multipart.md)
+ [Consideraciones sobre el ajuste de trabajos](emr-spark-committer-tuning.md)
+ [Habilitación del confirmador optimizado para S3 de EMRFS para Amazon EMR 5.19.0](emr-spark-committer-enable.md)

# Requisitos del confirmador optimizado para S3 de EMRFS
<a name="emr-spark-committer-reqs"></a>

El confirmador optimizado para S3 de EMRFS se utiliza cuando se cumplen las siguientes condiciones:
+ Ejecuta trabajos de Spark que utilizan Spark o Datasets para escribir archivos en Amazon S3. DataFrames A partir de Amazon EMR 6.4.0, este confirmador se puede utilizar para todos los formatos habituales, incluidos los formatos Parquet, ORC y basados en texto (incluidos CSV y JSON). En el caso de las versiones anteriores a Amazon EMR 6.4.0, solo se admite el formato Parquet.
+ Las cargas multiparte están habilitadas en Amazon EMR. Esta es la opción predeterminada. Para obtener más información, consulte [El confirmador optimizado para S3 de EMRFS y las cargas multiparte](emr-spark-committer-multipart.md). 
+ Se utiliza la compatibilidad de formatos de archivos integrados de Spark. La compatibilidad de formatos de archivos integrados se utiliza en las siguientes circunstancias:
  + En el caso de las tablas del almacén de metadatos de Hive, cuando `spark.sql.hive.convertMetastoreParquet` se establece en `true` para tablas Parquet o `spark.sql.hive.convertMetastoreOrc` se establece en `true` para tablas ORC con Amazon EMR 6.4.0 o posteriores. Esta es la configuración predeterminada.
  + Cuando los trabajos escriben orígenes de datos o tablas de formatos de archivos, por ejemplo, la tabla de destino se crea con la cláusula `USING parquet`. 
  + Cuando los trabajos escriben en tablas de Parquet de metaalmacenes de Hive no particionadas. La compatibilidad con Parquet integrada de Spark no admite tablas de Hive particionadas, se trata de una limitación conocida. Para obtener más información, consulte la [conversión de tablas de Hive Metastore Parquet](https://spark.apache.org/docs/latest/sql-data-sources-parquet.html#hive-metastore-parquet-table-conversion) en la Guía de conjuntos de datos DataFrames y Spark de Apache.
+ Las operaciones de trabajos de Spark que escriben en una ubicación de partición predeterminada (por ejemplo, `${table_location}/k1=v1/k2=v2/`) utilizan el confirmador. El confirmador no se utiliza si una operación de trabajo escribe en una ubicación de partición personalizada, por ejemplo, si una ubicación de partición personalizada se establece con el comando `ALTER TABLE SQL`.
+ Se deben utilizar los valores siguientes para Spark:
  + La propiedad `spark.sql.parquet.fs.optimized.committer.optimization-enabled` debe establecerse en `true`. Esta es la configuración predeterminada con Amazon EMR 5.20.0 y versiones posteriores. Con Amazon EMR 5.19.0, el valor predeterminado es `false`. Para obtener más información acerca de cómo configurar este valor, consulte [Habilitación del confirmador optimizado para S3 de EMRFS para Amazon EMR 5.19.0](emr-spark-committer-enable.md).
  + Si se escribe en tablas del metaalmacén de Hive no particionadas, solo se admiten los formatos de archivo Parquet y Orc. `spark.sql.hive.convertMetastoreParquet` debe establecerse en `true` si se escribe en tablas Parquet no particionadas del metaalmacén de Hive. `spark.sql.hive.convertMetastoreOrc` debe establecerse en `true` si se escribe en tablas Orc no particionadas del metaalmacén de Hive. Esta es la configuración predeterminada.
  + `spark.sql.parquet.output.committer.class` se debe establecer en `com.amazon.emr.committer.EmrOptimizedSparkSqlParquetOutputCommitter`. Esta es la configuración predeterminada.
  + `spark.sql.sources.commitProtocolClass` debe establecerse en `org.apache.spark.sql.execution.datasources.SQLEmrOptimizedCommitProtocol` o `org.apache.spark.sql.execution.datasources.SQLHadoopMapReduceCommitProtocol`. `org.apache.spark.sql.execution.datasources.SQLEmrOptimizedCommitProtocol` es la configuración predeterminada para la versión 5.30.0 y posteriores de la serie 5.x de Amazon EMR y para la versión 6.2.0 y posteriores de la serie 6.x de Amazon EMR. `org.apache.spark.sql.execution.datasources.SQLHadoopMapReduceCommitProtocol` es la configuración predeterminada para las versiones anteriores de Amazon EMR.
  + Si los trabajos de Spark sobrescriben conjuntos de datos de Parquet particionados con columnas de partición, entonces la opción de escritura `partitionOverwriteMode` y `spark.sql.sources.partitionOverwriteMode` se deben establecer en `static`. Es la configuración predeterminada.
**nota**  
La opción de escritura `partitionOverwriteMode` se introdujo en Spark 2.4.0. En el caso de la versión 2.3.2 de Spark, incluida con la versión 5.19.0 de Amazon EMR, establezca la propiedad `spark.sql.sources.partitionOverwriteMode`. 

## Ocasiones en las que no se utiliza el confirmador optimizado para S3 de EMRFS
<a name="emr-spark-committer-reqs-anti"></a>

Por lo general, el confirmador optimizado para S3 de EMRFS no se utiliza en las siguientes situaciones.


****  

| Situación | Por qué no se utiliza el confirmador | 
| --- | --- | 
| Cuando escribe en HDFS | El confirmador solo admite la escritura en Amazon S3 mediante EMRFS. | 
| Cuando utiliza el sistema de archivos S3A | El confirmador solo admite EMRFS. | 
| Cuando utilizas la MapReduce API RDD de Spark | El confirmador solo admite el uso de SparkSQL o DataFrame Dataset. APIs | 

En los siguientes ejemplos se muestran algunas situaciones más que evitan el uso del confirmador optimizado para S3 de EMRFS en su conjunto (el primer ejemplo) y en parte (el segundo ejemplo).

**Example – Modo de sobrescritura de partición dinámica**  
En el siguiente ejemplo de Scala se indica a Spark que utilice un algoritmo de confirmación diferente, lo que impide por completo el uso del confirmador optimizado para S3 de EMRFS. El código establece la propiedad `partitionOverwriteMode` en `dynamic` para sobrescribir solo las particiones en las que escriba datos. A continuación, las columnas de particiones dinámicas se especifican mediante `partitionBy` y el modo de escritura se establece en `overwrite`.   

```
val dataset = spark.range(0, 10)
  .withColumn("dt", expr("date_sub(current_date(), id)"))

dataset.write.mode("overwrite")
  .option("partitionOverwriteMode", "dynamic")
  .partitionBy("dt")
  .parquet("s3://amzn-s3-demo-bucket1/output")
```
Debe establecer las tres configuraciones para evitar utilizar el confirmador optimizado para S3 de EMRFS. Al hacerlo, Spark ejecuta un algoritmo de confirmación diferente que se especifica en el protocolo de confirmación de Spark. En el caso de las versiones 5.x de Amazon EMR anteriores a la 5.30.0 y las versiones 6.x de Amazon EMR anteriores a la 6.2.0, el protocolo de confirmación utiliza el directorio provisional de Spark, que es un directorio temporal creado en la ubicación de salida que comienza por `.spark-staging`. El algoritmo cambia de forma secuencial el nombre de los directorios de particiones, lo que puede afectar negativamente al rendimiento. Para obtener más información sobre la versión 5.30.0 y posteriores y 6.2.0 y posteriores de Amazon EMR, consulte [Uso del protocolo de confirmación optimizado para S3 de EMRFS](emr-spark-s3-optimized-commit-protocol.md).   
El algoritmo de Spark 2.4.0 sigue estos pasos:  

1. La tarea intenta escribir su salida en los directorios de particiones en el directorio provisional de Spark (por ejemplo, `${outputLocation}/spark-staging-${jobID}/k1=v1/k2=v2/`).

1. Para cada partición escrita, la tarea intenta llevar un seguimiento de las rutas de partición relativas (por ejemplo, `k1=v1/k2=v2`).

1. Cuando una tarea se completa de forma satisfactoria, proporciona al controlador todas las rutas de partición relativa cuyo seguimiento ha realizado.

1. Una vez completadas todas las tareas, la fase de confirmación del trabajo recopila todos los directorios de partición que los intentos de tarea correctos escribieron en el directorio de ensayo de Spark. Spark cambia el nombre de estos directorios de forma secuencial a su ubicación de salida final utilizando operaciones de cambio de nombre de árbol de directorio.

1. El directorio de ensayo se elimina antes de que se complete la fase de confirmación de trabajo.

**Example – Ubicación de partición personalizada**  
En este ejemplo, el código Scala se inserta en dos particiones. Una partición tiene una ubicación de partición personalizada. La otra partición utiliza la ubicación de partición predeterminada. El confirmador optimizado para S3 de EMRFS se utiliza solo para escribir la salida de tarea en la partición que utiliza la ubicación de partición predeterminada.  

```
val table = "dataset"
val location = "s3://bucket/table"
                            
spark.sql(s"""
  CREATE TABLE $table (id bigint, dt date) 
  USING PARQUET PARTITIONED BY (dt) 
  LOCATION '$location'
""")
                            
// Add a partition using a custom location
val customPartitionLocation = "s3://bucket/custom"
spark.sql(s"""
  ALTER TABLE $table ADD PARTITION (dt='2019-01-28') 
  LOCATION '$customPartitionLocation'
""")
                            
// Add another partition using default location
spark.sql(s"ALTER TABLE $table ADD PARTITION (dt='2019-01-29')")
                            
def asDate(text: String) = lit(text).cast("date")
                            
spark.range(0, 10)
  .withColumn("dt",
    when($"id" > 4, asDate("2019-01-28")).otherwise(asDate("2019-01-29")))
  .write.insertInto(table)
```
El código de Scala crea los siguientes objetos de Amazon S3:  

```
custom/part-00001-035a2a9c-4a09-4917-8819-e77134342402.c000.snappy.parquet
custom_$folder$
table/_SUCCESS
table/dt=2019-01-29/part-00000-035a2a9c-4a09-4917-8819-e77134342402.c000.snappy.parquet
table/dt=2019-01-29_$folder$
table_$folder$
```
Al escribir en particiones de ubicaciones personalizadas, Spark utiliza un algoritmo de confirmación similar al del ejemplo anterior, que se detalla a continuación. Como ocurre en el ejemplo anterior, el algoritmo da como resultado cambios de nombre secuenciales, lo que puede afectar negativamente al rendimiento.  

1. Al escribir la salida en una partición de una ubicación personalizada, las tareas escriben en un archivo del directorio de ensayo de Spark, que se crea en la ubicación de salida final. El nombre del archivo incluye un UUID aleatorio para proteger contra las colisiones de archivo. La tarea intenta mantener un seguimiento de cada archivo junto con la ruta de salida deseada final.

1. Cuando una tarea se completa de forma satisfactoria, proporciona al controlador los archivos y las rutas de salida deseada final.

1. Una vez completadas todas las tareas, la fase de confirmación de trabajo cambia el nombre de forma secuencial de todos los archivos que se escribieron para particiones en ubicaciones personalizadas en sus rutas de salida finales.

1. El directorio de ensayo se elimina antes de que se complete la fase de confirmación de trabajo.

# El confirmador optimizado para S3 de EMRFS y las cargas multiparte
<a name="emr-spark-committer-multipart"></a>

Para utilizar el confirmador optimizado para S3 de EMRFS, debe habilitar las cargas multiparte para Amazon EMR. Las cargas multiparte están habilitadas de forma predeterminada. Puede volver a habilitarlas si es necesario. Para obtener más información, consulte [Configuración de carga multiparte para Amazon S3](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-plan-upload-s3.html#Config_Multipart) en la *Guía de administración de Amazon EMR*. 

El confirmador optimizado para S3 de EMRFS utiliza las características similares a las transacciones de las cargas multiparte para garantizar que los archivos escritos por los intentos de tareas solo aparecen en la ubicación de salida del trabajo al confirmar las tareas. Al utilizar las cargas multiparte de esta forma, el confirmador mejora el rendimiento de las confirmaciones de tareas en comparación con la versión 2 del algoritmo predeterminado. FileOutputCommitter Cuando se utiliza el confirmador optimizado para S3 de EMRFS, existen algunas diferencias clave que lo distinguen del comportamiento tradicional de las cargas multiparte y que hay que tener en cuenta:
+ Las cargas multiparte siempre se llevan a cabo independientemente del tamaño del archivo. Esto difiere del comportamiento predeterminado de EMRFS, donde la propiedad `fs.s3n.multipart.uploads.split.size` controla el tamaño del archivo en el que se activan las cargas multiparte.
+ Las cargas multiparte se dejan en un estado incompleto durante un periodo de tiempo más prolongado hasta que la tarea se confirma o se anula. Esto difiere del comportamiento predeterminado de EMRFS, donde una carga multiparte se completa cuando una tarea termina de escribir un determinado archivo.

Debido a estas diferencias, si la JVM de un ejecutor de Spark se bloquea o se termina mientras hay tareas ejecutándose y escribiendo datos en Amazon S3, es más probable que queden cargas multiparte incompletas sin finalizar. Por este motivo, cuando utilice el confirmador optimizado para S3 de EMRFS, asegúrese de seguir las prácticas recomendadas para la administración de cargas multiparte con errores. Para obtener más información, consulte [Prácticas recomendadas](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-plan-upload-s3.html#emr-bucket-bestpractices) para trabajar con buckets de Amazon S3 en la *Guía de administración de Amazon EMR*.

# Consideraciones sobre el ajuste de trabajos
<a name="emr-spark-committer-tuning"></a>

El confirmador optimizado para S3 de EMRFS consume una pequeña cantidad de memoria por cada archivo escrito por un intento de tarea hasta que la tarea se confirma o se anula. En la mayoría de los trabajos, la cantidad de memoria consumida es insignificante. En los trabajos que tienen tareas de ejecución prolongada que escriben un gran número de archivos, la memoria que consume el confirmador puede ser apreciable y requerir algunos ajustes de la memoria asignada a los ejecutores de Spark. Puede ajustar la memoria del ejecutor mediante la propiedad `spark.executor.memory`. Como pauta general, una sola tarea que escribe 100 000 archivos, normalmente requerirá 100 MB de memoria adicionales. Para obtener más información, consulte [Application properties](https://spark.apache.org/docs/latest/configuration.html#application-properties) en la documentación de configuración de Apache Spark.

# Habilitación del confirmador optimizado para S3 de EMRFS para Amazon EMR 5.19.0
<a name="emr-spark-committer-enable"></a>

Si utiliza Amazon EMR 5.19.0, puede establecer manualmente la propiedad `spark.sql.parquet.fs.optimized.committer.optimization-enabled` en `true` al crear un clúster o desde Spark si está utilizando Amazon EMR.

## Habilitación del confirmador optimizado para S3 de EMRFS al crear un clúster
<a name="w2aac62c61c17c13b5"></a>

Utilice la clasificación de configuración `spark-defaults` para establecer la propiedad `spark.sql.parquet.fs.optimized.committer.optimization-enabled` en `true`. Para obtener más información, consulte [Configuración de aplicaciones](emr-configure-apps.md).

## Habilitación del confirmador optimizado para S3 de EMRFS desde Spark
<a name="w2aac62c61c17c13b7"></a>

Puede establecer la propiedad `spark.sql.parquet.fs.optimized.committer.optimization-enabled` en `true` codificándola de forma rígida en un `SparkConf`, pasándola como un parámetro `--conf` en el shell de Spark o las herramientas `spark-submit` y `spark-sql`, o en `conf/spark-defaults.conf`. Para obtener más información, consulte [Spark configuration](https://spark.apache.org/docs/latest/configuration.html) en la documentación de Apache Spark.

En el siguiente ejemplo, se muestra cómo activar el confirmador mientras se ejecuta un comando spark-sql.

```
spark-sql \
  --conf spark.sql.parquet.fs.optimized.committer.optimization-enabled=true \
  -e "INSERT OVERWRITE TABLE target_table SELECT * FROM source_table;"
```

# Uso del protocolo de confirmación optimizado para S3 de EMRFS
<a name="emr-spark-s3-optimized-commit-protocol"></a>

El protocolo de confirmación optimizado para S3 para EMRFS es una [FileCommitProtocol](https://spark.apache.org/docs/2.2.0//api/java/org/apache/spark/internal/io/FileCommitProtocol.html)implementación alternativa que está optimizada para escribir archivos con la sobrescritura dinámica de particiones de Spark en Amazon S3 cuando se usa EMRFS. El protocolo mejora el rendimiento de las aplicaciones al evitar las operaciones de cambio de nombre en Amazon S3 durante la fase de confirmación de los trabajos de sobrescritura de particiones dinámicas de Spark. 

Tenga en cuenta que el [confirmador optimizado para S3 de EMRFS](emr-spark-s3-optimized-committer.html) también mejora el rendimiento al evitar las operaciones de cambio de nombre. Sin embargo, no funciona para los casos de sobrescritura de particiones dinámicas, mientras que las mejoras del protocolo de confirmación solo se dirigen a los casos de sobrescritura de particiones dinámicas.

El protocolo de confirmación está disponible con la versión 5.30.0 y posteriores y 6.2.0 y posteriores de Amazon EMR y está habilitado de forma predeterminada. Amazon EMR agregó una mejora de paralelismo a partir de la versión 5.31.0. El protocolo se utiliza para los trabajos de Spark que utilizan Spark o Datasets. DataFrames Existen circunstancias en las cuales no se utiliza el protocolo de confirmación. Para obtener más información, consulte [Requisitos del protocolo de confirmación optimizado para S3 de EMRFS](emr-spark-committer-reqs.md).

**Topics**
+ [Requisitos del protocolo de confirmación optimizado para S3 de EMRFS](emr-spark-commit-protocol-reqs.md)
+ [El protocolo de confirmación optimizado para S3 de EMRFS y las cargas multiparte](emr-spark-commit-protocol-multipart.md)
+ [Consideraciones sobre el ajuste de trabajos](emr-spark-commit-protocol-tuning.md)

# Requisitos del protocolo de confirmación optimizado para S3 de EMRFS
<a name="emr-spark-commit-protocol-reqs"></a>

El protocolo de confirmación optimizado para S3 de EMRFS se utiliza cuando se cumplen las siguientes condiciones:
+ Ejecutas trabajos de Spark que usan Spark o Datasets para sobrescribir tablas particionadas. DataFrames
+ Ejecuta trabajos de Spark cuyo modo de sobrescritura de particiones es `dynamic`.
+ Las cargas multiparte están habilitadas en Amazon EMR. Esta es la opción predeterminada. Para obtener más información, consulte [El protocolo de confirmación optimizado para S3 de EMRFS y las cargas multiparte](emr-spark-commit-protocol-multipart.md). 
+ La caché del sistema de archivos para EMRFS está habilitada. Es el valor predeterminado. Compruebe que la configuración `fs.s3.impl.disable.cache` esté establecida en `false`. 
+ Se utiliza la compatibilidad de orígenes de datos integrados de Spark. La compatibilidad de orígenes de datos integrados se utiliza en las siguientes circunstancias:
  + Cuando los trabajos escriben en orígenes de datos o tablas integrados.
  + Cuando los trabajos escriben en tablas Parquet del metaalmacén de Hive. Esto sucede cuando `spark.sql.hive.convertInsertingPartitionedTable` y `spark.sql.hive.convertMetastoreParquet` se establecen en true. Esta es la configuración predeterminada.
  + Cuando los trabajos escriben en tablas ORC del metaalmacén de Hive. Esto sucede cuando `spark.sql.hive.convertInsertingPartitionedTable` y `spark.sql.hive.convertMetastoreOrc` se establecen en `true`. Esta es la configuración predeterminada.
+ Las operaciones de trabajos de Spark que escriben en una ubicación de partición predeterminada (por ejemplo, `${table_location}/k1=v1/k2=v2/`) utilizan el protocolo de confirmación. El protocolo no se utiliza si una operación de trabajo escribe en una ubicación de partición personalizada, por ejemplo, si una ubicación de partición personalizada se establece con el comando `ALTER TABLE SQL`.
+ Se deben utilizar los valores siguientes para Spark:
  + `spark.sql.sources.commitProtocolClass` se debe establecer en `org.apache.spark.sql.execution.datasources.SQLEmrOptimizedCommitProtocol`. Esta es la configuración predeterminada para las versiones 5.30.0 y posteriores y 6.2.0 y posteriores de Amazon EMR. 
  + La opción de escritura `partitionOverwriteMode` o `spark.sql.sources.partitionOverwriteMode` debe estar establecida en `dynamic`. El ajuste predeterminado es `static`.
**nota**  
La opción de escritura `partitionOverwriteMode` se introdujo en Spark 2.4.0. En el caso de la versión 2.3.2 de Spark, incluida con la versión 5.19.0 de Amazon EMR, establezca la propiedad `spark.sql.sources.partitionOverwriteMode`. 
  + Si los trabajos de Spark sobrescriben en la tabla Parquet del metaalmacén de Hive, `spark.sql.hive.convertMetastoreParquet`, `spark.sql.hive.convertInsertingPartitionedTable` y `spark.sql.hive.convertMetastore.partitionOverwriteMode` debe establecerse en `true`. Esta es la configuración predeterminada. 
  + Si los trabajos de Spark sobrescriben en la tabla ORC del metaalmacén de Hive, `spark.sql.hive.convertMetastoreOrc`, `spark.sql.hive.convertInsertingPartitionedTable` y `spark.sql.hive.convertMetastore.partitionOverwriteMode` debe establecerse en `true`. Esta es la configuración predeterminada.

**Example – Modo de sobrescritura de partición dinámica**  
En este ejemplo de Scala, se activa la optimización. En primer lugar, establece la propiedad `partitionOverwriteMode` en `dynamic`. Esto solo sobrescribe las particiones en las que escribe datos. A continuación, especifica las columnas de particiones dinámicas mediante `partitionBy` y establece el modo de escritura en `overwrite`.  

```
val dataset = spark.range(0, 10)
  .withColumn("dt", expr("date_sub(current_date(), id)"))

dataset.write.mode("overwrite")                 // "overwrite" instead of "insert"
  .option("partitionOverwriteMode", "dynamic")  // "dynamic" instead of "static"  
  .partitionBy("dt")                            // partitioned data instead of unpartitioned data
  .parquet("s3://amzn-s3-demo-bucket1/output")    // "s3://" to use Amazon EMR file system, instead of "s3a://" or "hdfs://"
```

## Cuando no se utiliza el protocolo de confirmación optimizado para S3 de EMRFS
<a name="emr-spark-commit-protocol-reqs-anti"></a>

Por lo general, el protocolo de confirmación optimizado para S3 de EMRFS funciona igual que el protocolo de confirmación de Spark predeterminado de código abierto, `org.apache.spark.sql.execution.datasources.SQLHadoopMapReduceCommitProtocol`. La optimización no se producirá en las siguientes situaciones.


****  

| Situación | Por qué no se utiliza el protocolo de confirmación | 
| --- | --- | 
| Cuando escribe en HDFS | El protocolo de confirmación solo admite la escritura en Amazon S3 mediante EMRFS. | 
| Cuando utiliza el sistema de archivos S3A | El protocolo de confirmación solo admite EMRFS. | 
| Cuando utilizas la MapReduce API RDD de Spark | El protocolo de confirmación solo admite el uso de SparkSQL o DataFrame Dataset. APIs | 
| Cuando no se activa la sobrescritura de particiones dinámicas | El protocolo de confirmación solo optimiza los casos de sobrescritura de particiones dinámicas. Para los demás casos, consulte [Uso del confirmador optimizado para S3 de EMRFS](emr-spark-s3-optimized-committer.md). | 

En los siguientes ejemplos de Scala se muestran algunas situaciones adicionales en las que el protocolo de confirmación optimizado para S3 de EMRFS delega en `SQLHadoopMapReduceCommitProtocol`.

**Example – Modo de sobrescritura de particiones dinámica con ubicación de partición personalizada**  
En este ejemplo, los programas de Scala sobrescriben dos particiones en el modo de sobrescritura de particiones dinámicas. Una partición tiene una ubicación de partición personalizada. La otra partición utiliza la ubicación de partición predeterminada. El protocolo de confirmación optimizado para S3 de EMRFS solo mejora la partición que utiliza la ubicación de partición predeterminada.  

```
val table = "dataset"
val inputView = "tempView"
val location = "s3://bucket/table"
                            
spark.sql(s"""
  CREATE TABLE $table (id bigint, dt date) 
  USING PARQUET PARTITIONED BY (dt) 
  LOCATION '$location'
""")

// Add a partition using a custom location
val customPartitionLocation = "s3://bucket/custom"
spark.sql(s"""
  ALTER TABLE $table ADD PARTITION (dt='2019-01-28') 
  LOCATION '$customPartitionLocation'
""")

// Add another partition using default location
spark.sql(s"ALTER TABLE $table ADD PARTITION (dt='2019-01-29')")

def asDate(text: String) = lit(text).cast("date")   
                       
spark.range(0, 10)
  .withColumn("dt",
    when($"id" > 4, asDate("2019-01-28")).otherwise(asDate("2019-01-29")))
  .createTempView(inputView)
  
// Set partition overwrite mode to 'dynamic'
spark.sql(s"SET spark.sql.sources.partitionOverwriteMode=dynamic")
  
spark.sql(s"INSERT OVERWRITE TABLE $table SELECT * FROM $inputView")
```
El código de Scala crea los siguientes objetos de Amazon S3:  

```
custom/part-00001-035a2a9c-4a09-4917-8819-e77134342402.c000.snappy.parquet
custom_$folder$
table/_SUCCESS
table/dt=2019-01-29/part-00000-035a2a9c-4a09-4917-8819-e77134342402.c000.snappy.parquet
table/dt=2019-01-29_$folder$
table_$folder$
```
Escribir en ubicaciones de particiones personalizadas en versiones anteriores de Spark puede provocar la pérdida de datos. En este ejemplo, la partición `dt='2019-01-28'` se perdería. Para obtener más información, consulte [SPARK-35106](https://issues.apache.org/jira/browse/SPARK-35106). Esto se corrigió en la versión 5.33.0 y posteriores de Amazon EMR, excluidas las 6.0.x y 6.1.x.

Al escribir en particiones de ubicaciones personalizadas, Spark utiliza un algoritmo de confirmación similar al del ejemplo anterior, que se detalla a continuación. Como ocurre en el ejemplo anterior, el algoritmo da como resultado cambios de nombre secuenciales, lo que puede afectar negativamente al rendimiento.

El algoritmo de Spark 2.4.0 sigue estos pasos:

1. Al escribir la salida en una partición de una ubicación personalizada, las tareas escriben en un archivo del directorio de ensayo de Spark, que se crea en la ubicación de salida final. El nombre del archivo incluye un UUID aleatorio para proteger contra las colisiones de archivo. La tarea intenta mantener un seguimiento de cada archivo junto con la ruta de salida deseada final.

1. Cuando una tarea se completa de forma satisfactoria, proporciona al controlador los archivos y las rutas de salida deseada final.

1. Una vez completadas todas las tareas, la fase de confirmación de trabajo cambia el nombre de forma secuencial de todos los archivos que se escribieron para particiones en ubicaciones personalizadas en sus rutas de salida finales.

1. El directorio de ensayo se elimina antes de que se complete la fase de confirmación de trabajo.

# El protocolo de confirmación optimizado para S3 de EMRFS y las cargas multiparte
<a name="emr-spark-commit-protocol-multipart"></a>

Para utilizar la optimización de la sobrescritura de particiones dinámicas en el protocolo de confirmación optimizado para S3 de EMRFS, las cargas multiparte deben estar habilitadas en Amazon EMR. Las cargas multiparte están habilitadas de forma predeterminada. Puede volver a habilitarlas si es necesario. Para obtener más información, consulte [Configuración de carga multiparte para Amazon S3](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-plan-upload-s3.html#Config_Multipart) en la *Guía de administración de Amazon EMR*. 

Durante la sobrescritura de particiones dinámicas, el protocolo de confirmación optimizado para S3 de EMRFS utiliza las características similares a las transacciones de las cargas multiparte para garantizar que los archivos escritos por los intentos de tareas solo aparecen en la ubicación de salida del trabajo al confirmar las tareas. Al utilizar las cargas multiparte de este modo, el protocolo de confirmación mejora el rendimiento de las confirmaciones de trabajos en comparación con la opción predeterminada `SQLHadoopMapReduceCommitProtocol`. Cuando se utiliza el protocolo de confirmación optimizado para S3 de EMRFS, hay algunas diferencias clave que lo distinguen del comportamiento tradicional de las cargas multiparte y que hay que tener en cuenta:
+ Las cargas multiparte siempre se llevan a cabo independientemente del tamaño del archivo. Esto difiere del comportamiento predeterminado de EMRFS, donde la propiedad `fs.s3n.multipart.uploads.split.size` controla el tamaño del archivo en el que se activan las cargas multiparte.
+ Las cargas multiparte se dejan en un estado incompleto durante un periodo de tiempo más prolongado hasta que la tarea se confirma o se anula. Esto difiere del comportamiento predeterminado de EMRFS, donde una carga multiparte se completa cuando una tarea termina de escribir un determinado archivo.

Debido a estas diferencias, si la JVM de un ejecutor de Spark se bloquea o se termina mientras hay tareas ejecutándose y escribiendo datos en Amazon S3, o la JVM de un controlador de Spark se bloquea o se termina durante la ejecución de un trabajo, es más probable que queden cargas multiparte incompletas sin finalizar. Por este motivo, cuando utilice el protocolo de confirmación optimizado para S3 de EMRFS, asegúrese de seguir las prácticas recomendadas para la administración de cargas multiparte con errores. Para obtener más información, consulte [Prácticas recomendadas](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-plan-upload-s3.html#emr-bucket-bestpractices) para trabajar con buckets de Amazon S3 en la *Guía de administración de Amazon EMR*.

# Consideraciones sobre el ajuste de trabajos
<a name="emr-spark-commit-protocol-tuning"></a>

En los ejecutores de Spark, el protocolo de confirmación optimizado para S3 de EMRFS consume una pequeña cantidad de memoria por cada archivo escrito por un intento de tarea hasta que la tarea se confirma o se anula. En la mayoría de los trabajos, la cantidad de memoria consumida es insignificante. 

En los controladores de Spark, el protocolo de confirmación optimizado para S3 de EMRFS requiere memoria para almacenar la información de los metadatos de cada archivo confirmado hasta que el trabajo se confirma o se anula. En la mayoría de los trabajos, la configuración de memoria predeterminada del controlador de Spark es insignificante. 

En los trabajos que tienen tareas de ejecución prolongada y que escriben un gran número de archivos, la memoria que consume el protocolo de confirmación puede ser apreciable y requerir algunos ajustes de la memoria asignada a Spark, especialmente a los ejecutores de Spark. Puede ajustar la memoria mediante la propiedad `spark.driver.memory` para los controladores de Spark y la propiedad `spark.executor.memory` para los ejecutores de Spark. Como pauta general, una sola tarea que escribe 100 000 archivos, normalmente requerirá 100 MB de memoria adicionales. Para obtener más información, consulte [Application properties](https://spark.apache.org/docs/latest/configuration.html#application-properties) en la documentación de configuración de Apache Spark.

# Reintento de solicitudes de Amazon S3 con EMRFS
<a name="emr-spark-emrfs-retry"></a>

En este tema se proporciona información sobre las estrategias de reintentos que puede utilizar al realizar solicitudes a Amazon S3 con EMRFS. Cuando la tasa de solicitudes aumenta, S3 intenta escalar para dar cabida a la nueva tasa. Durante este proceso, S3 puede limitar las solicitudes y devolver un error `503 Slow Down`. Para mejorar la tasa de éxito de las solicitudes de S3, puede configurar las propiedades de la configuración `emrfs-site` para ajustar la estrategia de reintentos.

Puede ajustar la estrategia de reintentos de las siguientes maneras.
+ Aumente el límite máximo de reintentos para la estrategia de reintentos de retroceso exponencial predeterminada.
+ Habilite y configure la estrategia de reintentos de aumento aditivo/disminución multiplicativa (AIMD). AIMD es compatible con la versión 6.4.0 y posteriores de Amazon EMR.

## Uso de la estrategia de retroceso exponencial predeterminada
<a name="emr-spark-emrfs-retry-exponential-backoff"></a>

De forma predeterminada, EMRFS utiliza una estrategia de retroceso exponencial para reintentar las solicitudes de Amazon S3. El límite de reintentos de EMRFS predeterminado es de 15. Para evitar un error `503 Slow Down` de S3, puede aumentar el límite de reintentos al crear un clúster nuevo, en un clúster en ejecución o durante el tiempo de ejecución de la aplicación.

Para aumentar el límite de reintentos, debe cambiar el valor de `fs.s3.maxRetries` de la configuración `emrfs-site`. En el siguiente ejemplo de configuración se establece `fs.s3.maxRetries` en un valor personalizado de 30.

```
[
    {
      "Classification": "emrfs-site",
      "Properties": {
        "fs.s3.maxRetries": "30"
      }
    }
]
```

Para obtener información acerca del uso de objetos de configuración, consulte [Configuración de aplicaciones](emr-configure-apps.md).

## Uso de la estrategia de reintentos de AIMD
<a name="emr-spark-emrfs-retry-aimd"></a>

Con la versión 6.4.0 y posteriores de Amazon EMR, EMRFS admite una estrategia de reintentos alternativa basada en un modelo de aumento aditivo/disminución multiplicativa (AIMD). La estrategia de reintentos de AIMD resulta especialmente útil cuando se trabaja con clústeres grandes de Amazon EMR.

AIMD calcula una tasa de solicitudes personalizada a partir de los datos sobre las solicitudes recientes que se han realizado correctamente. Esta estrategia reduce el número de solicitudes limitadas y el total de intentos necesarios por solicitud.

Para habilitar la estrategia de reintentos de AIMD, debe establecer la propiedad `fs.s3.aimd.enabled` en `true` en la configuración `emrfs-site`, como en el siguiente ejemplo.

```
[
    {
      "Classification": "emrfs-site",
      "Properties": {
        "fs.s3.aimd.enabled": "true"
      }
    }
]
```

Para obtener información acerca del uso de objetos de configuración, consulte [Configuración de aplicaciones](emr-configure-apps.md).

## Configuración avanzada de reintentos de AIMD
<a name="emr-spark-emrfs-retry-advanced-properties"></a>

Puede configurar las propiedades que se muestran en la siguiente tabla para refinar el comportamiento de los reintentos al utilizar la estrategia de reintentos de AIMD. Para la mayoría de los casos de uso, le recomendamos que utilice los valores predeterminados.


**Propiedades avanzadas de la estrategia de reintentos de AIMD**  

| Propiedad | Predeterminado | Description (Descripción) | 
| --- | --- | --- | 
| fs.s3.aimd.increaseIncrement | 0.1 | Controla la rapidez con la que aumenta la tasa de solicitudes cuando las solicitudes consecutivas se realizan correctamente. | 
| fs.s3.aimd.reductionFactor | 2 | Controla la rapidez con la que disminuye la tasa de solicitudes cuando Amazon S3 devuelve una respuesta 503. El factor predeterminado de 2 reduce la tasa de solicitudes a la mitad. | 
| fs.s3.aimd.minRate | 0.1 | Establece el límite inferior de la tasa de solicitudes cuando las solicitudes sufren una limitación constante por parte de S3. | 
| fs.s3.aimd.initialRate | 5500 | Establece la tasa de solicitudes inicial, que luego cambia según los valores que especifique para fs.s3.aimd.increaseIncrement y fs.s3.aimd.reductionFactor.La tasa inicial también se usa para las solicitudes GET y se escala de forma proporcional (3500/5500) para las solicitudes PUT. | 
| fs.s3.aimd.adjustWindow | 2 | Controla la frecuencia con la que se ajusta la tasa de solicitudes, medida en número de respuestas. | 
| fs.s3.aimd.maxAttempts | 100 | Establece el número máximo de intentos para intentar una solicitud. | 

# Adición de un paso de Spark
<a name="emr-spark-submit-step"></a>

Puede utilizar los pasos de Amazon EMR para enviar trabajo al marco de Spark instalado en un clúster de EMR. Para obtener más información, consulte [Pasos](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-overview.html#emr-overview-data-processing) en la Guía de administración de Amazon EMR. En la consola y la interfaz de línea de comandos, puede hacerlo a través de un paso de la aplicación Spark, que ejecuta el script `spark-submit` como un paso en su nombre. Con la API, utilice un paso para invocar `spark-submit` utilizando `command-runner.jar`.

Para obtener más información acerca de cómo enviar aplicaciones a Spark, consulte [Submitting applications](https://spark.apache.org/docs/latest/submitting-applications.html) en la documentación de Apache Spark.

**Para enviar un paso de Spark utilizando la consola**

1. [Abra la consola Amazon EMR en https://console.aws.amazon.com /emr.](https://console.aws.amazon.com/emr/)

1. En **Cluster List (Lista de clústeres)**, elija el nombre del clúster.

1. Desplácese hasta la sección **Steps (Pasos)** y amplíela; a continuación, elija **Add step (Añadir paso)**.

1. En el cuadro de diálogo **Add Step (Añadir paso)**:
   + En **Step type (Tipo de paso)**, elija **Spark application (Aplicación de Spark)**.
   + En **Name (Nombre)**, acepte el nombre predeterminado (Aplicación de Spark) o escriba un nombre nuevo.
   + En **Deploy mode (Modo de implementación)**, elija el modo **Client (Cliente)** o **Cluster (Clúster)**. El modo de cliente lanza el programa de controlador en la instancia principal del clúster, mientras que el modo de clúster lanza el programa de controlador en el clúster. En el modo de cliente, la salida del registro del controlador aparece en los registros de pasos, mientras que en el modo de clúster, la salida del registro del controlador aparece en los registros del primer contenedor de YARN. Para obtener más información, consulte [Cluster mode overview](https://spark.apache.org/docs/latest/cluster-overview.html) en la documentación de Apache Spark.
   + Especifique el valor deseado de **Spark-submit options (Opciones de spark-submit)**. Para obtener más información sobre las opciones de `spark-submit`, consulte [Launching applications with spark-submit](https://spark.apache.org/docs/latest/submitting-applications.html#launching-applications-with-spark-submit).
   + En **Application location (Ubicación de la aplicación)**, especifique la ruta local o el URI de S3 de la aplicación.
   + En **Arguments (Argumentos)**, deje el campo en blanco.
   + En **Action on failure (Acción sobre el error)**, acepte la opción predeterminada, **Continue (Continuar)**.

1. Elija **Añadir**. El paso aparece en la consola con el estado Pending (Pendiente). 

1. El estado del paso cambia de **Pending (Pendiente)** a **Running (En ejecución)** y a **Completed (Completado)** a medida que se ejecuta. Para actualizar el estado, elija el icono **Refresh (Actualizar)** situado encima de la columna **Actions (Acciones)**. 

1. Los resultados del paso se encuentran en la página Detalles del clúster de la consola de Amazon EMR junto a su paso en **Archivos de registro** si ha configurado el registro. Si lo desea, puede encontrar información sobre el paso en el bucket de registro que configuró al lanzar el clúster. 

**Para enviar un trabajo a Spark utilizando el AWS CLI**

Envíe un paso al crear el clúster o utilice el subcomando `aws emr add-steps` en un clúster existente. 

1. Use `create-cluster` como se muestra en el ejemplo siguiente.
**nota**  
Se incluyen caracteres de continuación de línea de Linux (\$1) para facilitar la lectura. Se pueden eliminar o utilizar en los comandos de Linux. En Windows, elimínelos o sustitúyalos por un signo de intercalación (^).

   ```
   aws emr create-cluster --name "Add Spark Step Cluster" --release-label emr-7.12.0 --applications Name=Spark \
   --ec2-attributes KeyName=myKey --instance-type m5.xlarge --instance-count 3 \
   --steps Type=Spark,Name="Spark Program",ActionOnFailure=CONTINUE,Args=[--class,org.apache.spark.examples.SparkPi,/usr/lib/spark/examples/jars/spark-examples.jar,10] --use-default-roles
   ```

   También puede usar `command-runner.jar` como se muestra en el siguiente ejemplo.

   ```
   aws emr create-cluster --name "Add Spark Step Cluster" --release-label emr-7.12.0 \
   --applications Name=Spark --ec2-attributes KeyName=myKey --instance-type m5.xlarge --instance-count 3 \
   --steps Type=CUSTOM_JAR,Name="Spark Program",Jar="command-runner.jar",ActionOnFailure=CONTINUE,Args=[spark-example,SparkPi,10] --use-default-roles
   ```
**nota**  
Se incluyen caracteres de continuación de línea de Linux (\$1) para facilitar la lectura. Se pueden eliminar o utilizar en los comandos de Linux. En Windows, elimínelos o sustitúyalos por un signo de intercalación (^).

1. Como alternativa, añada los pasos a un clúster ya en ejecución. Utilice `add-steps`.

   ```
   aws emr add-steps --cluster-id j-2AXXXXXXGAPLF --steps Type=Spark,Name="Spark Program",ActionOnFailure=CONTINUE,Args=[--class,org.apache.spark.examples.SparkPi,/usr/lib/spark/examples/jars/spark-examples.jar,10]
   ```

   También puede usar `command-runner.jar` como se muestra en el siguiente ejemplo.

   ```
   aws emr add-steps --cluster-id j-2AXXXXXXGAPLF --steps Type=CUSTOM_JAR,Name="Spark Program",Jar="command-runner.jar",ActionOnFailure=CONTINUE,Args=[spark-example,SparkPi,10]
   ```

**Para enviar trabajo a Spark mediante el SDK para Java**

1. En el siguiente ejemplo se muestra cómo agregar un paso a un clúster con Spark mediante Java.

   ```
   AWSCredentials credentials = new BasicAWSCredentials(accessKey, secretKey);
   AmazonElasticMapReduce emr = new AmazonElasticMapReduceClient(credentials);
    
   StepFactory stepFactory = new StepFactory();
   AmazonElasticMapReduceClient emr = new AmazonElasticMapReduceClient(credentials);
   AddJobFlowStepsRequest req = new AddJobFlowStepsRequest();
   req.withJobFlowId("j-1K48XXXXXXHCB");
   
   List<StepConfig> stepConfigs = new ArrayList<StepConfig>();
   		
   HadoopJarStepConfig sparkStepConf = new HadoopJarStepConfig()
   			.withJar("command-runner.jar")
   			.withArgs("spark-submit","--executor-memory","1g","--class","org.apache.spark.examples.SparkPi","/usr/lib/spark/examples/jars/spark-examples.jar","10");			
   		
   StepConfig sparkStep = new StepConfig()
   			.withName("Spark Step")
   			.withActionOnFailure("CONTINUE")
   			.withHadoopJarStep(sparkStepConf);
   
   stepConfigs.add(sparkStep);
   req.withSteps(stepConfigs);
   AddJobFlowStepsResult result = emr.addJobFlowSteps(req);
   ```

1. Vea los resultados del paso examinando los registros del paso. Para ello, Consola de administración de AWS si has activado el registro, selecciona **Pasos**, selecciona tu paso y, en el caso de los **archivos de registro**, elige una de las dos `stdout` opciones`stderr`. Para ver los registros disponibles, elija **View Logs (Ver registros)**.

## Anulación de las opciones de configuración predeterminadas de Spark
<a name="dynamic-configuration"></a>

Es posible que desee anular los valores de configuración predeterminados de Spark por aplicación. Puede hacerlo cuando envíe aplicaciones utilizando un paso, que básicamente transfiere opciones a `spark-submit`. Por ejemplo, es posible que desee cambiar la memoria asignada a un proceso de ejecutor cambiando `spark.executor.memory`. Suministraría el modificador `--executor-memory` con un argumento como el siguiente:

```
spark-submit --executor-memory 1g --class org.apache.spark.examples.SparkPi /usr/lib/spark/examples/jars/spark-examples.jar 10
```

Del mismo modo, puede ajustar `--executor-cores` y `--driver-memory`. En un paso, debería proporcionar los siguientes argumentos al paso:

```
--executor-memory 1g --class org.apache.spark.examples.SparkPi /usr/lib/spark/examples/jars/spark-examples.jar 10
```

También puede ajustar la configuración que puede no tener un modificador integrado utilizando la opción `--conf`. Para obtener más información sobre otras opciones que se pueden ajustar, consulte el tema [Dynamically loading Spark properties](https://spark.apache.org/docs/latest/configuration.html#dynamically-loading-spark-properties) en la documentación de Apache Spark.

# Visualización del historial de aplicaciones de Spark
<a name="emr-spark-application-history"></a>

Puede ver los detalles de la interfaz de usuario de Tez, las aplicaciones de YARN y Spark mediante la pestaña **Interfaces de usuario de aplicaciones** de la página de detalles de un clúster en la consola. Las interfaces de usuario (IU) de aplicaciones de Amazon EMR le facilitan la resolución de problemas y el análisis de los trabajos activos y el historial de trabajos.

Para obtener más información, consulte [Ver el historial de aplicaciones](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-cluster-application-history.html) en la *Guía de administración de Amazon EMR*.

# Accede a la web de Spark UIs
<a name="emr-spark-webui"></a>

Para ver la web UIs de Spark, siga los procedimientos para crear un túnel SSH o un proxy en la sección denominada [Conectar al clúster de la](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-connect-master-node.html) Guía de administración de Amazon EMR y, a continuación, vaya al ResourceManager YARN de su clúster. Elija el enlace de la aplicación en **Tracking UI (IU de seguimiento)**. Si la aplicación está en ejecución, verá. **ApplicationMaster** Esto le lleva a la IU web del nodo principal de la aplicación en el puerto 20888 donde se encuentra el controlador. El controlador podría estar situado en el nodo principal del clúster si se ejecuta en modo de cliente de YARN. Si ejecuta una aplicación en el modo de clúster de YARN, el controlador se encuentra en el ApplicationMaster correspondiente a la aplicación del clúster. Si tu aplicación ha finalizado, verás el **Historial**, que te llevará al número de puerto de la HistoryServer interfaz de usuario de Spark, 18080, del nodo principal del clúster de EMR. Esto es para aplicaciones que ya se han completado. También puedes ir a la HistoryServer interfaz de usuario de Spark directamente en http: //:18080/. *master-public-dns-name*

Con la versión 5.25.0 y posteriores de Amazon EMR, puede acceder a la interfaz de usuario del servidor del historial de Spark desde la consola sin configurar un proxy web a través de una conexión SSH. Para obtener más información, consulte [Ver interfaces de usuario de aplicaciones persistentes](https://docs.aws.amazon.com/emr/latest/ManagementGuide/app-history-spark-UI.html).

# Uso del conector Amazon Kinesis Data Streams de streaming estructurado de Spark
<a name="emr-spark-structured-streaming-kinesis"></a>

Las versiones 7.1.0 y posteriores de Amazon EMR incluyen un conector de Amazon Kinesis Data Streams de streaming estructurado Spark en la imagen de la versión. Con este conector, puede usar Spark en Amazon EMR para procesar los datos que están almacenados en Amazon Kinesis Data Streams. El conector admite tanto los tipos de consumidores `GetRecords` (rendimiento compartido) como `SubscribeToShard` (distribución mejorada). Esta integración se basa en [https://github.com/awslabs/spark-sql-kinesis-connector](https://github.com/awslabs/spark-sql-kinesis-connector). Para obtener información detallada sobre cómo empezar a utilizar el conector, consulte el [README](https://github.com/awslabs/spark-sql-kinesis-connector/blob/main/README.md).

En el siguiente ejemplo, se muestra cómo utilizar el conector para iniciar una aplicación Spark con Amazon EMR.

```
spark-submit my_kinesis_streaming_script.py
```

# Uso de la integración de Amazon Redshift para Apache Spark con Amazon EMR
<a name="emr-spark-redshift"></a>

Con la versión 6.4.0 y posteriores de Amazon EMR, la imagen de cada versión incluye un conector entre [Apache Spark](https://aws.amazon.com/emr/features/spark/) y Amazon Redshift. Con este conector, puede usar Spark en Amazon EMR para procesar los datos almacenados en Amazon Redshift. En el caso de las versiones 6.4.0 a 6.8.0 de Amazon EMR, la integración se basa en el [conector de código abierto `spark-redshift`](https://github.com/spark-redshift-community/spark-redshift#readme). En el caso de las versiones 6.9.0 y posteriores de Amazon EMR, la [integración de Amazon Redshift para Apache Spark](https://docs.aws.amazon.com/redshift/latest/mgmt/spark-redshift-connector.html) se ha migrado de la versión de la comunidad a una integración nativa. 

**Topics**
+ [Lanzamiento de una aplicación de Spark mediante la integración de Amazon Redshift para Apache Spark](emr-spark-redshift-launch.md)
+ [Autenticación con la integración de Amazon Redshift para Apache Spark](emr-spark-redshift-auth.md)
+ [Lectura y escritura desde y hacia Amazon Redshift](emr-spark-redshift-readwrite.md)
+ [Consideraciones y limitaciones al utilizar el conector de Spark](emr-spark-redshift-considerations.md)

# Lanzamiento de una aplicación de Spark mediante la integración de Amazon Redshift para Apache Spark
<a name="emr-spark-redshift-launch"></a>

En el caso de las versiones 6.4 a 6.9 de Amazon EMR, debe usar la opción `--jars` o `--packages` para especificar cuáles de los siguientes archivos JAR desea usar. La opción `--jars` especifica las dependencias almacenadas localmente, en HDFS o mediante HTTP/S. Para ver otras ubicaciones de archivos compatibles con la opción `--jars`, consulte la sección [Advanced Dependency Management](https://spark.apache.org/docs/latest/submitting-applications.html#advanced-dependency-management) en la documentación de Spark. La opción `--packages` especifica las dependencias almacenadas en el repositorio público de Maven. 
+ `spark-redshift.jar`
+ `spark-avro.jar`
+ `RedshiftJDBC.jar`
+ `minimal-json.jar`

Las versiones 6.10.0 y posteriores de Amazon EMR no requieren la dependencia `minimal-json.jar` e instalan automáticamente las demás dependencias en cada clúster de forma predeterminada. En los siguientes ejemplos se muestra cómo lanzar una aplicación de Spark con la integración de Amazon Redshift para Apache Spark.

------
#### [ Amazon EMR 6.10.0 \$1 ]

En el siguiente ejemplo se muestra cómo lanzar una aplicación de Spark con el conector `spark-redshift` con las versiones 6.10 y posteriores de Amazon EMR.

```
spark-submit my_script.py
```

------
#### [ Amazon EMR 6.4.0 - 6.9.x ]

Para lanzar una aplicación de Spark con el conector `spark-redshift` en las versiones 6.4 a 6.9 de Amazon EMR, debe usar la opción `--jars` o `--packages`, como se muestra en el siguiente ejemplo. Tenga en cuenta que las rutas enumeradas con la opción `--jars` son las rutas predeterminadas para los archivos JAR.

```
spark-submit \
  --jars /usr/share/aws/redshift/jdbc/RedshiftJDBC.jar,/usr/share/aws/redshift/spark-redshift/lib/spark-redshift.jar,/usr/share/aws/redshift/spark-redshift/lib/spark-avro.jar,/usr/share/aws/redshift/spark-redshift/lib/minimal-json.jar \
  my_script.py
```

------

# Autenticación con la integración de Amazon Redshift para Apache Spark
<a name="emr-spark-redshift-auth"></a>

## AWS Secrets Manager Utilización para recuperar credenciales y conectarse a Amazon Redshift
<a name="emr-spark-redshift-secrets"></a>

El siguiente ejemplo de código muestra cómo recuperar credenciales AWS Secrets Manager para conectarse a un clúster de Amazon Redshift con la PySpark interfaz de Apache Spark en Python.

```
from pyspark.sql import SQLContext
import boto3

sc = # existing SparkContext
sql_context = SQLContext(sc)

secretsmanager_client = boto3.client('secretsmanager')
secret_manager_response = secretsmanager_client.get_secret_value(
    SecretId='string',
    VersionId='string',
    VersionStage='string'
)
username = # get username from secret_manager_response
password = # get password from secret_manager_response
url = "jdbc:redshift://redshifthost:5439/database?user=" + username + "&password=" + password

# Read data from a table
df = sql_context.read \
    .format("io.github.spark_redshift_community.spark.redshift") \
    .option("url", url) \
    .option("dbtable", "my_table") \
    .option("tempdir", "s3://path/for/temp/data") \
    .load()
```

## Uso de IAM para recuperar credenciales y conectarse a Amazon Redshift
<a name="emr-spark-redshift-iam"></a>

Puede utilizar el controlador JDBC versión 2 proporcionado por Amazon Redshift para conectarse a Amazon Redshift con el conector de Spark. Para usar AWS Identity and Access Management (IAM), [configure la URL de JDBC para](https://docs.aws.amazon.com/redshift/latest/mgmt/generating-iam-credentials-configure-jdbc-odbc.html) usar la autenticación de IAM. Para conectarse a un clúster de Redshift desde Amazon EMR, debe conceder a su rol de IAM permiso para recuperar credenciales de IAM temporales. Asigne los siguientes permisos a su rol de IAM para que pueda recuperar credenciales y ejecutar operaciones de Amazon S3. 
+  [Redshift: GetClusterCredentials](https://docs.aws.amazon.com/redshift/latest/APIReference/API_GetClusterCredentials.html) (para clústeres de Amazon Redshift aprovisionados) 
+  [Redshift: DescribeClusters](https://docs.aws.amazon.com/redshift/latest/APIReference/API_DescribeClusters.html) (para clústeres de Amazon Redshift aprovisionados) 
+ [Redshift: GetWorkgroup](https://docs.aws.amazon.com/redshift-serverless/latest/APIReference/API_GetWorkgroup.html) (para grupos de trabajo sin servidor de Amazon Redshift)
+  [Redshift: GetCredentials](https://docs.aws.amazon.com/redshift-serverless/latest/APIReference/API_GetCredentials.html) (para grupos de trabajo sin servidor de Amazon Redshift) 
+  [s3: GetBucket](https://docs.aws.amazon.com/AmazonS3/latest/API/API_control_GetBucket.html) 
+  [s3: GetBucketLocation](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketLocation.html) 
+  [s3: GetObject](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html) 
+  [s3: PutObject](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html) 
+  [s3: GetBucketLifecycleConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketLifecycleConfiguration.html) 

Para obtener más información sobre `GetClusterCredentials`, consulte [Políticas de recursos de `GetClusterCredentials`](https://docs.aws.amazon.com/redshift/latest/mgmt/redshift-iam-access-control-identity-based.html#redshift-policy-resources.getclustercredentials-resources).

También debe asegurarse de que Amazon Redshift puede asumir el rol de IAM durante las operaciones `COPY` y `UNLOAD`.

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "sts:AssumeRole"
      ],
      "Resource": "arn:aws:iam::123456789012:role/RedshiftServiceRole",
      "Sid": "AllowSTSAssumerole"
    }
  ]
}
```

------

En el siguiente ejemplo, se utiliza la autenticación de IAM entre Spark y Amazon Redshift:

```
from pyspark.sql import SQLContext
import boto3

sc = # existing SparkContext
sql_context = SQLContext(sc)

url = "jdbc:redshift:iam://redshift-host:redshift-port/db-name"
iam_role_arn = "arn:aws:iam::account-id:role/role-name"

# Read data from a table
df = sql_context.read \
    .format("io.github.spark_redshift_community.spark.redshift") \
    .option("url", url) \
    .option("aws_iam_role", iam_role_arn) \
    .option("dbtable", "my_table") \
    .option("tempdir", "s3a://path/for/temp/data") \
    .mode("error") \
    .load()
```

# Lectura y escritura desde y hacia Amazon Redshift
<a name="emr-spark-redshift-readwrite"></a>

Los siguientes ejemplos de código se utilizan PySpark para leer y escribir datos de muestra desde y hacia una base de datos de Amazon Redshift con una API de fuente de datos y mediante SparkSQL.

------
#### [ Data source API ]

Se utiliza PySpark para leer y escribir datos de muestra desde y hacia una base de datos de Amazon Redshift con una API de fuente de datos.

```
import boto3
from pyspark.sql import SQLContext

sc = # existing SparkContext
sql_context = SQLContext(sc)

url = "jdbc:redshift:iam://redshifthost:5439/database"
aws_iam_role_arn = "arn:aws:iam::accountID:role/roleName"

df = sql_context.read \
    .format("io.github.spark_redshift_community.spark.redshift") \
    .option("url", url) \
    .option("dbtable", "tableName") \
    .option("tempdir", "s3://path/for/temp/data") \
    .option("aws_iam_role", "aws_iam_role_arn") \
    .load()

df.write \
    .format("io.github.spark_redshift_community.spark.redshift") \
    .option("url", url) \
    .option("dbtable", "tableName_copy") \
    .option("tempdir", "s3://path/for/temp/data") \
    .option("aws_iam_role", "aws_iam_role_arn") \
    .mode("error") \
    .save()
```

------
#### [ SparkSQL ]

Se utiliza PySpark para leer y escribir datos de muestra desde y hacia una base de datos de Amazon Redshift con SparkSQL.

```
import boto3
import json
import sys
import os
from pyspark.sql import SparkSession

spark = SparkSession \
    .builder \
    .enableHiveSupport() \
    .getOrCreate()
    
url = "jdbc:redshift:iam://redshifthost:5439/database"
aws_iam_role_arn = "arn:aws:iam::accountID:role/roleName"
    
bucket = "s3://path/for/temp/data"
tableName = "tableName" # Redshift table name

s = f"""CREATE TABLE IF NOT EXISTS {tableName} (country string, data string) 
    USING io.github.spark_redshift_community.spark.redshift 
    OPTIONS (dbtable '{tableName}', tempdir '{bucket}', url '{url}', aws_iam_role '{aws_iam_role_arn}' ); """

spark.sql(s)
         
columns = ["country" ,"data"]
data = [("test-country","test-data")]
df = spark.sparkContext.parallelize(data).toDF(columns)

# Insert data into table
df.write.insertInto(tableName, overwrite=False)
df = spark.sql(f"SELECT * FROM {tableName}")
df.show()
```

------

# Consideraciones y limitaciones al utilizar el conector de Spark
<a name="emr-spark-redshift-considerations"></a>
+ Le recomendamos que active SSL para la conexión JDBC desde Spark en Amazon EMR a Amazon Redshift.
+ Le recomendamos que administre las credenciales del clúster de Amazon Redshift en AWS Secrets Manager como práctica recomendada. Consulte [Utilización AWS Secrets Manager para recuperar credenciales para conectarse a Amazon Redshift](https://docs.aws.amazon.com/redshift/latest/mgmt/redshift-secrets-manager-integration.html) para ver un ejemplo.
+ Le recomendamos que pase un rol de IAM con el parámetro `aws_iam_role` para el parámetro de autenticación de Amazon Redshift.
+ El URI `tempdir` apunta a una ubicación de Amazon S3. Este directorio temporal no se limpia automáticamente y, por lo tanto, podría agregar costos adicionales. 
+ Tenga en cuenta las siguientes recomendaciones para Amazon Redshift:
  + Le recomendamos que bloquee el acceso público al clúster de Amazon Redshift.
  + Le recomendamos que active el [registro de auditoría de Amazon Redshift](https://docs.aws.amazon.com/redshift/latest/mgmt/db-auditing.html).
  + Le recomendamos que active el [cifrado en reposo de Amazon Redshift](https://docs.aws.amazon.com/redshift/latest/mgmt/security-server-side-encryption.html).
+ Tenga en cuenta las siguientes recomendaciones para Amazon S3:
  + Le recomendamos que [bloquee el acceso público a los buckets de Amazon S3](https://docs.aws.amazon.com/AmazonS3/latest/userguide/access-control-block-public-access.html).
  + Le recomendamos que utilice el [cifrado del servidor de Amazon S3](https://docs.aws.amazon.com/AmazonS3/latest/userguide/serv-side-encryption.html) para cifrar los buckets de Amazon S3 utilizados.
  + Le recomendamos que utilice las [políticas de ciclo de vida de Amazon S3](https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-lifecycle-mgmt.html) para definir las reglas de retención del bucket de Amazon S3.
  + Amazon EMR siempre verifica el código importado desde el código abierto a la imagen. Por motivos de seguridad, no admitimos los siguientes métodos de autenticación de Spark a Amazon S3:
    + Establecer las claves de AWS acceso en la clasificación de `hadoop-env` configuración
    + Codificación de las claves de AWS acceso en el `tempdir` URI

Para obtener más información sobre el uso del conector y sus parámetros compatibles, consulte los siguientes recursos:
+ [Integración de Amazon Redshift para Apache Spark](https://docs.aws.amazon.com/redshift/latest/mgmt/spark-redshift-connector.html) en la *Guía de administración de Amazon Redshift*
+ [Repositorio comunitario de `spark-redshift`](https://github.com/spark-redshift-community/spark-redshift#readme) en GitHub

# Historial de lanzamientos de Spark
<a name="Spark-release-history"></a>

En la siguiente tabla, se muestra la versión de Spark incluida en cada versión de lanzamiento de Amazon EMR, junto con los componentes instalados con la aplicación. Para ver las versiones de los componentes de cada versión, consulte la sección Versiones de los componentes en la versión correspondiente de [Versiones de Amazon EMR 7.x](emr-release-7x.md), [Versiones de lanzamiento de Amazon EMR 6.x](emr-release-6x.md) o [Versiones de lanzamiento de Amazon EMR 5.x](emr-release-5x.md).

**importante**  
La versión 2.3.1 de Apache Spark, disponible a partir de la versión 5.16.0 de Amazon EMR, aborda [CVE-2018-8024](https://nvd.nist.gov/vuln/detail/CVE-2018-8024) y [CVE-2018-1334](https://nvd.nist.gov/vuln/detail/CVE-2018-1334). Se recomienda migrar las versiones anteriores de Spark a la versión 2.3.1 o posteriores de Spark.


**Información de la versión de Spark**  

| Etiqueta de versión de Amazon EMR | Versión de Spark | Componentes instalados con Spark | 
| --- | --- | --- | 
| emr-7.12.0 | 3.5.6-amzn-1 | delta, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-hdfs-zkfc, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, iceberg, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-7.11.0 | 3.5.6-amzn-0 | delta, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-hdfs-zkfc, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, iceberg, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-7.10.0 | 3.5.5-amzn-1 | delta, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, iceberg, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-7.9.0 | 3.5.5-amzn-0 | delta, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, iceberg, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-7.8.0 | 3.5.4-amzn-0 | delta, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, iceberg, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-7.7.0 | 3.5.3-amzn-1 | delta, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, iceberg, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-7.6.0 | 3.5.3-amzn-0 | delta, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, iceberg, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-7.5.0 | 3.5.2-amzn-1 | delta, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, iceberg, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-7.4.0 | 3.5.2-amzn-0 | delta, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, iceberg, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-7.3.0 | 3.5.1-amzn-1 | delta, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, iceberg, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-7.2.0 | 3.5.1-amzn-0 | delta, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, iceberg, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.36.2 | 2.4.8-amzn-2 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-7.1.0 | 3.5.0-amzn-1 | delta, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, iceberg, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-7.0.0 | 3.5.0-amzn-0 | delta, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, iceberg, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-6.15.0 | 3.4.1-amzn-2 | aws-sagemaker-spark-sdk, delta, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, iceberg, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-6.14.0 | 3.4.1-amzn-1 | aws-sagemaker-spark-sdk, delta, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, iceberg, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-6.13.0 | 3.4.1-amzn-0 | aws-sagemaker-spark-sdk, delta, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, iceberg, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-6.12.0 | 3.4.0-amzn-0 | aws-sagemaker-spark-sdk, delta, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, iceberg, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-6.11.1 | 3.3.2-amzn-0.1 | aws-sagemaker-spark-sdk, delta, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, iceberg, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-6.11.0 | 3.3.2-amzn-0 | aws-sagemaker-spark-sdk, delta, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, iceberg, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-6.10.1 | 3.3.1-amzn-0.1 | aws-sagemaker-spark-sdk, delta, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, iceberg, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-6.10.0 | 3.3.1-amzn-0 | aws-sagemaker-spark-sdk, delta, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, iceberg, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-6.9.1 | 3.3.0-amzn-1.1 | aws-sagemaker-spark-sdk, delta, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, iceberg, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-6.9.0 | 3.3.0-amzn-1 | aws-sagemaker-spark-sdk, delta, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, iceberg, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-6.8.1 | 3.3.0-amzn-0.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, iceberg, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-6.8.0 | 3.3.0-amzn-0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, iceberg, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-6.7.0 | 3.2.1-amzn-0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, iceberg, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.36.1 | 2.4.8-amzn-2 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.36.0 | 2.4.8-amzn-2 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-6.6.0 | 3.2.0-amzn-0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, iceberg, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.35.0 | 2.4.8-amzn-1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-6.5.0 | 3.1.2-amzn-1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, iceberg, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-6.4.0 | 3.1.2-amzn-0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-6.3.1 | 3.1.1-amzn-0.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-6.3.0 | 3.1.1-amzn-0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-6.2.1 | 3.0.1-amzn-0.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-6.2.0 | 3.0.1-amzn-0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-6.1.1 | 3.0.0-amzn-0.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-6.1.0 | 3.0.0-amzn-0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-6.0.1 | 2.4.4 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-6.0.0 | 2.4.4 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.34.0 | 2.4.8-amzn-0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.33.1 | 2.4.7-amzn-1.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.33.0 | 2.4.7-amzn-1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.32.1 | 2.4.7-amzn-0.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.32.0 | 2.4.7-amzn-0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.31.1 | 2.4.6-amzn-0.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.31.0 | 2.4.6-amzn-0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.30.2 | 2.4.5-amzn-0.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.30.1 | 2.4.5-amzn-0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.30.0 | 2.4.5-amzn-0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-notebook-env, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.29.0 | 2.4.4 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.28.1 | 2.4.4 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.28.0 | 2.4.4 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.27.1 | 2.4.4 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.27.0 | 2.4.4 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.26.0 | 2.4.3 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.25.0 | 2.4.3 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.24.1 | 2.4.2 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.24.0 | 2.4.2 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.23.1 | 2.4.0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.23.0 | 2.4.0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.22.0 | 2.4.0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.21.2 | 2.4.0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.21.1 | 2.4.0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.21.0 | 2.4.0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.20.1 | 2.4.0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.20.0 | 2.4.0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.19.1 | 2.3.2 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.19.0 | 2.3.2 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.18.1 | 2.3.2 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.18.0 | 2.3.2 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, livy-server, nginx, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.17.2 | 2.3.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, livy-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.17.1 | 2.3.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, livy-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.17.0 | 2.3.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, emr-s3-select, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, livy-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.16.1 | 2.3.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, livy-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.16.0 | 2.3.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, livy-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.15.1 | 2.3.0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, livy-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.15.0 | 2.3.0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, livy-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.14.2 | 2.3.0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, livy-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.14.1 | 2.3.0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, livy-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.14.0 | 2.3.0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, livy-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.13.1 | 2.3.0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, livy-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.13.0 | 2.3.0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, livy-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.12.3 | 2.2.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, livy-server, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.12.2 | 2.2.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, livy-server, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.12.1 | 2.2.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, livy-server, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.12.0 | 2.2.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, livy-server, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.11.4 | 2.2.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, livy-server, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.11.3 | 2.2.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, livy-server, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.11.2 | 2.2.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, livy-server, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.11.1 | 2.2.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, livy-server, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.11.0 | 2.2.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, livy-server, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.10.1 | 2.2.0 | emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, livy-server, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.10.0 | 2.2.0 | emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, livy-server, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.9.1 | 2.2.0 | emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.9.0 | 2.2.0 | emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.8.3 | 2.2.0 | emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.8.2 | 2.2.0 | emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.8.1 | 2.2.0 | emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.8.0 | 2.2.0 | emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.7.1 | 2.1.1 | emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.7.0 | 2.1.1 | emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.6.1 | 2.1.1 | emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.6.0 | 2.1.1 | emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.5.4 | 2.1.0 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.5.3 | 2.1.0 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.5.2 | 2.1.0 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.5.1 | 2.1.0 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.5.0 | 2.1.0 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.4.1 | 2.1.0 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.4.0 | 2.1.0 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.3.2 | 2.1.0 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.3.1 | 2.1.0 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.3.0 | 2.1.0 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.2.3 | 2.0.2 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.2.2 | 2.0.2 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.2.1 | 2.0.2 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.2.0 | 2.0.2 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.1.1 | 2.0.1 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.1.0 | 2.0.1 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.0.3 | 2.0.1 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.0.2 | 2.0.0 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.0.1 | 2.0.0 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-5.0.0 | 2.0.0 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-4.9.6 | 1.6.3 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-4.9.5 | 1.6.3 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-4.9.4 | 1.6.3 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-4.9.3 | 1.6.3 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-4.9.2 | 1.6.3 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-4.9.1 | 1.6.3 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-4.8.5 | 1.6.3 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-4.8.4 | 1.6.3 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-4.8.3 | 1.6.3 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-4.8.2 | 1.6.2 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-4.8.1 | 1.6.2 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-4.8.0 | 1.6.2 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-4.7.4 | 1.6.2 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-4.7.3 | 1.6.2 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-4.7.2 | 1.6.2 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-4.7.1 | 1.6.1 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-4.7.0 | 1.6.1 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-4.6.1 | 1.6.1 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-4.6.0 | 1.6.1 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-4.5.0 | 1.6.1 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-4.4.0 | 1.6.0 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-4.3.0 | 1.6.0 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-4.2.0 | 1.5.2 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-4.1.0 | 1.5.0 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 
| emr-4.0.0 | 1.4.1 | emrfs, emr-goodies, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-namenode, hadoop-httpfs-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave | 

# Uso de vistas materializadas con Amazon EMR
<a name="emr-spark-materialized-views"></a>

La versión 7.12.0 y posteriores de Amazon EMR admiten la creación y administración de vistas materializadas de Apache Iceberg en el catálogo de datos de Glue. AWS Una vista materializada es una tabla administrada que almacena el resultado precalculado de una consulta SQL en formato Apache Iceberg y se actualiza de forma incremental a medida que cambian las tablas de origen subyacentes. Puede utilizar las vistas materializadas para simplificar la canalización de transformación de datos y acelerar el rendimiento de las consultas para cargas de trabajo analíticas complejas.

Al crear una vista materializada con Spark en Amazon EMR, la definición de la vista y los metadatos se almacenan en el catálogo de datos de AWS Glue. Los resultados precalculados se almacenan como tablas de Apache Iceberg en los buckets de Amazon S3 Tables o en los buckets de uso general de Amazon S3 de su cuenta. AWS El catálogo de datos de AWS Glue supervisa automáticamente las tablas de origen y actualiza las vistas materializadas mediante una infraestructura de procesamiento gestionada.

**Topics**
+ [Cómo funcionan las vistas materializadas con Amazon EMR](#emr-spark-materialized-views-how-it-works)
+ [Requisitos previos](#emr-spark-materialized-views-prerequisites)
+ [Configuración de Spark para usar vistas materializadas](#emr-spark-materialized-views-configure)
+ [Creación de vistas materializadas](#emr-spark-materialized-views-create)
+ [Consulta de vistas materializadas](#emr-spark-materialized-views-query)
+ [Actualización de vistas materializadas](#emr-spark-materialized-views-refresh)
+ [Administración de vistas materializadas](#emr-spark-materialized-views-manage)
+ [Permisos para vistas materializadas](#emr-spark-materialized-views-permissions)
+ [Supervisión de las operaciones de vistas materializadas](#emr-spark-materialized-views-monitoring)
+ [Ejemplo: flujo de trabajo completo](#emr-spark-materialized-views-example)
+ [Consideraciones y limitaciones](#emr-spark-materialized-views-limitations)

## Cómo funcionan las vistas materializadas con Amazon EMR
<a name="emr-spark-materialized-views-how-it-works"></a>

Las vistas materializadas se integran con Amazon EMR mediante el soporte Iceberg de Apache Spark. Cuando configuras tu sesión de Spark para usar el catálogo de datos de AWS Glue, puedes crear vistas materializadas con la sintaxis SQL estándar. El optimizador de Spark puede reescribir automáticamente las consultas para utilizar vistas materializadas cuando ofrecen un mejor rendimiento, lo que elimina la necesidad de modificar manualmente el código de la aplicación.

El catálogo de datos de AWS Glue gestiona todos los aspectos operativos del mantenimiento de la vista materializada, incluidos:
+ Detección de cambios en las tablas fuente mediante la capa de metadatos de Apache Iceberg
+ Programación y ejecución de operaciones de actualización mediante cómputo Spark administrado
+ Cómo determinar si realizar una actualización completa o incremental en función de los cambios en los datos
+ Almacenamiento de resultados precalculados en formato Apache Iceberg para el acceso con múltiples motores

Puede consultar vistas materializadas de Amazon EMR mediante las mismas interfaces de Spark SQL que utiliza para las tablas normales. También se puede acceder a los datos precalculados desde otros servicios, como Amazon Athena y Amazon Redshift.

## Requisitos previos
<a name="emr-spark-materialized-views-prerequisites"></a>

Para utilizar vistas materializadas con Amazon EMR, necesita:
+ ¿Una cuenta AWS 
+ Un clúster de Amazon EMR que ejecute la versión 7.12.0 o posterior
+ Tablas fuente en formato Apache Iceberg registradas en el catálogo de datos de AWS Glue
+ AWS Permisos de Lake Formation configurados para tablas de origen y bases de datos de destino
+ Una cubeta S3 Tables o una cubeta S3 de uso general registrada en AWS Lake Formation para almacenar datos de vistas materializadas

## Configuración de Spark para usar vistas materializadas
<a name="emr-spark-materialized-views-configure"></a>

Para crear y gestionar vistas materializadas, configura tu sesión de Spark con las extensiones de Iceberg y los ajustes del catálogo necesarios. La configuración varía en función de si las tablas fuente y las vistas materializadas utilizan cubos de S3 Tables o grupos de uso general de S3.

### Configuración para tablas de S3
<a name="emr-spark-materialized-views-configure-s3-tables"></a>

Cuando utilice cubos de S3 Tables para las vistas materializadas, configure referencias de catálogo independientes para las tablas de origen y las vistas materializadas:

```
spark-sql \
  --conf spark.sql.extensions=org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions \
  --conf spark.sql.catalog.glue_catalog=org.apache.iceberg.spark.SparkCatalog \
  --conf spark.sql.catalog.glue_catalog.type=glue \
  --conf spark.sql.catalog.glue_catalog.warehouse=s3://amzn-s3-demo-bucket/warehouse \
  --conf spark.sql.catalog.glue_catalog.glue.region=us-east-1 \
  --conf spark.sql.catalog.glue_catalog.glue.id=111122223333 \
  --conf spark.sql.catalog.glue_catalog.glue.account-id=111122223333 \
  --conf spark.sql.catalog.glue_catalog.glue.lakeformation-enabled=true \
  --conf spark.sql.catalog.s3t_catalog=org.apache.iceberg.spark.SparkCatalog \
  --conf spark.sql.catalog.s3t_catalog.type=glue \
  --conf spark.sql.catalog.s3t_catalog.glue.id=111122223333:s3tablescatalog/my-table-bucket \
  --conf spark.sql.catalog.s3t_catalog.glue.account-id=111122223333 \
  --conf spark.sql.catalog.s3t_catalog.glue.lakeformation-enabled=true \
  --conf spark.sql.catalog.s3t_catalog.warehouse=s3://amzn-s3-demo-bucket/mv-warehouse \
  --conf spark.sql.catalog.s3t_catalog.glue.region=us-east-1 \
  --conf spark.sql.defaultCatalog=s3t_catalog \
  // turn on automatic query rewrite (optional)
  --conf spark.sql.optimizer.answerQueriesWithMVs.enabled=true
```

### Configuración para depósitos de uso general de S3
<a name="emr-spark-materialized-views-configure-s3-general"></a>

Cuando utilice depósitos de uso general de S3, configure una referencia de catálogo única:

```
spark-sql \
  --conf spark.sql.extensions=org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions \
  --conf spark.sql.catalog.glue_catalog=org.apache.iceberg.spark.SparkCatalog \
  --conf spark.sql.catalog.glue_catalog.type=glue \
  --conf spark.sql.catalog.glue_catalog.warehouse=s3://amzn-s3-demo-bucket/warehouse \
  --conf spark.sql.catalog.glue_catalog.glue.region=us-east-1 \
  --conf spark.sql.catalog.glue_catalog.glue.id=111122223333 \
  --conf spark.sql.catalog.s3t_catalog.glue.account-id=111122223333 \
  --conf spark.sql.catalog.s3t_catalog.glue.lakeformation-enabled=true \
  --conf spark.sql.defaultCatalog=glue_catalog \
  // turn on automatic query rewrite (optional)
  --conf spark.sql.optimizer.answerQueriesWithMVs.enabled=true
```

### Habilitación de la actualización incremental
<a name="emr-spark-materialized-views-configure-incremental"></a>

Para habilitar la optimización de las actualizaciones incrementales, añade las siguientes propiedades de configuración a tu sesión de Spark:

```
spark-sql \
  --conf spark.sql.optimizer.incrementalMVRefresh.enabled=true \
```

### Parámetros de configuración
<a name="emr-spark-materialized-views-configure-parameters"></a>

Los siguientes parámetros de configuración controlan el comportamiento de la vista materializada:
+ `spark.sql.extensions`: habilita las extensiones de sesión de Iceberg Spark necesarias para la compatibilidad con la vista materializada.
+ `spark.sql.optimizer.answerQueriesWithMVs.enabled`: habilita la reescritura automática de consultas para usar vistas materializadas. Establézcalo en «true» para activar esta optimización.
+ `spark.sql.optimizer.incrementalMVRefresh.enabled`: permite la optimización de la actualización incremental. Establézcalo en «true» para procesar solo los datos modificados durante las operaciones de actualización.

## Creación de vistas materializadas
<a name="emr-spark-materialized-views-create"></a>

Las vistas materializadas se crean mediante la sentencia SQL CREATE MATERIALIZED VIEW. La definición de vista especifica la lógica de transformación como una consulta SQL que hace referencia a una o más tablas de origen.

### DLLs
<a name="emr-spark-materialized-views-create-dlls"></a>

**Crear vista**

```
{ CREATE OR REPLACE MATERIALIZED VIEW | CREATE MATERIALIZED VIEW [ IF NOT EXISTS ] }
   view_identifier
  [ view_clauses ]
  [ schedule_clauses ]
  AS [ select_statement ]

view_clauses =
  { [ LOCATION location ] |
    [ PARTITIONED BY (col [, ...]) ] |
    [ COMMENT view_comment ] |
    [ SCHEDULE [ REFRESH ] schedule_clause ] }

schedule_clause =
  { EVERY number { HOUR | HOURS | DAY | DAYS | WEEK | WEEKS } }
```

**nota**  
Las view\$1clauses deben aparecer antes de la select\$1statement.

### Crear una vista materializada básica
<a name="emr-spark-materialized-views-create-basic"></a>

En el siguiente ejemplo, se crea una vista materializada que agrega los datos de los pedidos por cliente. En la definición de la vista, se utilizan nombres de tabla completos con una convención de nomenclatura de tres partes:

```
CREATE MATERIALIZED VIEW customer_orders
AS 
SELECT 
    customer_name, 
    COUNT(*) as order_count, 
    SUM(amount) as total_amount 
FROM glue_catalog.sales.orders
GROUP BY customer_name;
```

### Creación de una vista materializada con actualización automática
<a name="emr-spark-materialized-views-create-auto-refresh"></a>

Para configurar la actualización automática, especifique un programa de actualización al crear la vista utilizando nombres de tabla completos con una convención de nomenclatura de tres partes en la definición de la vista:

```
CREATE MATERIALIZED VIEW customer_orders
SCHEDULE REFRESH EVERY 1 HOUR
AS 
SELECT 
    customer_name, 
    COUNT(*) as order_count, 
    SUM(amount) as total_amount 
FROM glue_catalog.sales.orders
GROUP BY customer_name;
```

### Creación de una vista materializada con referencias entre catálogos
<a name="emr-spark-materialized-views-create-cross-catalog"></a>

Cuando las tablas de origen se encuentran en un catálogo distinto del de la vista materializada, utilice nombres de tabla totalmente calificados con la convención de nomenclatura de tres partes tanto en el nombre de la vista como en la definición de la vista:

```
CREATE MATERIALIZED VIEW s3t_catalog.analytics.customer_summary
AS 
SELECT 
    customer_name, 
    COUNT(*) as order_count, 
    SUM(amount) as total_amount 
FROM glue_catalog.sales.orders
GROUP BY customer_name;
```

## Consulta de vistas materializadas
<a name="emr-spark-materialized-views-query"></a>

Tras crear una vista materializada, puede consultarla como cualquier otra tabla mediante las instrucciones SQL SELECT estándar:

```
SELECT * FROM customer_orders;
```

### Reescritura automática de consultas
<a name="emr-spark-materialized-views-query-rewrite"></a>

Cuando la reescritura automática de consultas está habilitada, el optimizador de Spark analiza las consultas y utiliza automáticamente las vistas materializadas para mejorar el rendimiento. Por ejemplo, la siguiente consulta no se ejecuta:

```
SELECT 
    customer_name, 
    COUNT(*) as order_count, 
    SUM(amount) as total_amount 
FROM orders
GROUP BY customer_name;
```

El optimizador de Spark reescribe automáticamente esta consulta para utilizar la vista materializada «customer\$1orders» en lugar de procesar la tabla base de pedidos, siempre que la vista materializada esté actualizada.

### Verificación de la reescritura automática de consultas
<a name="emr-spark-materialized-views-query-verify"></a>

Para verificar si una consulta utiliza la reescritura automática de consultas, use el comando EXPLAIN EXTENDED:

```
EXPLAIN EXTENDED
SELECT customer_name, COUNT(*) as order_count, SUM(amount) as total_amount 
FROM orders
GROUP BY customer_name;
```

En el plan de ejecución, busque el nombre de la vista materializada en la BatchScan operación. Si el plan muestra BatchScan glue\$1catalog.analytics.customer\$1orders en lugar de glue\$1catalog.sales.orders, la consulta se ha reescrito automáticamente para BatchScan utilizar la vista materializada.

**nota**  
La reescritura automática de consultas requiere tiempo para que la caché de metadatos de Spark se llene después de crear una vista materializada. Este proceso suele completarse en un plazo de 30 segundos.

## Actualización de vistas materializadas
<a name="emr-spark-materialized-views-refresh"></a>

Puede actualizar las vistas materializadas mediante dos métodos: actualización completa o actualización incremental. La actualización completa vuelve a calcular toda la vista materializada a partir de todos los datos de las tablas base, mientras que la actualización incremental procesa únicamente los datos que han cambiado desde la última actualización.

### Actualización completa manual
<a name="emr-spark-materialized-views-refresh-full"></a>

Para realizar una actualización completa de una vista materializada:

```
REFRESH MATERIALIZED VIEW customer_orders FULL;
```

Tras ejecutar este comando, consulte la vista materializada para comprobar los resultados actualizados:

```
SELECT * FROM customer_orders;
```

### Actualización incremental manual
<a name="emr-spark-materialized-views-refresh-incremental"></a>

Para realizar una actualización incremental, asegúrese de que la actualización incremental esté habilitada en la configuración de su sesión de Spark y, a continuación, ejecute:

```
REFRESH MATERIALIZED VIEW customer_orders;
```

El catálogo de datos de AWS Glue determina automáticamente si la actualización incremental es aplicable en función de la definición de la vista y de la cantidad de datos modificados. Si la actualización incremental no es posible, la operación recurre a una actualización completa.

### Verificación de la ejecución de la actualización incremental
<a name="emr-spark-materialized-views-refresh-verify"></a>

Para confirmar que la actualización incremental se ha ejecutado correctamente, puede comprobar las propiedades de la `lastRefreshType` tabla ejecutando los siguientes comandos:

```
SHOW TBLPROPERTIES <mvName>("lastRefreshType")
```

Además, esto también se puede lograr habilitando el registro de depuración modificando la configuración del registro de Spark:

1. Abre el archivo de configuración log4j de Spark:

   ```
   sudo vim /usr/lib/spark/conf/log4j2.properties
   ```

1. Añade las siguientes configuraciones de registro:

   ```
   logger.spark.name = org.apache.spark.sql
   logger.spark.level = debug
   
   logger.inmemcache.name = org.apache.spark.sql.InMemMvMetadataCache
   logger.inmemcache.level = off
   ```

1. Tras ejecutar una operación de actualización, busca el siguiente mensaje en la salida de Spark:

   ```
   DEBUG RefreshMaterializedViewExec: Executed Incremental Refresh
   ```

## Administración de vistas materializadas
<a name="emr-spark-materialized-views-manage"></a>

Amazon EMR proporciona comandos SQL para gestionar el ciclo de vida de las vistas materializadas.

### Descripción de una vista materializada
<a name="emr-spark-materialized-views-manage-describe"></a>

Para ver los metadatos de una vista materializada, incluida su definición, el estado de actualización y la marca de tiempo de la última actualización:

```
DESCRIBE EXTENDED customer_orders;
```

### Modificación de una vista materializada
<a name="emr-spark-materialized-views-manage-alter"></a>

Para modificar el calendario de actualización de una vista materializada existente:

```
ALTER MATERIALIZED VIEW customer_orders 
ADD SCHEDULE REFRESH EVERY 2 HOURS;
```

Para eliminar la actualización automática:

```
ALTER MATERIALIZED VIEW customer_orders 
DROP SCHEDULE;
```

### Eliminación de una vista materializada
<a name="emr-spark-materialized-views-manage-drop"></a>

Para eliminar una vista materializada:

```
DROP MATERIALIZED VIEW customer_orders;
```

Este comando elimina la definición de vista materializada del catálogo de datos de AWS Glue y elimina los datos de la tabla Iceberg subyacente del bucket de S3.

## Permisos para vistas materializadas
<a name="emr-spark-materialized-views-permissions"></a>

Para crear y administrar vistas materializadas, debe configurar los permisos de AWS Lake Formation. El rol de IAM que crea la vista materializada (la función de definición) requiere permisos específicos en las tablas de origen y las bases de datos de destino.

### Permisos requeridos para el rol definidor
<a name="emr-spark-materialized-views-permissions-definer"></a>

El rol definidor debe contar con los siguientes permisos de Lake Formation:
+ En las tablas de origen: permisos SELECT o ALL, sin filtros de filas, columnas ni celdas.
+ En la base de datos de destino: permiso CREATE\$1TABLE
+ Sobre el catálogo de datos de AWS Glue GetTable y los permisos CreateTable de la API

Cuando crea una vista materializada, el ARN del rol definidor se almacena en la definición de la vista. El catálogo de datos de AWS Glue asume esta función al ejecutar operaciones de actualización automática. Si el rol definidor pierde el acceso a las tablas de origen, las operaciones de actualización fallarán hasta que se restablezcan los permisos.

### Concesión de acceso a vistas materializadas
<a name="emr-spark-materialized-views-permissions-access"></a>

Para conceder a otros usuarios acceso para consultar una vista materializada, utilice AWS Lake Formation para conceder el permiso SELECT en la tabla de vistas materializadas. Los usuarios pueden consultar la vista materializada sin necesidad de tener acceso directo a las tablas de origen subyacentes.

Para obtener información detallada sobre la configuración de los permisos de Lake Formation, consulte Concesión y revocación de permisos en los recursos del catálogo de datos en la Guía para desarrolladores de AWS Lake Formation.

## Supervisión de las operaciones de vistas materializadas
<a name="emr-spark-materialized-views-monitoring"></a>

El catálogo de datos de AWS Glue publica métricas y registros para las operaciones de actualización de vistas materializadas en Amazon CloudWatch. Puede supervisar el estado de la actualización, la duración y el volumen de datos procesados mediante CloudWatch métricas.

### Visualización de las métricas de actualización
<a name="emr-spark-materialized-views-monitoring-metrics"></a>

Para ver las métricas de actualización de vistas materializadas:

1. Abra la CloudWatch consola.

1. Seleccione Métricas en el panel de navegación.

1. Seleccione el espacio de nombres Glue (Adherencia).

1. Filtre las métricas por el nombre de la vista materializada.

### Configuración de alarmas
<a name="emr-spark-materialized-views-monitoring-alarms"></a>

Para recibir notificaciones cuando las operaciones de actualización fallen o superen la duración prevista, cree CloudWatch alarmas en las métricas de visualización materializada. También puedes configurar EventBridge las reglas de Amazon para activar respuestas automáticas para actualizar los eventos.

## Ejemplo: flujo de trabajo completo
<a name="emr-spark-materialized-views-example"></a>

El siguiente ejemplo muestra un flujo de trabajo completo para crear y utilizar una vista materializada en Amazon EMR.

1. Conéctese al nodo principal del clúster de EMR mediante SSH.

1. Cree una tabla base con datos de ejemplo:

   ```
   spark-sql \
     --conf spark.sql.extensions=org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions \
     --conf spark.sql.catalog.glue_catalog=org.apache.iceberg.spark.SparkCatalog \
     --conf spark.sql.catalog.glue_catalog.type=glue \
     --conf spark.sql.catalog.glue_catalog.warehouse=s3://amzn-s3-demo-bucket/warehouse \
     --conf spark.sql.catalog.glue_catalog.glue.region=us-east-1 \
     --conf spark.sql.catalog.glue_catalog.glue.id=111122223333 \
     --conf spark.sql.catalog.glue_catalog.glue.account-id=111122223333 \
     --conf spark.sql.catalog.glue_catalog.glue.lakeformation-enabled=true \
     --conf spark.sql.defaultCatalog=glue_catalog \
     --conf spark.sql.optimizer.answerQueriesWithMVs.enabled=true 
   
   
   CREATE DATABASE IF NOT EXISTS sales;
   
   USE sales;
   
   CREATE TABLE orders (
       id INT,
       customer_name STRING,
       amount DECIMAL(10,2),
       order_date DATE
   );
   
   INSERT INTO orders VALUES 
       (1, 'John Doe', 150.00, DATE('2024-01-15')),
       (2, 'Jane Smith', 200.50, DATE('2024-01-16')),
       (3, 'Bob Johnson', 75.25, DATE('2024-01-17'));
   ```

1. Cree una vista materializada:

   ```
   CREATE MATERIALIZED VIEW customer_summary
   AS 
   SELECT 
       customer_name, 
       COUNT(*) as order_count, 
       SUM(amount) as total_amount 
   FROM glue_catalog.sales.orders
   GROUP BY customer_name;
   ```

1. Consulte la vista materializada:

   ```
   SELECT * FROM customer_summary;
   ```

1. Inserte datos adicionales en la tabla base:

   ```
   INSERT INTO orders VALUES 
       (4, 'Jane Smith', 350.00, DATE('2024-01-18')),
       (5, 'Bob Johnson', 100.25, DATE('2024-01-19'));
   ```

1. Actualice la vista materializada:

   ```
   REFRESH MATERIALIZED VIEW customer_summary FULL;
   ```

1. Compruebe los resultados actualizados:

   ```
   SELECT * FROM customer_summary;
   ```

## Consideraciones y limitaciones
<a name="emr-spark-materialized-views-limitations"></a>

Tenga en cuenta lo siguiente cuando utilice vistas materializadas con Amazon EMR:
+ Las vistas materializadas requieren Amazon EMR versión 7.12.0 o posterior.
+ Las tablas de origen deben ser tablas de Apache Iceberg registradas en el catálogo de datos de AWS Glue. Las tablas de Apache Hive, Apache Hudi y Delta Lake de Linux Foundation no son compatibles en el lanzamiento.
+ Las tablas de origen deben residir en la misma AWS región y AWS tener en cuenta la vista materializada.
+ Todas las tablas de fuentes deben regirse por AWS Lake Formation. No se admiten los permisos exclusivos de IAM ni el acceso híbrido.
+ Las vistas materializadas no pueden hacer referencia a las vistas del catálogo de datos de AWS Glue, a las vistas multidialectales ni a otras vistas materializadas como tablas de origen.
+ El rol definidor de la vista debe contar con acceso de lectura completo (permisos SELECT o ALL) en todas las tablas de origen, sin aplicar filtros de filas, columnas ni celdas.
+ Las vistas materializadas son eventualmente coherentes con las tablas de origen. Durante la ventana de actualización, las consultas pueden devolver datos obsoletos. Ejecute una actualización manual para obtener consistencia inmediata.
+ El intervalo mínimo de actualización automática es de una hora.
+ La actualización incremental admite un conjunto limitado de operaciones SQL. La definición de la vista debe ser un único bloque SELECT-FROM-WHERE-GROUP BY-HAVING y no puede contener operaciones de conjunto, subconsultas, la palabra clave DISTINCT en las funciones SELECT o agregadas, funciones de ventana o uniones que no sean INNER JOIN.
+ La actualización incremental no admite funciones definidas por el usuario ni determinadas funciones integradas. Solo se admite un subconjunto de las funciones integradas de Spark SQL.
+ La reescritura automática de consultas solo tiene en cuenta vistas materializadas cuyas definiciones pertenecen a un subconjunto restringido de SQL, similar a las restricciones de la actualización incremental.
+ Las operaciones de actualización completa sobrescriben la tabla en su totalidad y hacen que las instantáneas anteriores dejen de estar disponibles.
+ Los identificadores que contienen caracteres especiales distintos de caracteres alfanuméricos y guiones bajos no son compatibles en las consultas CREAR VISTA MATERIALIZADA.
+ Las columnas de vistas materializadas que comienzan con el prefijo \$1\$1ivm están reservadas para el uso del sistema. AWS se reserva el derecho de modificar o eliminar estas columnas en futuras versiones.
+ Las cláusulas SORT BY, LIMIT, OFFSET, CLUSTER BY y ORDER BY no son compatibles en las definiciones de vistas materializadas.
+ No se admiten tablas de origen entre regiones ni entre cuentas.
+ Las funciones no deterministas, como rand() o current\$1timestamp(), no son compatibles en las definiciones de vistas materializadas.