Trabalhando com o Apache Iceberg no Amazon EMR - AWS Orientação prescritiva

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

Trabalhando com o Apache Iceberg no Amazon EMR

O Amazon EMR fornece processamento de dados em escala de petabytes, análises interativas e aprendizado de máquina na nuvem usando estruturas de código aberto, como Apache Spark, Apache Hive, Flink e Trino.

nota

Este guia usa o Apache Spark como exemplos.

O Amazon EMR oferece suporte a várias opções de implantação: Amazon EMR no Amazon EC2, Amazon EMR no Amazon EKS, Amazon EMR Serverless e Amazon EMR on. AWS Outposts Para escolher uma opção de implantação para sua carga de trabalho, consulte as perguntas frequentes do Amazon EMR.

Compatibilidade de versões e recursos

A versão 6.5.0 e versões posteriores do Amazon EMR oferecem suporte nativo ao Apache Iceberg. Para obter uma lista das versões compatíveis do Iceberg para cada versão do Amazon EMR, consulte o histórico de lançamentos do Iceberg na documentação do Amazon EMR. Analise também as considerações e limitações do uso do Iceberg no Amazon EMR para ver quais recursos do Iceberg são compatíveis com o Amazon EMR em diferentes estruturas.

Recomendamos que você use a versão mais recente do Amazon EMR para se beneficiar da versão mais recente compatível do Iceberg. Os exemplos de código e as configurações nesta seção pressupõem que você esteja usando a versão emr-6.9.0 do Amazon EMR.

Criação de um cluster do Amazon EMR com o Iceberg

Para criar um cluster do Amazon EMR no Amazon EC2 com o Iceberg instalado, siga as instruções na documentação do Amazon EMR. 

Especificamente, seu cluster deve ser configurado com a seguinte classificação:

[{ "Classification": "iceberg-defaults", "Properties": { "iceberg.enabled": "true" } }]

Você também pode optar por usar o Amazon EMR Serverless ou o Amazon EMR no Amazon EKS como opções de implantação para suas cargas de trabalho do Iceberg, a partir do Amazon EMR 6.6.0.

Desenvolvendo aplicativos Iceberg no Amazon EMR

Para desenvolver o código Spark para seus aplicativos Iceberg, você pode usar o Amazon EMR Studio, que é um ambiente de desenvolvimento integrado (IDE) baseado na web para notebooks Jupyter totalmente gerenciados que são executados em clusters do Amazon EMR. 

Usando notebooks Amazon EMR Studio

Você pode desenvolver aplicativos Spark de forma interativa nos notebooks Amazon EMR Studio Workspace e conectar esses notebooks ao seu Amazon EMR nos clusters do Amazon EC2 ou ao Amazon EMR nos endpoints gerenciados do Amazon EKS. Consulte a Serviço da AWS documentação para obter instruções sobre como configurar um EMR Studio para o Amazon EMR no Amazon EC2 e o Amazon EMR no Amazon EKS.

