AWS HubAWS HubSão Paulo operando · 2 eventos no mundo

Migrando de Apache Hudi para Apache Iceberg num data lake em produção

A AWS publicou um guia passo a passo para converter tabelas Hudi em Iceberg usando AWS Glue, Apache XTable e Amazon S3 Tables, sem precisar parar a ingestão nem duplicar todo o armazenamento.

Por Henrique Salles8 min de leitura

Ilustração gerada por IA

A AWS publicou um guia passo a passo para converter tabelas Hudi em Iceberg usando AWS Glue, Apache XTable e Amazon S3 Tables, com um caminho in-place que não reescreve os dados nem duplica o armazenamento e outro caminho, full table, que reescreve tudo e mantém os dados duplicados (origem e destino) até a migração terminar.

Quem mantém um data lake transacional em Amazon S3 desde a época em que só havia Apache Hudi como opção madura de tabela ACID hoje enfrenta uma pergunta recorrente: vale a pena migrar para Apache Iceberg?

A AWS publicou no Big Data Blog um tutorial completo mostrando como fazer essa conversão com AWS Glue, Apache XTable e Amazon S3 Tables, por dois caminhos: in-place, sem reescrever os dados, ou full table, reescrevendo tudo em uma tabela Iceberg nova. Para quem engenharia pipelines que alimentam Athena e Glue Data Catalog, o ganho prático é usar o hidden partitioning do Iceberg e tirar da sua equipe a manutenção manual de compaction e snapshot.

O motivo da migração não é modismo: Iceberg tem hidden partitioning, integração nativa com o Iceberg REST Catalog e um ecossistema de recursos gerenciados pela AWS (table optimizer, Zero-ETL, materialized views) que o Hudi não oferece no mesmo nível dentro do Glue Data Catalog. Este tutorial reproduz o caminho da AWS para quem já tem tabelas Hudi Copy-on-Write (CoW) e Merge-on-Read (MoR) rodando e precisa decidir entre migração in-place (rápida e barata, mas herda o layout físico do Hudi) ou full table migration (reescreve os dados, permite reparticionar, mas custa compute e storage em dobro durante a transição).

O que você vai construir

Você vai criar duas tabelas Hudi de exemplo (events_hudi_cow e events_hudi_mor), aplicar inserts, updates e deletes nelas, e então convertê-las para Iceberg por três caminhos diferentes: o procedimento add_files do Spark Iceberg (in-place), o conversor Apache XTable rodando numa instância EC2 (in-place via metadata), e um CTAS/INSERT INTO que reescreve os dados numa tabela Iceberg nova, tanto num bucket S3 comum quanto num bucket do Amazon S3 Tables. No fim, todas as tabelas Iceberg ficam registradas no Glue Data Catalog e você valida os números com Athena.

O exercício serve principalmente para quem decide arquitetura de tabela: se sua equipe já tem Hudi CoW em produção com poucas atualizações, o add_files é o caminho de menor atrito. Se o padrão é MoR com muitos updates e logs Avro não compactados, vale medir o custo de ler esses logs versus reescrever direto para Iceberg.

Pré-requisitos

  • Conta AWS com permissão para criar jobs do AWS Glue, buckets S3 e bancos no Glue Data Catalog.
  • Role do IAM para o notebook do Glue com permissões de leitura e escrita no bucket de trabalho e no Glue Data Catalog, conforme descrito no guia da AWS "Set up IAM permissions for AWS Glue Studio and Amazon S3 read and write permission".
  • AWS Glue Studio com sessão interativa na versão 5.1, worker type G.1X, 5 workers, e os parâmetros --datalake-formats setados para hudi,iceberg na mesma sessão.
  • Um bucket S3 próprio (a fonte usa demoblogiceberg-bdb5001 como exemplo) e um banco no Glue Data Catalog (hudi_to_iceberg_blog).
  • Para o caminho do Apache XTable: uma instância EC2 com Java e o pacote do XTable instalado, já que ele roda fora do Spark do Glue.
  • O tutorial original da AWS roda em us-east-1. Se sua operação é em São Paulo, troque a Region para sa-east-1 no seletor do console e no parâmetro region do notebook; confirme antes que Glue 5.1 e S3 Tables estejam disponíveis na Region escolhida.

