Delta Lake vs Apache Iceberg em 2026: Arquitetura Lakehouse e Perguntas de Entrevista

Comparação técnica completa entre Delta Lake e Apache Iceberg para arquiteturas lakehouse modernas. Guia prático com exemplos de código e perguntas de entrevista para data engineering.

Delta Lake vs Apache Iceberg em 2026: Arquitetura Lakehouse e Perguntas de Entrevista

Delta Lake e Apache Iceberg representam os dois formatos de tabela abertos dominantes que impulsionam as arquiteturas data lakehouse modernas em 2026. Ambas as tecnologias resolvem o mesmo problema fundamental—trazer transações ACID, evolução de schema e viagem no tempo para o armazenamento de objetos na nuvem—mas adotam abordagens arquiteturais diferentes que importam para cargas de trabalho em produção.

Comparação Rápida

Delta Lake se destaca em ambientes nativos Spark com integração estreita ao Databricks, enquanto Iceberg oferece compatibilidade mais ampla com engines (Spark, Trino, Flink, Dremio) e particionamento mais flexível através de partições ocultas e evolução de partições.

Delta Lake vs Iceberg: Diferenças Arquiteturais Fundamentais

Ambos os formatos armazenam dados como arquivos Parquet em armazenamento de objetos, mas suas camadas de metadados diferem significativamente.

Delta Lake utiliza um log de transações (_delta_log/) contendo arquivos JSON que registram cada alteração. Cada commit cria um novo arquivo JSON, e checkpoints periódicos consolidam esses arquivos em Parquet para leituras mais rápidas. A especificação do protocolo Delta Lake define recursos de leitura/escrita versionados para compatibilidade futura.

Apache Iceberg mantém uma hierarquia de arquivos de metadados: um arquivo JSON de metadados apontando para listas de manifestos, que por sua vez apontam para manifestos contendo estatísticas no nível do arquivo. Este design permite predicate pushdown na etapa de planejamento—o engine de consultas ignora arquivos inteiros antes de ler qualquer dado.

| Recurso | Delta Lake | Apache Iceberg | |---------|------------|----------------| | Log de Transações | JSON + checkpoints Parquet | JSON metadados + arquivos de manifesto | | Evolução de Partições | Requer reescrita | In-place sem reescrita | | Suporte a Engines | Spark, Trino, Flink | Spark, Trino, Flink, Dremio, Athena | | Viagem no Tempo | Baseado em versões | Baseado em snapshots com branch/tag | | Evolução de Schema | Adicionar/renomear colunas | Adicionar/renomear/reordenar/ampliar colunas |

Partições Ocultas: A Vantagem Chave do Iceberg

O particionamento tradicional estilo Hive expõe as colunas de partição nas consultas (WHERE year=2026 AND month=7), acoplando o layout físico à sintaxe SQL. As partições ocultas do Iceberg desacoplam essas preocupações.

python
# iceberg_partition_example.py
from pyiceberg.catalog import load_catalog
from pyiceberg.schema import Schema
from pyiceberg.types import StringType, TimestampType, LongType, NestedField
from pyiceberg.partitioning import PartitionSpec, PartitionField
from pyiceberg.transforms import MonthTransform

# Definição do schema
schema = Schema(
    NestedField(1, "event_id", LongType(), required=True),
    NestedField(2, "event_time", TimestampType(), required=True),
    NestedField(3, "user_id", StringType(), required=True),
    NestedField(4, "event_type", StringType(), required=False),
)

# Partição oculta sobre o mês extraído de event_time
partition_spec = PartitionSpec(
    PartitionField(
        source_id=2,  # campo event_time
        field_id=1000,
        transform=MonthTransform(),
        name="event_time_month"
    )
)

# Criação da tabela com particionamento oculto
catalog = load_catalog("production")
catalog.create_table(
    identifier="analytics.events",
    schema=schema,
    partition_spec=partition_spec
)

Os usuários escrevem WHERE event_time > '2026-01-01' e o Iceberg elimina automaticamente as partições irrelevantes. Esta abordagem simplifica as consultas e permite a evolução de partições sem reescrever dados.

Delta Lake: Gerenciamento do Log de Transações

O mecanismo de log de transações do Delta Lake fornece rastreabilidade completa das alterações. Cada operação gera um arquivo JSON atômico no diretório _delta_log.

python
# delta_transaction_log.py
from delta import DeltaTable
from pyspark.sql import SparkSession

spark = SparkSession.builder \
    .appName("DeltaTransactionDemo") \
    .config("spark.sql.extensions", "io.delta.sql.DeltaSparkSessionExtension") \
    .config("spark.sql.catalog.spark_catalog", "org.apache.spark.sql.delta.catalog.DeltaCatalog") \
    .getOrCreate()

# Criação de uma tabela Delta
data = [(1, "2026-07-15", "click"), (2, "2026-07-16", "purchase")]
df = spark.createDataFrame(data, ["id", "date", "event"])
df.write.format("delta").save("/data/events")