Para usar o Iceberg no EMR Studio, siga estas etapas: 

  1. Inicie um cluster do Amazon EMR com o Iceberg ativado, conforme as instruções em Use um cluster com o Iceberg instalado. 

  2. Configure um EMR Studio. Para obter instruções, consulte Configurar um Amazon EMR Studio.

  3. Abra um notebook do EMR Studio Workspace e execute o código a seguir como a primeira célula no notebook para configurar sua sessão do Spark para usar o Iceberg:

    %%configure -f { "conf": { "spark.sql.catalog.<catalog_name>": "org.apache.iceberg.spark.SparkCatalog", "spark.sql.catalog.<catalog_name>.warehouse": "s3://YOUR-BUCKET-NAME/YOUR-FOLDER-NAME/", "spark.sql.catalog.<catalog_name>.catalog-impl": "org.apache.iceberg.aws.glue.GlueCatalog", "spark.sql.catalog.<catalog_name>.io-impl": "org.apache.iceberg.aws.s3.S3FileIO", "spark.sql.extensions": "org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions" } }

    onde:

    • <catalog_name>é o nome do catálogo de sessões do Iceberg Spark. Substitua-o pelo nome do seu catálogo e lembre-se de alterar as referências em todas as configurações associadas a esse catálogo. Em seu código, você deve então se referir às suas tabelas do Iceberg com o nome da tabela totalmente qualificado, incluindo o nome do catálogo da sessão do Spark, da seguinte forma:

      <catalog_name>.<database_name>.<table_name>
    • <catalog_name>.warehouseaponta para o caminho do Amazon S3 onde você deseja armazenar seus dados e metadados.

    • Para tornar o catálogo um AWS Glue Data Catalog, <catalog_name>.catalog-impl defina comoorg.apache.iceberg.aws.glue.GlueCatalog. Essa chave é necessária para apontar para uma classe de implementação para qualquer implementação de catálogo personalizado. A seção de melhores práticas gerais, mais adiante neste guia, descreve os diferentes catálogos compatíveis com o Iceberg.

    • Use org.apache.iceberg.aws.s3.S3FileIO como para aproveitar <catalog_name>.io-impl as vantagens do upload de várias partes do Amazon S3 para obter alto paralelismo.

  4. Agora você pode começar a desenvolver interativamente seu aplicativo Spark para o Iceberg no notebook, como faria com qualquer outro aplicativo Spark.

Para obter mais informações sobre como configurar o Spark para o Apache Iceberg usando o Amazon EMR Studio, consulte a postagem do blog Crie um data lake evolutivo de alto desempenho, compatível com ACID, usando o Apache Iceberg no Amazon EMR. 

Executando trabalhos do Iceberg no Amazon EMR

Depois de desenvolver o código do aplicativo Spark para sua carga de trabalho do Iceberg, você pode executá-lo em qualquer opção de implantação do Amazon EMR que suporte o Iceberg (consulte as perguntas frequentes do Amazon EMR).

Assim como em outros trabalhos do Spark, você pode enviar trabalhos para um cluster do Amazon EMR no Amazon EC2 adicionando etapas ou enviando interativamente trabalhos do Spark para o nó principal. Para executar um trabalho do Spark, consulte as seguintes páginas de documentação do Amazon EMR:

As seções a seguir fornecem um exemplo para cada opção de implantação do Amazon EMR.

Amazon EMR no Amazon EC2

Você pode usar essas etapas para enviar a tarefa do Iceberg Spark:

  1. Crie o arquivo emr_step_iceberg.json com o seguinte conteúdo em sua estação de trabalho:

    [{ "Name": "iceberg-test-job", "Type": "spark", "ActionOnFailure": "CONTINUE", "Args": [ "--deploy-mode", "client", "--conf", "spark.sql.extensions=org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions", "--conf", "spark.sql.catalog.<catalog_name>=org.apache.iceberg.spark.SparkCatalog", "--conf", "spark.sql.catalog.<catalog_name>.catalog-impl=org.apache.iceberg.aws.glue.GlueCatalog", "--conf", "spark.sql.catalog.<catalog_name>.warehouse=s3://YOUR-BUCKET-NAME/YOUR-FOLDER-NAME/", "--conf", "spark.sql.catalog.<catalog_name>.io-impl=org.apache.iceberg.aws.s3.S3FileIO", "s3://YOUR-BUCKET-NAME/code/iceberg-job.py" ] }]
  2. Modifique o arquivo de configuração para sua tarefa específica do Spark personalizando as opções de configuração do Iceberg destacadas em negrito.

  3. Envie a etapa usando o AWS Command Line Interface (AWS CLI). Execute o comando no diretório em que o emr_step_iceberg.json arquivo está localizado.

    aws emr add-steps ‐‐cluster-id <cluster_id> ‐‐steps file://emr_step_iceberg.json

Amazon EMR Serverless