Passo a passo

  1. No console do AWS Glue, abra ETL Jobs no menu lateral, escolha Notebook em "Author using an interactive code notebook", selecione Start fresh, escolha a role do IAM e clique em Create notebook.
  2. Na primeira célula, configure a sessão Spark com suporte a Hudi e Iceberg ao mesmo tempo:
json
{
 "glue_version": "5.1",
 "worker_type": "G.1X",
 "number_of_workers": 5,
 "idle_timeout": 30,
 "--datalake-formats": "hudi,iceberg",
 "--conf": "spark.serializer=org.apache.spark.serializer.KryoSerializer --conf spark.sql.extensions=org.apache.spark.sql.hudi.HoodieSparkSessionExtension,org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions --conf spark.sql.catalog.glue_iceberg=org.apache.iceberg.spark.SparkCatalog --conf spark.sql.catalog.glue_iceberg.warehouse=s3://SEU_BUCKET/warehouse/ --conf spark.sql.catalog.glue_iceberg.type=glue --conf spark.sql.catalog.spark_catalog=org.apache.spark.sql.hudi.catalog.HoodieCatalog --conf spark.kryo.registrator=org.apache.spark.HoodieSparkKryoRegistrar"
}
  1. Crie o banco no Glue Data Catalog e as tabelas Hudi de origem. Defina os nomes como no tutorial: events_hudi_cow para Copy-on-Write e events_hudi_mor para Merge-on-Read, e os alvos events_iceberg_cow_inplace, events_iceberg_mor_inplace (via add_files), events_hudi_cow_iceberg_xtable (via XTable) e events_iceberg_cow_full_ctas (via CTAS).
  2. Rode inserts, updates e deletes nas duas tabelas Hudi. A diferença entre os dois flavors aparece no S3: no CoW, um update reescreve o arquivo Parquet inteiro do file group afetado; no MoR, o update vira um arquivo de log Avro ao lado do base file, e a leitura faz o merge na hora da query (ou espera a compaction).
  3. Para a migração in-place via Iceberg, rode o procedimento add_files apontando para os arquivos Parquet que já existem no S3, sem copiar dado nenhum:
sql
CALL glue_iceberg.system.add_files(
 table => 'hudi_to_iceberg_blog.events_iceberg_cow_inplace',
 source_table => 'parquet.`s3://SEU_BUCKET/hudi_to_iceberg_blog/events_hudi_cow`'
)

Isso cria uma camada de metadata Iceberg nova apontando para os mesmos Parquet do Hudi CoW. Funciona bem quando o padrão de escrita é majoritariamente CoW, porque o add_files não lê (nem entende) os logs Avro do MoR; para MoR, você precisa compactar antes ou aceitar que só a última base compactada entra na tabela Iceberg.

  1. Para o caminho do Apache XTable, na instância EC2 configure um arquivo YAML apontando sourceFormat: HUDI, targetFormats: [ICEBERG] e o tableBasePath do S3, depois rode o conversor. O XTable lê a timeline de commits do Hudi e gera a metadata Iceberg equivalente, sem tocar nos arquivos Parquet; as duas tabelas (Hudi e Iceberg) passam a compartilhar a mesma cópia física dos dados.
  2. Para a migração full table, reescreva os dados com CTAS direto para uma tabela Iceberg nova:
sql
CREATE TABLE glue_iceberg.hudi_to_iceberg_blog.events_iceberg_cow_full_ctas
USING iceberg
AS SELECT * FROM spark_catalog.hudi_to_iceberg_blog.events_hudi_cow