# Acesso ao histórico de transações
delta_table = DeltaTable.forPath(spark, "/data/events")
history = delta_table.history()
history.select("version", "timestamp", "operation", "operationMetrics").show()

Os checkpoints Parquet são criados a cada 10 commits por padrão, otimizando o desempenho de leitura ao evitar a reconstrução do estado a partir de múltiplos arquivos JSON.

Evolução de Schema: Comparação Prática

A evolução de schema representa um caso de uso crítico para pipelines de dados em produção. Ambos os formatos suportam adição de colunas, mas o Iceberg oferece capacidades mais avançadas.

sql
-- Evolução de schema Iceberg
ALTER TABLE analytics.events ADD COLUMN device_type STRING;
ALTER TABLE analytics.events ALTER COLUMN event_type SET NOT NULL;
ALTER TABLE analytics.events RENAME COLUMN event_type TO action_type;

-- Reordenamento de colunas (específico do Iceberg)
ALTER TABLE analytics.events ALTER COLUMN device_type FIRST;
ALTER TABLE analytics.events ALTER COLUMN user_id AFTER event_id;
sql
-- Evolução de schema Delta Lake
ALTER TABLE events ADD COLUMNS (device_type STRING);
-- Renomear requer habilitar column mapping
ALTER TABLE events SET TBLPROPERTIES ('delta.columnMapping.mode' = 'name');
ALTER TABLE events RENAME COLUMN event_type TO action_type;

O Delta Lake requer a habilitação explícita do column mapping para renomeação, enquanto o Iceberg o suporta nativamente através do seu sistema de identificadores de campo.

Viagem no Tempo e Gerenciamento de Versões

Ambos os formatos permitem consultar estados históricos dos dados, funcionalidade essencial para auditoria, debug e reprodutibilidade de análises.

python
# time_travel_comparison.py

# Delta Lake - Viagem no tempo
df_v1 = spark.read.format("delta").option("versionAsOf", 1).load("/data/events")
df_timestamp = spark.read.format("delta").option("timestampAsOf", "2026-07-15").load("/data/events")

# Restauração para uma versão anterior
delta_table = DeltaTable.forPath(spark, "/data/events")
delta_table.restoreToVersion(1)
python
# Iceberg - Viagem no tempo com snapshots
from pyiceberg.catalog import load_catalog

catalog = load_catalog("production")
table = catalog.load_table("analytics.events")

# Lista de snapshots disponíveis
for snapshot in table.snapshots():
    print(f"Snapshot {snapshot.snapshot_id}: {snapshot.timestamp_ms}")

# Leitura de um snapshot específico
df = spark.read \
    .format("iceberg") \
    .option("snapshot-id", 3821550127947089987) \
    .load("analytics.events")

# Branches e tags do Iceberg (funcionalidade avançada)
# CREATE TAG production_v1 FOR TABLE analytics.events
# CREATE BRANCH feature_test FOR TABLE analytics.events

O Iceberg oferece funcionalidades adicionais com branches e tags, permitindo workflows de desenvolvimento isolados sem duplicar dados.

Otimização e Manutenção de Tabelas

As operações de manutenção são cruciais para manter o desempenho das tabelas lakehouse ao longo do tempo.

python
# delta_optimization.py
from delta.tables import DeltaTable

delta_table = DeltaTable.forPath(spark, "/data/events")

# Compactação de arquivos pequenos
delta_table.optimize().executeCompaction()

# Z-Ordering para melhorar o data skipping
delta_table.optimize().executeZOrderBy("user_id", "event_time")

# Vacuum para remover arquivos obsoletos
delta_table.vacuum(168)  # Retenção de 7 dias em horas

# Estatísticas de colunas
spark.sql("ANALYZE TABLE events COMPUTE STATISTICS FOR ALL COLUMNS")
python
# iceberg_maintenance.py

# Compactação Iceberg via Spark
spark.sql("""
    CALL system.rewrite_data_files(
        table => 'analytics.events',
        options => map('target-file-size-bytes', '134217728')
    )
""")

# Expiração de snapshots
spark.sql("""
    CALL system.expire_snapshots(
        table => 'analytics.events',
        older_than => TIMESTAMP '2026-07-01 00:00:00',
        retain_last => 5
    )
""")

# Remoção de arquivos órfãos
spark.sql("""
    CALL system.remove_orphan_files(
        table => 'analytics.events',
        older_than => TIMESTAMP '2026-07-01 00:00:00'
    )
""")

Perguntas de Entrevista Data Engineering: Arquitetura Lakehouse

As entrevistas de data engineering em 2026 frequentemente incluem perguntas sobre arquiteturas lakehouse. Estes são os temas técnicos essenciais para dominar.

Pergunta 1: Explicar as vantagens das partições ocultas do Iceberg

A resposta esperada deve cobrir: o desacoplamento entre o layout físico e a sintaxe SQL, a eliminação automática de partições pelo engine de consultas, e a possibilidade de evoluir o schema de particionamento sem reescrever os dados existentes.

Pergunta 2: Como o Delta Lake garante transações ACID?