Para enviar uma tarefa do Iceberg Spark para o Amazon EMR Serverless usando: AWS CLI

  1. Crie o arquivo emr_serverless_iceberg.json com o seguinte conteúdo em sua estação de trabalho:

    { "applicationId": "<APPLICATION_ID>", "executionRoleArn": "<ROLE_ARN>", "jobDriver": { "sparkSubmit": { "entryPoint": "s3://YOUR-BUCKET-NAME/code/iceberg-job.py", "entryPointArguments": [], "sparkSubmitParameters": "--jars /usr/share/aws/iceberg/lib/iceberg-spark3-runtime.jar" } }, "configurationOverrides": { "applicationConfiguration": [{ "classification": "spark-defaults", "properties": { "spark.sql.extensions": "org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions", "spark.sql.catalog.<catalog_name>": "org.apache.iceberg.spark.SparkCatalog", "spark.sql.catalog.<catalog_name>.catalog-impl": "org.apache.iceberg.aws.glue.GlueCatalog", "spark.sql.catalog.<catalog_name>.warehouse": "s3://YOUR-BUCKET-NAME/YOUR-FOLDER-NAME/", "spark.sql.catalog.<catalog_name>.io-impl": "org.apache.iceberg.aws.s3.S3FileIO", "spark.jars":"/usr/share/aws/iceberg/lib/iceberg-spark3-runtime.jar", "spark.hadoop.hive.metastore.client.factory.class":"com.amazonaws.glue.catalog.metastore.AWSGlueDataCatalogHiveClientFactory" } }], "monitoringConfiguration": { "s3MonitoringConfiguration": { "logUri": "s3://YOUR-BUCKET-NAME/emr-serverless/logs/" } } } }
  2. Modifique o arquivo de configuração para sua tarefa específica do Spark personalizando as opções de configuração do Iceberg destacadas em negrito.

  3. Envie o trabalho usando AWS CLI o. Execute o comando no diretório em que o emr_serverless_iceberg.json arquivo está localizado:

    aws emr-serverless start-job-run ‐‐cli-input-json file://emr_serverless_iceberg.json

Para enviar uma tarefa do Iceberg Spark para o Amazon EMR Serverless usando o console do EMR Studio:

  1. Siga as instruções na documentação do Amazon EMR Serverless.

  2. Para a configuração do Job, use a configuração do Iceberg para o Spark fornecida para o AWS CLI e personalize os campos destacados do Iceberg. Para obter instruções detalhadas, consulte Usando o Apache Iceberg com o EMR Serverless na documentação do Amazon EMR.

Amazon EMR no Amazon EKS

Para enviar uma tarefa do Iceberg Spark para o Amazon EMR no Amazon EKS usando: AWS CLI

  1. Crie o arquivo emr_eks_iceberg.json com o seguinte conteúdo em sua estação de trabalho:

    { "name": "iceberg-test-job", "virtualClusterId": "<VIRTUAL_CLUSTER_ID>", "executionRoleArn": "<ROLE_ARN>", "releaseLabel": "emr-6.9.0-latest", "jobDriver": { "sparkSubmitJobDriver": { "entryPoint": "s3://YOUR-BUCKET-NAME/code/iceberg-job.py", "entryPointArguments": [], "sparkSubmitParameters": "--jars local:///usr/share/aws/iceberg/lib/iceberg-spark3-runtime.jar" } }, "configurationOverrides": { "applicationConfiguration": [{ "classification": "spark-defaults", "properties": { "spark.sql.extensions": "org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions", "spark.sql.catalog.<catalog_name>": "org.apache.iceberg.spark.SparkCatalog", "spark.sql.catalog.<catalog_name>.catalog-impl": "org.apache.iceberg.aws.glue.GlueCatalog", "spark.sql.catalog.<catalog_name>.warehouse": "s3://YOUR-BUCKET-NAME/YOUR-FOLDER-NAME/", "spark.sql.catalog.<catalog_name>.io-impl": "org.apache.iceberg.aws.s3.S3FileIO", "spark.hadoop.hive.metastore.client.factory.class": "com.amazonaws.glue.catalog.metastore.AWSGlueDataCatalogHiveClientFactory" } }], "monitoringConfiguration": { "persistentAppUI": "ENABLED", "s3MonitoringConfiguration": { "logUri": "s3://YOUR-BUCKET-NAME/emr-serverless/logs/" } } } }
  2. Modifique o arquivo de configuração da sua tarefa do Spark personalizando as opções de configuração do Iceberg destacadas em negrito.

  3. Envie o trabalho usando AWS CLI o. Execute o comando a seguir no diretório em que o emr_eks_iceberg.json arquivo está localizado:

    aws emr-containers start-job-run ‐‐cli-input-json file://emr_eks_iceberg.json