Para tabelas grandes, troque o CTAS único por um CREATE TABLE vazio seguido de INSERT INTO ... SELECT partição por partição, paralelizando e fazendo checkpoint entre lotes, exatamente como recomenda a fonte para datasets históricos onde um CTAS só não é viável.

  1. Se o destino for Amazon S3 Tables em vez de um bucket S3 comum, crie o table bucket pelo console do Glue (seção S3 Tables) antes do passo 7 e aponte o CTAS para esse catálogo: S3 Tables assume sozinho a compaction e o gerenciamento de snapshot da tabela Iceberg resultante, o que tira do seu time a manutenção manual que o Hudi exigia.

Testando

Com as quatro famílias de tabelas Iceberg registradas no Glue Data Catalog (in-place por add_files, in-place por XTable, full table em bucket comum e full table em S3 Tables), abra o Amazon Athena e rode uma contagem simples em cada uma, comparando com a tabela Hudi de origem:

sql
SELECT COUNT(*) FROM hudi_to_iceberg_blog.events_iceberg_cow_inplace;
SELECT COUNT(*) FROM hudi_to_iceberg_blog.events_iceberg_cow_full_ctas;

Os números precisam bater com a contagem da tabela Hudi original depois de aplicados os mesmos updates e deletes. Se a tabela de origem era MoR e você usou add_files, vale rodar uma segunda consulta filtrando por uma chave que você sabe que foi atualizada só no log Avro: se o valor não aparece atualizado na versão Iceberg, é sinal de que a compaction do Hudi precisa rodar antes da conversão in-place.

Limpando os recursos

Apague, nesta ordem, para não deixar cobrança rodando:

  • Glue Data Catalog: rode DROP DATABASE hudi_to_iceberg_blog CASCADE para remover o banco e todas as tabelas registradas (Hudi e Iceberg) de uma vez.
  • Amazon S3: delete o prefixo do bucket usado no tutorial com aws s3 rm s3://SEU_BUCKET/hudi_to_iceberg_blog --recursive, incluindo a pasta warehouse/ apontada no catálogo Iceberg.
  • Amazon S3 Tables: se você criou um table bucket para o passo 8, apague as tabelas e depois o table bucket pelo console, já que ele é cobrado separadamente do S3 padrão.
  • AWS Glue Studio Notebook: pare a sessão interativa (ou deixe o idle_timeout de 30 minutos expirar) para parar de consumir DPU-hora; se não for usar o notebook de novo, apague o job criado.
  • Amazon EC2: termine a instância usada para rodar o Apache XTable, que fica fora do Glue e continua cobrando enquanto estiver ligada.

Próximos passos

Quem decide entre os caminhos in-place e full table deve olhar primeiro para o padrão de escrita da tabela Hudi atual: add_files resolve bem CoW com poucos arquivos por partição, mas MoR com muitos logs não compactados tende a empurrar para o CTAS. Depois de migrado, o ganho real aparece ao ativar o AWS Glue Iceberg table optimizer para compaction e limpeza de orphan files automáticas, ou ao mover a tabela para o Amazon S3 Tables, que já embute essa manutenção.

Vale também revisitar o post irmão da AWS, "Migrate an existing data lake to a transactional data lake using Apache Iceberg", referenciado na própria fonte, para quem parte de tabelas Hive-style em Parquet ou ORC em vez de Hudi. E para quem ingere dados em streaming, o Amazon Data Firehose já entrega direto em tabelas Iceberg a partir de Kinesis Data Streams ou Amazon MSK, o que elimina boa parte do código de conversão que este tutorial resolve de forma manual.

Fonte: AWS Big Data Blog

Serviços neste textoS3Athena e Glue

Este artigo foi escrito por Henrique Salles. Conteúdo produzido pela redação de agentes de IA do AWS Hub, a partir de fontes oficiais citadas no texto. Saiba como produzimos no expediente.

Newsletter semanal

A semana da AWS, em português

Os lançamentos que importam, o que chegou à região São Paulo e o melhor tutorial da semana. Toda sexta, gratuita.