O Delta Lake utiliza bloqueio otimista com um log de transações append-only. Cada commit verifica que a versão base não mudou desde a leitura. Em caso de conflito, a operação falha e pode ser reexecutada. Os checkpoints Parquet permitem uma reconstrução rápida do estado.

Pergunta 3: Quando escolher Iceberg em vez de Delta Lake?

O Iceberg é mais adequado quando: múltiplos engines de consulta precisam acessar os mesmos dados (Spark, Trino, Flink), a evolução de partições é uma necessidade recorrente, ou a organização prefere um formato verdadeiramente aberto sem dependência de um fornecedor específico.

python
# interview_code_example.py
# Pergunta: Implementar um upsert com Delta Lake

from delta.tables import DeltaTable

def upsert_events(spark, source_df, target_path):
    """Merge incremental events into Delta table."""
    target_table = DeltaTable.forPath(spark, target_path)
    
    target_table.alias("target").merge(
        source_df.alias("source"),
        "target.event_id = source.event_id"
    ).whenMatchedUpdate(set={
        "event_time": "source.event_time",
        "event_type": "source.event_type",
        "updated_at": "current_timestamp()"
    }).whenNotMatchedInsert(values={
        "event_id": "source.event_id",
        "event_time": "source.event_time",
        "event_type": "source.event_type",
        "created_at": "current_timestamp()",
        "updated_at": "current_timestamp()"
    }).execute()

Pergunta 4: Descrever a estratégia de data skipping

Ambos os formatos mantêm estatísticas min/max por arquivo. Ao executar uma consulta com predicados, o engine compara os valores dos predicados com as estatísticas e elimina os arquivos que não podem conter correspondências. O Z-Ordering (Delta) e o sorting (Iceberg) melhoram a eficiência agrupando valores similares.

Pronto para mandar bem nas entrevistas de Data Engineering?

Pratique com nossos simuladores interativos, flashcards e testes tecnicos.

Integração com Catálogos de Metadados

Os catálogos de metadados centralizam o gerenciamento de tabelas lakehouse e permitem a descoberta de dados em escala organizacional.

python
# catalog_integration.py

# Configuração Unity Catalog para Delta Lake
spark = SparkSession.builder \
    .config("spark.sql.catalog.unity", "com.databricks.sql.managedcatalog.UnityCatalogSpark") \
    .config("spark.databricks.unityCatalog.enabled", "true") \
    .getOrCreate()

# Configuração Iceberg com AWS Glue Catalog
spark = SparkSession.builder \
    .config("spark.sql.catalog.glue_catalog", "org.apache.iceberg.spark.SparkCatalog") \
    .config("spark.sql.catalog.glue_catalog.warehouse", "s3://datalake/warehouse") \
    .config("spark.sql.catalog.glue_catalog.catalog-impl", "org.apache.iceberg.aws.glue.GlueCatalog") \
    .config("spark.sql.catalog.glue_catalog.io-impl", "org.apache.iceberg.aws.s3.S3FileIO") \
    .getOrCreate()

# Configuração Iceberg com REST Catalog (Polaris, Tabular)
spark = SparkSession.builder \
    .config("spark.sql.catalog.rest_catalog", "org.apache.iceberg.spark.SparkCatalog") \
    .config("spark.sql.catalog.rest_catalog.type", "rest") \
    .config("spark.sql.catalog.rest_catalog.uri", "https://catalog.example.com") \
    .getOrCreate()

Performance: Benchmarks e Considerações

O desempenho depende fortemente do caso de uso específico, do tamanho dos dados e do engine de consultas utilizado.

Para leituras analíticas intensivas, o Iceberg pode oferecer vantagem graças ao seu planejamento de consultas mais eficiente baseado em manifestos. Para workloads de streaming com micro-batches frequentes, o Delta Lake com seu log de transações otimizado pode ser mais performático.

python
# performance_monitoring.py

# Métricas Delta Lake
spark.sql("DESCRIBE HISTORY events").show()
spark.sql("DESCRIBE DETAIL events").show()

# Métricas Iceberg
spark.sql("SELECT * FROM analytics.events.metadata_log_entries").show()
spark.sql("SELECT * FROM analytics.events.manifests").show()
spark.sql("SELECT * FROM analytics.events.files").show()

Conclusão

Delta Lake e Apache Iceberg representam duas abordagens maduras para arquitetura lakehouse em 2026. O Delta Lake oferece integração nativa com o ecossistema Databricks e Spark, enquanto o Iceberg prioriza a interoperabilidade multi-engine e a flexibilidade do particionamento.

A escolha entre essas tecnologias depende principalmente do ecossistema existente, dos requisitos de interoperabilidade e dos padrões de acesso aos dados. Ambos os formatos continuam evoluindo com funcionalidades convergentes, como o Delta Lake UniForm que permite a leitura de tabelas Delta através das APIs do Iceberg.

Para entrevistas de data engineering, o domínio dos conceitos fundamentais—transações ACID sobre armazenamento de objetos, evolução de schema, viagem no tempo e otimização de performance—permanece mais importante do que o conhecimento profundo de um formato específico.

Compartilhar

Artigos relacionados