Para obter instruções detalhadas, consulte Como usar o Apache Iceberg com o Amazon EMR no EKS na documentação do Amazon EMR no EKS. 

Melhores práticas para o Amazon EMR

Esta seção fornece diretrizes gerais para ajustar trabalhos do Spark no Amazon EMR para otimizar a leitura e gravação de dados nas tabelas do Iceberg. Para conhecer as melhores práticas específicas do Iceberg, consulte a seção Melhores práticas mais adiante neste guia.

  • Use a versão mais recente do Amazon EMR — O Amazon EMR fornece otimizações do Spark prontas para usar com o tempo de execução do Amazon EMR Spark. AWS melhora o desempenho do mecanismo de tempo de execução do Spark a cada nova versão.

  • Determine a infraestrutura ideal para suas cargas de trabalho do Spark — As cargas de trabalho do Spark podem exigir diferentes tipos de hardware para diferentes características de trabalho para garantir o desempenho ideal. O Amazon EMR oferece suporte a vários tipos de instância (como otimizado para computação, otimizado para memória, uso geral e otimizado para armazenamento) para cobrir todos os tipos de requisitos de processamento. Ao integrar novas cargas de trabalho, recomendamos que você faça o benchmark com tipos gerais de instância, como M5 ou M6g. Monitore o sistema operacional (OS) e as métricas do YARN da Ganglia e da Amazon CloudWatch para determinar os gargalos do sistema (CPU, memória, armazenamento e E/S) no pico de carga e escolha o hardware apropriado.

  • Ajuste spark.sql.shuffle.partitions — defina a spark.sql.shuffle.partitions propriedade como o número total de núcleos virtuais (vCores) em seu cluster ou como um múltiplo desse valor (normalmente, 1 a 2 vezes o número total de vCores). Essa configuração afeta o paralelismo do Spark quando você usa particionamento de hash e intervalo como modo de distribuição de gravação. Ele solicita uma reprodução aleatória antes de gravar para organizar os dados, o que garante o alinhamento das partições.

  • Ative a escalabilidade gerenciada — Para quase todos os casos de uso, recomendamos que você habilite a escalabilidade gerenciada e a alocação dinâmica. No entanto, se você tiver uma carga de trabalho com um padrão previsível, sugerimos que você desative o escalonamento automático e a alocação dinâmica. Quando a escalabilidade gerenciada estiver habilitada, recomendamos que você use instâncias spot para reduzir custos. Use instâncias spot para nós de tarefas em vez de nós principais ou principais. Ao usar instâncias spot, use frotas de instâncias com vários tipos de instância por frota para garantir a disponibilidade spot.

  • Use a junção de transmissão quando possível — A junção de transmissão (no lado do mapa) é a melhor junção, desde que uma de suas tabelas seja pequena o suficiente para caber na memória do seu menor nó (na ordem de MBs) e você esteja realizando uma junção equi (=). Todos os tipos de junção, exceto as junções externas completas, são suportados. Uma junção de transmissão transmite a tabela menor como uma tabela de hash em todos os nós de trabalho na memória. Depois que a pequena tabela for transmitida, você não poderá fazer alterações nela. Como a tabela de hash está localmente na máquina virtual Java (JVM), ela pode ser mesclada facilmente com a tabela grande com base na condição de junção usando uma junção de hash. As junções de transmissão oferecem alto desempenho devido à sobrecarga mínima de reprodução aleatória.

  • Ajuste o coletor de lixo — Se os ciclos de coleta de lixo (GC) forem lentos, considere mudar do coletor de lixo paralelo padrão para o G1GC para melhorar o desempenho. Para otimizar o desempenho do GC, você pode ajustar os parâmetros do GC. Para monitorar o desempenho do GC, você pode monitorá-lo usando a interface do usuário do Spark. Idealmente, o tempo de GC deve ser menor ou igual a 1% do tempo de execução total da tarefa.