CURSOS / TECNOLOGIA / ENGENHARIA DE DADOS (MÓDULO 4 DE 4)
Sistemas de Dados · Módulo 4 de 4 · Bases de Infraestrutura

Sob o capô dos bytes
e da rede na nuvem.

Feche a formação dominando a física invisível que multiplica por 100x a velocidade dos seus pipelines: serialização em linha e colunar (Avro, Parquet, ORC), processamento zero-copy em memória com Apache Arrow, tabelas híbridas (Iceberg e Hudi), compressão moderna (Zstandard, Snappy, LZ4), topologia de rede na nuvem (AZs, Regiões, VPCs, Egress) e execução em contêineres.

Mesa de carvalho com paquímetro de latão medindo placas de vidro translúcidas em camadas, caderno com diagramas de serialização binária e topologia de rede na nuvem e notebook exibindo código PyArrow e Parquet
8 oficinasbaseadas nos Apêndices A e B de Joe Reis e Matt Housley
4 módulosconcluídos na trilha completa de Engenharia de Dados
Performance 100xcom Parquet, Apache Arrow, Zstd e Rede Cloud
Percurso completo em 4 cursos · Fundamentals of Data Engineering + Atualização 2026

Trilha de formação: Engenharia de Dados do fundamento estratégico à produção

Nos Apêndices A e B, Joe Reis e Matt Housley reúnem os detalhes técnicos de baixo nível que todo engenheiro de dados sênior precisa dominar para diagnosticar gargalos de CPU, memória, disco e rede na nuvem. Você está no Módulo 4 (Etapa Final).

Percurso do Módulo 4 (Apêndices A e B + Evolução 2026)

Explore as oito oficinas finais e teste localmente em Python como formatos de serialização, codecs de compressão e topologia de rede transformam o desempenho e o custo da sua plataforma.

Plantas técnicas de roteamento de rede e blocos de armazenamento colunar sobre papel arquivístico com compasso de latão e cubos de vidro óptico

“Já vimos o desempenho de jobs melhorar por um fator de 100 simplesmente trocando a serialização de CSV para Parquet.”

No Apêndice A de Fundamentals of Data Engineering, Joe Reis e Matt Housley demonstram que entender como os bytes são empacotados no disco, na memória RAM e nos cabos de rede da nuvem é um superpoder prático do engenheiro de dados.
Oficina 01 / 08

Serialização Baseada em Linhas: O Padrão Não-Padrão CSV, XML, JSONL e Apache Avro

Um arquivo CSV exportado por um ERP parceiro contém uma quebra de linha e um ponto e vírgula dentro do campo de observações, deslocando todas as colunas seguintes e corrompendo silenciosamente o carregamento noturno. Como tratar formatos orientados a linhas e realizar a reserialização segura?

O que é Serialização, Reserialização e o Problema do CSV ("The Nonstandard Standard")

No Apêndice A (páginas 529–531), Joe Reis e Matt Housley lembram que, na memória de um programa em execução, os dados vivem espalhados em estruturas complexas conectadas por ponteiros; para salvar esses dados em um disco ou transmiti-los pela rede para outro sistema, precisamos de Serialização (codificar em uma sequência contígua de bytes) e, na leitura, de Deserialização. Ao longo do pipeline, o engenheiro de dados gerencia constantemente a Reserialização: receber dados em um formato bruto ou legado da origem, tratar exceções e convertê-los imediatamente para um formato rápido e tipado para as etapas seguintes.

Na Serialização Baseada em Linhas (Row-Based Serialization), cada registro ou objeto completo é gravado sequencialmente um após o outro. O livro analisa os quatro formatos orientados a linhas que você encontrará na prática:

Formatos de serialização baseada em linhas (Apêndice A, páginas 529–531)
Formato em LinhaCaracterísticas TécnicasRecomendação Prática de Engenharia
1. CSV
(“The nonstandard standard”)
Texto delimitado sem padrão único para caracteres de escape, aspas, delimitadores (vírgula vs. ponto e vírgula), codificação (UTF-8 vs. Latin-1) e zero informação de tipo/schema.Evite usar CSV dentro dos seus pipelines internos! Se for obrigado a receber ou arquivar CSVs para parceiros externos, documente formalmente toda a configuração técnica de serialização (encoding, quote char, escape, separador).
2. XML
(Extensible Markup Language)
Formato textual marcado por tags verbosas; popular nos primórdios da web e em sistemas corporativos/fiscais legados (como NF-e e SOAP).Lento para serializar e deserializar e ocupa muito espaço; converta (reserialize) para formatos modernos assim que cruzar a camada de ingestão.
3. JSON e JSONL
(JSON Lines)
JSON é o padrão universal de APIs e Document Stores; JSONL grava uma sequência de objetos JSON separados por quebra de linha (\n), permitindo leitura em streaming linha a linha.JSONL é excelente para armazenar o dado bruto imediatamente após a ingestão de APIs ou logs (camada Landing/Raw), mas deve ser convertido para formato colunar (Parquet/Iceberg) nas etapas seguintes.
4. Apache AvroFormato binário orientado a linhas projetado para RPCs e streaming, com metadados de schema definidos em JSON embutidos no próprio arquivo ou gerenciados via Schema Registry.Padrão ouro para filas de eventos (Kafka/PubSub), capturas CDC brutas e escrita linha a linha rápida com suporte nativo à evolução de schema.
Comando para experimentar (Pipeline de Reserialização: CSV Frágil → JSONL Tipado + Schema estilo Avro)
# Veja na prática como isolar ambiguidades de um CSV com quebras/vírgulas internas
# e reserializá-lo para registros tipados com contrato de schema explícito (estilo Avro/JSONL):
python3 - <<'PY'
import csv, io, json

csv_bruto = '''id_pedido,cliente,observacao,valor
101,"Ana Silva","Entrega rápida, portaria 2",250.50
102,"Bruno Costa","Cuidado: item frágil; ligar antes",189.00'''

leitor = csv.DictReader(io.StringIO(csv_bruto), delimiter=",", quotechar='"')
schema_avro = {
    "type": "record",
    "name": "PedidoIngestao",
    "fields": [
        {"name": "id_pedido", "type": "int"},
        {"name": "cliente", "type": "string"},
        {"name": "observacao", "type": "string"},
        {"name": "valor", "type": "double"}
    ]
}

print("Schema Avro de Validação:", json.dumps(schema_avro))
print("\nSaída Reserializada e Tipada (JSONL):")
for row in leitor:
    registro_tipado = {
        "id_pedido": int(row["id_pedido"]),
        "cliente": row["cliente"].strip(),
        "observacao": row["observacao"].strip(),
        "valor": float(row["valor"])
    }
    print(json.dumps(registro_tipado, ensure_ascii=False))
PY
Laboratório avançado · Por que um arquivo JSON gigante único (`[ {...}, {...} ]`) é muito pior para ingestão distribuída do que o formato JSONL?

Em um arquivo JSON tradicional que abre com um colchete [ no primeiro byte e fecha com ] no último byte de um arquivo de 10 GB, o parser precisa validar a estrutura inteira para extrair os objetos, dificultando dividir o arquivo entre múltiplos workers (splittable) ou anexar novos eventos no final. Já no JSON Lines (JSONL / NDJSON), cada linha é um objeto JSON 100% independente separado por \n: você pode processar linha por linha em streaming com consumo mínimo de memória RAM ou fatiar o arquivo em blocos paralelos.

Entrega da etapa

Defina a política de entrada e Reserialização do seu pipeline: especifique como serão tratados arquivos CSV ou XML legados de terceiros, onde você utilizará JSONL ou Apache Avro na ingestão de eventos/APIs e em qual ponto exato do pipeline os dados serão convertidos para formato colunar.

Conexão com o livro · Apêndice A (Seção A.1: Serialization Formats & Row-Based Serialization) · reserialização, CSV (“The nonstandard standard”), XML, JSON, JSONL e Apache Avro.

Oficina 02 / 08

Serialização Colunar por Dentro: Apache Parquet, ORC e o Trade-Off de Mutação

Por que simplesmente converter um dataset analítico de CSV para Apache Parquet chega a acelerar consultas em até 100x — mas tentar atualizar uma única linha dentro de um arquivo colunar direto no disco é proibitivo?

Como a Serialização Colunar Pivota os Bytes no Disco (Páginas 531–533)

Enquanto formatos orientados a linhas gravam todas as colunas da Linha 1, seguidas por todas as colunas da Linha 2, a Serialização Colunar (Columnar Serialization) pivota a organização física dos dados: todos os valores da Coluna A ficam agrupados juntos, seguidos por todos os valores da Coluna B (geralmente dentro de blocos horizontais chamados Row Groups). Nas páginas 531–532, Reis e Housley explicam os dois ganhos imediatos dessa física:

  1. Leitura Seletiva de Colunas (Projection Pushdown): se uma tabela possui 100 colunas e sua consulta analítica pede apenas SELECT regiao, SUM(receita), o motor lê do disco exclusivamente os blocos das colunas regiao e receita, ignorando 98% dos bytes do arquivo!
  2. Tokenização e Altíssima Taxa de Compressão: colocar valores da mesma coluna lado a lado aproxima dados do mesmo tipo e com enorme repetição. Uma técnica simples e poderosa descrita no livro é a Tokenização / Dictionary Encoding: identificar valores que se repetem milhares de vezes na coluna (ex.: "SÃO PAULO", "CARTÃO_CRÉDITO") e substituí-los por pequenos inteiros ou tokens combinados com Run-Length Encoding (RLE). Mesmo em colunas de texto livre (como mensagens de suporte ao cliente), o vocabulário semelhante dentro da mesma coluna permite que algoritmos de compressão atinjam taxas altíssimas, economizando disco e banda de rede.

Porém, toda escolha arquitetural tem um trade-off (página 532): formatos colunares são péssimos para cargas de trabalho transacionais (OLTP). Para reconstruir um único registro completo, o motor precisa buscar pedaços em vários blocos de colunas diferentes; e para alterar um único campo de uma linha, é preciso descomprimir o bloco da coluna inteira, modificar o valor, recomprimir tudo e gravar um novo arquivo! Por isso, quebramos tabelas grandes em múltiplos arquivos particionados e usamos camadas de metadados (como Apache Iceberg).

Apache Parquet vs. Apache ORC e Portabilidade Poliglota

O Apêndice A compara os dois grandes formatos colunares abertos do ecossistema:

Apache Parquet vs. Apache ORC vs. Formatos Proprietários (Páginas 532–533)
Formato ColunarPontos FortesConsiderações de Interoperabilidade em 2026
Apache ParquetEmbute schema rigoroso no rodapé (footer), suporta dados aninhados complexos (STRUCT/ARRAY/MAP) nativamente, armazena estatísticas min/max por Row Group/Page e é lido/escrito por todos os motores modernos.Padrão universal absoluto em 2026 para Data Lakes e Lakehouses (Apache Iceberg / Delta Lake), evitando o custo pesado de deserializar e reserializar dados presos em formatos internos fechados de um único warehouse.
Apache ORC
(Optimized Row Columnar)
Excelente compressão e índices internos; muito popular historicamente no ecossistema Apache Hive.Menor suporte para exportação direta em ferramentas modernas de nuvem (como lembram os autores, Snowflake e BigQuery importam e exportam Parquet, mas não exportam para ORC).
Comando para experimentar (Tokenização Colunar / Dictionary Encoding + Run-Length Encoding)
# Veja como a serialização colunar comprime drasticamente uma coluna categórica
# usando Dictionary Encoding (Tokenização) + Run-Length Encoding (RLE), como faz o Parquet:
python3 - <<'PY'
coluna_status = ["PAGO"] * 500 + ["PENDENTE"] * 300 + ["CANCELADO"] * 200
bytes_brutos = sum(len(s.encode("utf-8")) for s in coluna_status)

# 1. Dictionary Encoding (mapeia cada string única para um inteiro curto):
dicionario = {val: idx for idx, val in enumerate(sorted(set(coluna_status)))}
tokens = [dicionario[s] for s in coluna_status]

# 2. Run-Length Encoding (RLE: agrupa sequências repetidas como pares [token, contagem]):
rle = []
for t in tokens:
    if not rle or rle[-1][0] != t:
        rle.append([t, 1])
    else:
        rle[-1][1] += 1

representacao_compacta = {"dict": dicionario, "rle_runs": rle}
bytes_compactos = len(str(representacao_compacta).encode("utf-8"))

print(f"Tamanho bruto de 1.000 valores na coluna: {bytes_brutos} bytes")
print(f"Representação Colunar (Dict + RLE):       {representacao_compacta}")
print(f"Tamanho após codificação colunar:         {bytes_compactos} bytes (Redução de {(1 - bytes_compactos/bytes_brutos)*100:.1f}%)")
PY
Laboratório avançado · Qual é o tamanho ideal de Row Group e de arquivo físico no Apache Parquet?

Se você gerar milhares de arquivos Parquet minúsculos de 1 MB, o motor analítico gastará mais tempo abrindo conexões HTTP no Object Storage e lendo rodapés de metadados do que processando dados. Por outro lado, se um único Row Group tiver 5 GB, um worker com pouca memória RAM pode sofrer Out of Memory ao descomprimir as páginas. Na prática de produção com Apache Iceberg, mire em arquivos Parquet entre 128 MB e 512 MB com Row Groups de 64 MB a 256 MB e colunas mais filtradas ordenadas (Z-order / sort order) para maximizar o descarte de blocos via estatísticas min/max.

Entrega da etapa

Especifique o padrão de armazenamento colunar do seu Lakehouse: justifique a adoção do Apache Parquet como formato base, defina o tamanho-alvo dos arquivos e dos Row Groups, escolha quais colunas serão usadas na ordenação física para maximizar a compressão por dicionário/RLE e explique como evitará mutações linha a linha diretas nos arquivos colunares.

Conexão com o livro · Apêndice A (Seção A.2: Columnar Serialization) · projeção de colunas, tokenização de valores repetidos, trade-off de atualização em bancos colunares, Apache Parquet e Apache ORC.

Oficina 03 / 08

Apache Arrow: Serialização Colunar em Memória, Zero-Copy, Shredding e DuckDB/Polars

Por que passar um DataFrame de um motor em Java/C++/Rust para o Python costumava consumir mais CPU e memória convertendo objetos do que executando o próprio algoritmo — e como o Apache Arrow eliminou essa barreira?

Repensando a Serialização em Memória e o Fim do Imposto de Deserialização

Nas páginas 533–534, Reis e Housley dedicam uma seção especial ao Apache Arrow. Tradicionalmente, linguagens de programação guardavam tipos simples em arrays contíguos (como em C ou Fortran), mas estruturas tabulares e documentos aninhados ficavam espalhados na memória RAM através de ponteiros, e cada linguagem (Python, Java, Scala, R, Rust, Go) organizava seus objetos em memória de um jeito incompatível. Sempre que o Spark (JVM) precisava enviar dados para o Python (PySpark/Pandas) ou um banco enviava resultados para um cliente, os dois lados pagavam um imposto pesadíssimo de serialização e deserialização.

A grande sacada do Apache Arrow foi criar um formato binário colunar padronizado na própria memória RAM que serve, sem nenhuma conversão, para três finalidades simultâneas:

  1. Processamento direto na memória (In-Memory Processing): cada coluna reside em buffers contíguos de memória alinhados para instruções vetorizadas SIMD das CPUs modernas.
  2. Leitura Zero-Copy via Memória Virtual (`mmap`) e Intercâmbio entre Linguagens: você pode mapear um arquivo Arrow em disco diretamente no espaço de endereçamento de memória virtual do processo e começar a rodar consultas imediatamente, sem overhead de deserialização (paginando blocos para dentro e para fora da RAM para processar datasets maiores que a memória física!). Além disso, um processo em Rust, C++ ou Java pode passar o ponteiro do buffer Arrow para um processo em Python (Zero-Copy) sem copiar nem converter um único byte.
  3. Shredding de Dados Aninhados (página 533): para lidar com documentos JSON aninhados, o Arrow utiliza uma técnica chamada shredding (fatiamento), que mapeia cada localização/caminho do schema do documento aninhado em uma coluna contígua separada na memória, trazendo velocidade colunar até para dados semiestruturados.

Na atualização prática para 2026, o Apache Arrow tornou-se a espinha dorsal invisível da engenharia de dados moderna: o Polars utiliza o layout de memória do Apache Arrow nativamente em Rust; o DuckDB lê e transmite fluxos Arrow sem cópia; protocolos como Arrow Flight e ADBC (Arrow Database Connectivity) substituíram o gargalo serial dos antigos drivers JDBC/ODBC ao transferir gigabytes por segundo em formato colunar direto pela rede; e novos formatos colunares para IA e vetores (como Lance, construído sobre Arrow) permitem acesso aleatório sub-milissegundo a embeddings e imagens de treinamento.

Fluxo Clássico com Deserialização vs. Ecossistema Apache Arrow em 2026
Operação no PipelineModelo Tradicional (Pré-Arrow)Modelo Apache Arrow (2026)
Troca entre Motores / Linguagens
(ex.: SQL Engine → Python)
Serializa objetos para bytes intermediários → copia buffer → deserializa objeto por objeto em Python (70%+ de CPU perdida).Zero-Copy Memory Sharing: DuckDB, Polars e PyArrow leem exatamente o mesmo endereço de memória colunar instantaneamente.
Conexão com Bancos Analíticos
(Driver de Rede)
Drivers JDBC/ODBC tradicionais convertendo dados colunares do banco para linhas e depois de volta para colunas no cliente.Arrow Flight / ADBC: transmite lotes colunares (RecordBatches) comprimidos direto pela rede para a memória do cliente.
Documentos JSON AninhadosPercorrer árvores de ponteiros lentas na memória para cada documento.Columnar Shredding: cada campo aninhado vira um vetor contíguo processado com instruções SIMD da CPU.
Comando para experimentar (Shredding Colunar estilo Apache Arrow + Processamento Vetorizado)
# Veja como funciona o "Shredding" (fatiamento colunar em memória do Apache Arrow)
# transformando objetos JSON aninhados em buffers colunares contíguos para leitura instantânea:
python3 - <<'PY'
documentos_json = [
    {"id": 1, "cliente": {"uf": "SP", "vip": True},  "metricas": {"latencia_ms": 12}},
    {"id": 2, "cliente": {"uf": "RJ", "vip": False}, "metricas": {"latencia_ms": 18}},
    {"id": 3, "cliente": {"uf": "SP", "vip": True},  "metricas": {"latencia_ms": 9}}
]

# Shredding: cada caminho folha do JSON aninhado vira um buffer colunar contíguo:
buffers_arrow = {
    "id":                   [d["id"] for d in documentos_json],
    "cliente.uf":           [d["cliente"]["uf"] for d in documentos_json],
    "cliente.vip":          [d["cliente"]["vip"] for d in documentos_json],
    "metricas.latencia_ms": [d["metricas"]["latencia_ms"] for d in documentos_json]
}

print("Buffers Colunares em Memória (Shredding Apache Arrow):")
for caminho, vetor in buffers_arrow.items():
    print(f"  Coluna '{caminho:20}' -> {vetor}")

# Consulta analítica lê apenas os 2 vetores necessários na memória:
media_vip = sum(lat for vip, lat in zip(buffers_arrow["cliente.vip"], buffers_arrow["metricas.latencia_ms"]) if vip) / 2
print(f"\nMédia de latência clientes VIP (lendo apenas 2 buffers): {media_vip:.1f} ms")
PY
Laboratório avançado · Por que o Pandas 2.x/3.x adotou PyArrow e mesmo assim Polars e DuckDB levam vantagem em pipelines?

Embora o Pandas tenha substituído gradualmente seus tipos internos baseados em NumPy por tipos apoiados em PyArrow (o que reduziu drasticamente o consumo de memória de strings e valores nulos), o Pandas mantém por compatibilidade uma API de execução imediata (eager evaluation) que materializa DataFrames intermediários a cada linha de código. Já o Polars (via LazyFrame) e o DuckDB possuem um Otimizador de Consultas completo sobre os buffers Arrow: eles analisam todo o encadeamento de filtros, projeções e joins antes de tocar nos dados, empurram filtros para a leitura do Parquet (predicate pushdown) e executam tudo em streaming paralelo multi-core sem criar cópias intermediárias na RAM.

Entrega da etapa

Planeje o uso do Apache Arrow no seu pipeline: identifique onde hoje ocorrem conversões caras de dados em memória ou via drivers JDBC/ODBC lentos e descreva como você usará Arrow / ADBC / DuckDB / Polars para eliminar cópias desnecessárias e processar dados aninhados com shredding.

Conexão com o livro · Apêndice A (Seção A.2.3: Apache Arrow or in-memory serialization) · formato binário em memória, eliminação do overhead de deserialização, shredding de JSON aninhado, swap via memória virtual e interoperabilidade entre linguagens + Atualização 2026 (DuckDB, Polars, Arrow Flight/ADBC e Lance).

Oficina 04 / 08

Serialização Híbrida (Hudi e Iceberg) e Motores de Armazenamento de Bancos

Se arquivos colunares Parquet são lentos para atualizar uma única linha e formatos em linha Avro são lentos para varreduras analíticas, como combinar o melhor dos dois mundos para receber fluxos contínuos de CDC no Lakehouse?

Serialização Híbrida: Como Apache Hudi e Apache Iceberg resolvem o dilema (Páginas 534–535)

Na Seção A.3, Reis e Housley cunham o termo Hybrid Serialization (Serialização Híbrida) para descrever tecnologias de gerenciamento de tabelas que combinam múltiplas técnicas de serialização ou integram a serialização física a camadas de abstração de metadados, snapshots e evolução de schema:

  • Apache Hudi (*Hadoop Update Delete Incremental*): combina engenhosamente os dois formatos físicos! Quando um stream de CDC chega de um banco transacional com milhares de atualizações por minuto, o Hudi (no modo Merge-on-Read) grava as mutações recentes rapidamente em arquivos de log orientados a linhas (Avro), enquanto mantém a base histórica da tabela em arquivos colunares (Parquet). Quando uma consulta analítica roda, ela lê os arquivos Parquet combinados aos logs incrementais para devolver o estado exato atual; periodicamente, um processo assíncrono de repacking / compaction funde os arquivos em linha e em coluna gerando novos arquivos Parquet otimizados.
  • Apache Iceberg: gerencia todas as mutações em escala petabyte através de uma árvore imutável de metadados e snapshots sobre o Object Storage. Para suportar atualizações e deleções rápidas sem reescrever arquivos Parquet inteiros a cada segundo, o Iceberg v2/v3 permite gravar pequenos Delete Files (arquivos de deleção posicional ou por igualdade) ao lado dos arquivos de dados colunares, reconciliando-os em leitura (Merge-on-Read) e compactando-os em background, além de oferecer Time Travel completo e Schema Evolution segura por IDs de coluna (você pode renomear, reordenar ou promover o tipo de uma coluna sem reescrever um único arquivo Parquet!).

Database Storage Engines: A Camada Invisível sob o Query Engine (Página 535)

Na Seção A.4, os autores explicam que todo banco de dados é dividido internamente em duas camadas de software distintas: o Query Engine (que recebe o SQL, otimiza o plano e coordena a execução) e o Storage Engine (Motor de Armazenamento) (que gerencia como os bytes são serializados no disco, o arranjo físico das páginas, os índices e o controle de concorrência). Enquanto sistemas como BigQuery e Snowflake mantêm seus motores de armazenamento internos abstraídos do usuário, outros bancos expõem escolhas arquiteturais decisivas:

Evolução dos Motores de Armazenamento de Bancos de Dados (Seção A.4 + 2026)
Tipo de Storage EngineEstrutura Física e ÍndicesComportamento e Evolução em 2026
Motores OLTP Clássicos
(InnoDB no MySQL, Heap/B-Tree no PostgreSQL)
Páginas orientadas a linhas (ex.: 8 KB ou 16 KB) indexadas por árvores B-Tree / B+Tree, otimizadas para leituras/escritas pontuais em SSDs.Excelentes para transações ACID de baixa latência; o MySQL permite até trocar o motor plugável por tabela.
Motores LSM-Tree
(RocksDB, Cassandra, HBase)
Log-Structured Merge-Tree: grava escritas sequencialmente em memória (MemTable) e despeja arquivos imutáveis ordenados (SSTables) no SSD com compactação em background.Altíssima taxa de escrita contínua em SSDs modernos e base de armazenamento de estado para motores de streaming como Apache Flink.
Motores Colunares e Híbridos em RDBMS
(SQL Server Columnstore, Postgres + pg_duckdb/Parquet)
Adicionam índices e armazenamento colunar comprimido dentro ou ao lado do banco relacional tradicional.Em 2026, extensões que embutem o motor vetorizado do DuckDB e leitura direta de tabelas Iceberg dentro do PostgreSQL aproximaram o OLTP do OLAP.
Comando para experimentar (Simulador de Serialização Híbrida Merge-on-Read + Compaction)
# Simule o funcionamento de uma tabela híbrida (estilo Apache Hudi / Apache Iceberg Merge-on-Read):
# 1. Leituras combinam o arquivo base colunar (Parquet) com o delta log recente sem reescrever tudo;
# 2. A rotina de Compaction consolida tudo em um novo arquivo Parquet limpo para máxima velocidade:
python3 - <<'PY'
# Arquivo base colunar imutável (Parquet - 100 MB):
base_parquet = {1: {"id": 1, "preco": 50.0}, 2: {"id": 2, "preco": 80.0}, 3: {"id": 3, "preco": 120.0}}

# Delta Log / Delete & Upsert File rápido gravado em segundos:
delta_log = [
    {"op": "UPDATE", "id": 2, "preco": 72.0},
    {"op": "DELETE", "id": 3},
    {"op": "INSERT", "id": 4, "preco": 99.0}
]

def leitura_merge_on_read(base, deltas):
    estado = dict(base)
    for d in deltas:
        if d["op"] == "DELETE":
            estado.pop(d["id"], None)
        else:
            estado[d["id"]] = {"id": d["id"], "preco": d["preco"]}
    return estado

estado_atual = leitura_merge_on_read(base_parquet, delta_log)
print("Resultado instantâneo via Merge-on-Read (Base Colunar + Delta Log):")
print(" ", estado_atual)

# Compaction assíncrona gera o novo snapshot Parquet consolidado:
novo_base_parquet = estado_atual
delta_log_pos_compaction = []
print("Estado após Compaction em background (0 deltas pendentes, leitura 100% colunar pura):", len(novo_base_parquet), "registros ativos.")
PY
Laboratório avançado · Copy-on-Write (CoW) vs. Merge-on-Read (MoR) no Apache Iceberg e Hudi: quando escolher cada um?

No modo Copy-on-Write (CoW), qualquer UPDATE ou DELETE reescreve imediatamente o arquivo Parquet afetado gerando uma versão nova: a escrita fica mais cara e lenta, mas as consultas analíticas de leitura têm zero penalidade porque leem apenas arquivos Parquet puros. Já no modo Merge-on-Read (MoR), as atualizações e deleções são gravadas instantaneamente em pequenos arquivos delta/delete sem reescrever o Parquet grande: ideal para ingestão de CDC de baixa latência (a cada minuto), exigindo apenas agendar jobs regulares de compaction para que o acúmulo de arquivos delta não deixe as leituras lentas.

Entrega da etapa

Defina a estratégia de Serialização Híbrida do seu projeto: escolha em quais tabelas você usará o padrão Copy-on-Write (foco em leitura rápida e atualizações espaçadas) vs. Merge-on-Read (foco em CDC contínuo de baixa latência) no Apache Iceberg / Hudi, e estabeleça a frequência da rotina de compaction.

Conexão com o livro · Apêndice A (Seções A.3: Hybrid Serialization — Apache Hudi e Apache Iceberg; e A.4: Database Storage Engines — separação entre Query Engine e Storage Engine, otimização para SSD e motores colunares).

Oficina 05 / 08

Algoritmos de Compressão: Lossless vs. Lossy, Gzip/Bzip2 vs. Snappy, LZ4 e Zstandard + Simulador

Por que comprimir arquivos Parquet com bzip2 ou gzip pode deixar suas consultas mais lentas por gargalo de CPU, enquanto codecs modernos como Zstandard (Zstd), Snappy e LZ4 aceleram tanto a rede quanto o processador?

Lossless vs. Lossy e a Nova Geração de Codecs de Alta Velocidade (Páginas 535–536)

Na Seção A.5, Reis e Housley explicam que todo algoritmo de compressão procura redundâncias e padrões repetitivos nos bytes para recodificá-los em representações menores, revertendo o processo na leitura. A primeira distinção fundamental é entre duas famílias:

  • Lossless Compression (Compressão Sem Perdas): ao descomprimir os dados, você recupera uma cópia exata bit por bit do original. É 100% obrigatória para tabelas analíticas, bancos de dados, logs, JSON, CSV e Parquet (você não pode aceitar que um algoritmo “aproxime” um valor financeiro ou um ID de cliente!).
  • Lossy Compression (Compressão Com Perdas): projetada para fidelidade sensorial humana em áudio, imagens e vídeo (como JPEG, MP3, AAC, H.264/HEVC), descartando detalhes imperceptíveis ao olho ou ouvido para reduzir drasticamente o tamanho. O engenheiro de dados lida com arquivos lossy ao construir pipelines de mídia ou ingestão multimodal para modelos de visão/áudio em IA, mas nunca na serialização de dados tabulares e metadados.

Dentro da compressão Lossless, o Apêndice A contrasta duas gerações de algoritmos que você configura diariamente no seu Data Lakehouse:

Comparativo dos algoritmos de compressão sem perdas (Seção A.5 + Padrão 2026)
Algoritmo (Codec)Perfil de Taxa vs. Velocidade de CPUOnde aplicar na Engenharia de Dados em 2026
Gzip e Bzip2
(Geração Clássica)
Alta taxa de compressão em texto puro, mas intensivos em CPU e mais lentos para comprimir e descomprimir (bzip2 é especialmente lento).Usados para comprimir arquivos de texto legados (.csv.gz, .jsonl.gz) para transferência ou arquivamento frio externo.
Snappy e LZ4
(Otimizados para Velocidade)
Priorizam velocidade extrema de CPU (centenas de MB/s a GB/s por core) com taxa de compressão moderada.Excelentes para buffers intermediários de shuffle (Spark), tópicos de streaming (Kafka) e leituras rápidas com baixa latência de CPU.
Zstandard (Zstd)
(O Padrão Ouro em 2026)
Criado no Facebook (Yann Collet), entrega taxa de compressão igual ou superior ao Gzip com velocidade de descompressão próxima ao Snappy/LZ4, além de níveis ajustáveis.Codec padrão recomendado em 2026 para arquivos Apache Parquet em tabelas Apache Iceberg / Delta Lake: reduz armazenamento e tráfego de rede no S3/GCS sem penalizar a CPU na leitura!
Comando para experimentar (Benchmark Real de Compressão Lossless no Python: Bruto vs. Zlib/Gzip)
# Execute no terminal um teste real de compressão lossless em lotes de logs JSONL
# medindo a taxa de compressão (Compression Ratio) e a fidelidade bit a bit:
python3 - <<'PY'
import zlib, time

# Simulando 5.000 linhas de log de telemetria com alta redundância estrutural:
payload_jsonl = "\n".join(
    f'{{"ts":"2026-04-12T10:00:{i%60:02d}Z","service":"checkout-api","region":"sa-east-1","status":200,"latency_ms":{15 + (i%10)}}}'
    for i in range(5000)
).encode("utf-8")

t0 = time.perf_counter()
comprimido = zlib.compress(payload_jsonl, level=6)
t_comp = (time.perf_counter() - t0) * 1000

t1 = time.perf_counter()
recuperado = zlib.decompress(comprimido)
t_decomp = (time.perf_counter() - t1) * 1000

assert recuperado == payload_jsonl, "Falha de fidelidade Lossless!"
ratio = len(payload_jsonl) / len(comprimido)

print(f"Tamanho Original (JSONL): {len(payload_jsonl):8,d} bytes")
print(f"Tamanho Comprimido:       {len(comprimido):8,d} bytes (Taxa {ratio:.1f}:1 | Economia de {(1 - len(comprimido)/len(payload_jsonl))*100:.1f}%)")
print(f"Tempo Compressão: {t_comp:.2f} ms | Tempo Descompressão: {t_decomp:.2f} ms | Cópia exata bit-a-bit: {recuperado == payload_jsonl}")
PY

Simulador de Reserialização (CSV → Parquet + Zstd) e Economia de Rede na Nuvem

Simule o impacto mensal na fatura e na performance ao converter pipelines de texto bruto (CSV/JSON) para Parquet comprimido com Zstandard e eliminar tráfego inter-zona/egress desnecessário.

Laboratório avançado · Por que comprimir dados acelera a leitura em rede e Object Storage mesmo gastando ciclos de CPU?

Na página 288 e no Apêndice A, Reis e Housley explicam a matemática física: uma CPU moderna descomprime dados em Zstandard, Snappy ou LZ4 a centenas ou milhares de megabytes por segundo por núcleo, enquanto a busca e transferência pela rede do Object Storage é muito mais limitada. Se uma coluna de 1 GB em disco cai para 120 MB comprimida com Zstd, você transfere 880 MB a menos pela rede — o tempo economizado no cabo de rede supera com folga os poucos milissegundos gastos pela CPU para descomprimir o bloco na RAM!

Entrega da etapa

Defina a matriz de compressão do seu projeto: especifique qual codec será configurado nas tabelas Apache Parquet / Iceberg (ex.: Zstandard), qual codec será usado em mensagens de baixa latência no streaming (ex.: LZ4 / Snappy), como tratará arquivos comprimidos legados na ingestão e registre o saldo do simulador acima.

Conexão com o livro · Apêndice A (Seção A.5: Compression: gzip, bzip2, Snappy, etc.) · remoção de redundância e tokenização, compressão Lossless vs. Lossy e comparação entre Gzip/Bzip2 e Snappy, Zstandard, LZFSE e LZ4.

Oficina 06 / 08

Topologia de Rede na Nuvem: Availability Zones, Regiões, VPCs e Falhas Correlacionadas

Um engenheiro sobe um cluster Spark de 30 nós espalhado entre três Zonas de Disponibilidade diferentes e usa endereços IP públicos para conectar os nós ao banco — dobrando a latência do shuffle e gerando milhares de dólares em taxas de tráfego interno. Como projetar a topologia de rede na nuvem corretamente?

Availability Zones (AZs), VPCs e o Segredo dos IPs Privados (Páginas 537–539)

No Apêndice B (páginas 537–540), Reis e Housley abordam um tema que muitos engenheiros de dados ignoram até levarem um susto na fatura ou na latência: a Topologia de Rede na Nuvem (Cloud Network Topology). AWS, GCP e Azure compartilham uma hierarquia física e lógica muito semelhante, começando pela Availability Zone (Zona de Disponibilidade — AZ) (Figura B-1):

  • O que é uma Availability Zone (AZ): é a menor unidade de topologia de rede que as nuvens públicas tornam visível ao cliente (composta por um ou mais datacenters com energia elétrica, água e conectividade independentes para que um apagão local não derrube outras zonas).
  • Onde alocar clusters de processamento pesado: as nuvens oferecem sua maior largura de banda e menor latência dentro de uma única Availability Zone. Por isso, Reis e Housley cravam a recomendação prática (página 538): cargas de trabalho intensivas em transferência de dados (como um cluster efêmero Amazon EMR / Spark ou Dask/Ray) devem rodar inteiramente dentro de uma única Availability Zone para maximizar a velocidade do shuffle e zerar taxas de tráfego entre zonas!
  • A Regra Crucial dos IPs Privados na VPC (página 538): o tráfego de rede enviado entre máquinas virtuais dentro da mesma Availability Zone é gratuito, mas com uma condição crítica: o tráfego precisa ser enviado para os endereços IP privados dentro da VPC (Virtual Private Cloud)! Se duas máquinas na mesma zona conversarem usando seus endereços IP públicos/externos, a nuvem cobrará taxas de saída de dados (Data Egress) como se os pacotes tivessem saído para a internet!

Regiões, Object Storage Regional, Multirregião (GCP) e Falhas Correlacionadas

Acima das zonas de disponibilidade estão as Regiões (Regions) e, no caso específico do Google Cloud, as Multirregiões (Multiregions):

Hierarquia de topologia de rede na nuvem e implicações para dados (Apêndice B)
Nível da TopologiaLatência, Banda e Custo de TráfegoBoas Práticas de Arquitetura e Resiliência
1. Mesma Availability Zone (Intra-AZ via IP Privado VPC)Latência mínima (<1 ms), banda máxima e tráfego gratuito entre VMs usando IPs privados.Aloque todos os nós de um job/cluster efêmero de processamento pesado na mesma AZ.
2. Entre AZs da Mesma Região (Cross-AZ)Baixa latência, porém um pouco maior que intra-AZ e cobra taxa nominal de transferência entre VMs de zonas diferentes.Use múltiplas AZs para bancos transacionais de alta disponibilidade (Multi-AZ) e failover automático contra queda de um datacenter.
3. Object Storage Regional (S3 / GCS Regional)Replicado automaticamente entre múltiplas zonas da região; VMs na mesma região leem/escrevem sem tarifa de tráfego entre zonas (paga-se apenas armazenamento e chamadas de API).Mantenha sempre os motores de computação (Spark, Trino, DuckDB workers) na mesma região do bucket Object Storage do Lakehouse.
4. Entre Regiões Diferentes (Cross-Region) e Multirregiões (GCP)Maior latência física (distância + saltos de roteadores / hops) e taxas mais altas de egress inter-regional (exceto em recursos multirregionais específicos do GCP na mesma multirregião US/EU/ASIA).Cuidado com Falhas Correlacionadas (Correlated Failures — p. 539): quedas de regiões inteiras geralmente ocorrem quando código ou configuração defeituosa é implantado simultaneamente em toda a região!
Comando para experimentar (Auditor de Topologia Cloud: Intra-AZ vs. Cross-AZ vs. IP Público)
# Calcule o desperdício financeiro mensal quando um cluster de processamento faz shuffle
# entre zonas diferentes (Cross-AZ) ou usa IPs públicos em vez de IPs privados na mesma AZ:
python3 - <<'PY'
tb_shuffle_mes = 150 # 150 TB trafegados entre nós durante joins e agregações no mês

cenarios = [
    {"arquitetura": "Cluster na mesma AZ + IP Privado VPC (Recomendado)", "tarifa_gb_usd": 0.00},
    {"arquitetura": "Cluster espalhado em 3 AZs (Tráfego Cross-AZ)",      "tarifa_gb_usd": 0.02},
    {"arquitetura": "Comunicação acidental via IP Público / NAT Gateway", "tarifa_gb_usd": 0.09}
]

for c in cenarios:
    custo_mensal = tb_shuffle_mes * 1024 * c["tarifa_gb_usd"]
    print(f"{c['arquitetura']:52} -> US$ {custo_mensal:8,.2f}/mês (US$ {custo_mensal*12:9,.2f}/ano)")
PY
Laboratório avançado · Como equilibrar Alta Disponibilidade (Multi-AZ) com Economia de Rede (Single-AZ) no mesmo pipeline?

A regra prática une os dois conceitos: para serviços permanentes e críticos de estado (como o banco OLTP de produção, o cluster Kafka de ingestão ou o banco de metadados do orquestrador), use arquitetura Multi-AZ para sobreviver à queda de um datacenter sem interromper o negócio. Já para os workers efêmeros de processamento em lote (como um job Spark ou worker DuckDB/Polars que lê do S3 regional, faz um join pesado e grava o resultado de volta no S3 regional), suba todo o cluster efêmero dentro de uma única AZ com IPs privados: você obtém velocidade máxima e custo zero de rede no shuffle, e se aquela AZ falhar naquele instante, o orquestrador simplesmente sobe o job efêmero na AZ vizinha!

Entrega da etapa

Desenhe a topologia de rede na nuvem do seu projeto: especifique em qual Região ficará o Object Storage do seu Lakehouse, quais serviços permanentes rodarão em Multi-AZ, como seus clusters efêmeros de processamento serão alocados em Single-AZ com IPs privados na VPC e como você evitará deploys globais que causem falhas correlacionadas.

Conexão com o livro · Apêndice B (Seções B.1 a B.4) · Cloud Network Topology, Availability Zones (AZs), VPCs e IPs privados vs. públicos, Regions, Object Storage regional, falhas correlacionadas e Multiregions / Premium Tier Networking no GCP.

Oficina 07 / 08

Egress Fees, Direct Connect, CDNs e VPC Endpoints / PrivateLink em 2026

Por que o Zoom escolheu a Oracle Cloud em vez da AWS no auge de 2020 economizando cerca de US$ 9 milhões por mês apenas em taxas de saída de dados — e como blindar sua arquitetura contra pedágios de rede?

O Fosso Econômico das Taxas de Saída (Data Egress) e o Caso Zoom (Páginas 537 e 540–541)

No Apêndice B, Reis e Housley explicam a mecânica econômica das redes em nuvem: o tráfego que entra na nuvem (inbound / ingress) é gratuito, mas o tráfego que sai para a internet ou para outro provedor (outbound / egress) é pesadamente tarifado. O tráfego de saída não custa mais caro fisicamente para o provedor; ele funciona como um fosso estratégico (moat) para criar gravidade artificial de dados e dificultar que clientes saiam daquela nuvem ou adotem arquiteturas multicloud ingênuas.

Na página 541, os autores citam o caso emblemático do Zoom em 2020 (analisado pelo especialista em AWS Corey Quinn): quando o tráfego de vídeo do Zoom explodiu no início da pandemia, a conta mensal de Data Egress pelo preço de tabela na AWS ultrapassaria US$ 11 milhões por mês, enquanto na Oracle Cloud ficaria abaixo de US$ 2 milhões por mês — um diferencial decisivo de infraestrutura de rede que definiu um contrato bilionário! Para domar a conectividade e cortar custos de transferência na prática, o Apêndice B (e a evolução de 2026) destaca três ferramentas essenciais:

Soluções de conectividade e redução de custos de rede na nuvem (Apêndice B + 2026)
Solução de RedeComo funciona tecnicamenteImpacto direto em Latência, Segurança e FinOps
1. Conexões Diretas Dedicadas
(AWS Direct Connect, Azure ExpressRoute, GCP Cloud Interconnect)
Conecta a rede física/datacenter da sua empresa diretamente a uma região ou VPC da nuvem sem passar pela internet pública.Entrega maior largura de banda, menor latência e descontos drásticos no Egress (no exemplo do livro na página 540, caindo de US$ 0,09/GB na internet pública para US$ 0,02/GB via Direct Connect).
2. CDNs
(Content Delivery Networks — Cloudflare, CloudFront, Cloud CDN)
Servidores de borda distribuídos globalmente que fazem cache de arquivos e ativos de dados próximos ao usuário final.Reduz drasticamente a latência e o custo de Egress do Object Storage quando os mesmos arquivos, pacotes de dados ou embeddings públicos são baixados repetidamente (atenção às regras regionais e letras miúdas).
3. VPC Endpoints & PrivateLink
(Prática Indispensável 2026)
Cria uma rota privada direta entre sua VPC e o Object Storage (S3/GCS), bancos SaaS (Snowflake/Databricks) e provedores de modelos de IA/RAG.Evita que os terabytes lidos do S3 passem por um NAT Gateway (que cobra pedágio por GB processado!) e impede que dados e prompts trafeguem pela internet pública.
Comando para experimentar (Calculadora de Economia: Internet Pública vs. Direct Connect e VPC Endpoint)
# Calcule a economia anual ao substituir transferência pela internet pública (US$ 0.09/GB)
# por Direct Connect (US$ 0.02/GB) e ao usar VPC Gateway Endpoint gratuito para acesso ao S3:
python3 - <<'PY'
tb_hibrido_mes = 60  # 60 TB/mês transferidos da nuvem para o ambiente híbrido da empresa
tb_s3_interno_mes = 200 # 200 TB/mês lidos do S3 pelos workers na mesma região

# 1. Comparação Internet Pública vs. Direct Connect (dados saindo para o datacenter):
custo_publico_anual = tb_hibrido_mes * 1024 * 0.09 * 12
custo_direct_anual  = tb_hibrido_mes * 1024 * 0.02 * 12

# 2. Comparação NAT Gateway mal configurado (US$ 0.045/GB) vs. S3 VPC Gateway Endpoint (US$ 0.00/GB):
custo_nat_errado_anual = tb_s3_interno_mes * 1024 * 0.045 * 12
custo_vpc_endpoint_anual = 0.0

print(f"Híbrido via Internet Pública (US$ 0.09/GB): US$ {custo_publico_anual:10,.2f}/ano")
print(f"Híbrido via Direct Connect   (US$ 0.02/GB): US$ {custo_direct_anual:10,.2f}/ano (Economia: US$ {custo_publico_anual - custo_direct_anual:,.2f}/ano)")
print(f"Leitura S3 passando por NAT Gateway (Erro): US$ {custo_nat_errado_anual:10,.2f}/ano")
print(f"Leitura S3 via VPC Gateway Endpoint:        US$ {custo_vpc_endpoint_anual:10,.2f}/ano (Economia: US$ {custo_nat_errado_anual:,.2f}/ano)")
PY
Laboratório avançado · Por que o erro do NAT Gateway é uma das armadilhas financeiras mais comuns em pipelines de dados na AWS/GCP?

Quando você coloca seus workers de engenharia de dados (Airflow, Dagster, Spark, Kubernetes) em uma sub-rede privada (sem IP público, como manda a boa segurança) e eles precisam ler 100 TB de arquivos Parquet no Amazon S3 ou Google Cloud Storage, se o administrador de rede não tiver criado um VPC Gateway Endpoint para o S3 / Private Google Access na tabela de rotas da sub-rede, todo o tráfego para o S3 sairá pelo NAT Gateway da VPC — que cobra cerca de US$ 0,045 por cada gigabyte atravessado, mesmo com o bucket estando na mesma região! Configurar o VPC Gateway Endpoint leva dois minutos via Terraform e reduz esse custo a zero.

Entrega da etapa

Audite as rotas de saída e conectividade do seu projeto: identifique qualquer fluxo que hoje pague Data Egress ou atravesse um NAT Gateway desnecessariamente, especifique onde você configurará VPC Endpoints / PrivateLink (para Object Storage, Warehouse e APIs de IA/RAG) e avalie se há casos para Direct Connect ou CDN.

Conexão com o livro · Apêndice B (Seções B.2 e B.5 a B.7) · Data Egress Charges, Direct Network Connections (AWS Direct Connect), CDNs e The Future of Data Egress Fees (caso Zoom/Oracle analisado por Corey Quinn) + Atualização 2026 (VPC Endpoints e PrivateLink).

Oficina 08 / 08

Infraestrutura de Execução em 2026: Contêineres, Kubernetes, Limites de RAM e Spill-to-Disk

Seu worker containerizado rodando no Kubernetes é encerrado abruptamente com código OOMKilled (Exit Code 137) no meio de uma agregação de 40 GB. Como configurar contêineres, memória, discos NVMe efêmeros e fechar a arquitetura completa dos 4 módulos?

Integrando Serialização, Memória e Rede dentro de Contêineres e Kubernetes

Ao longo dos quatro módulos, vimos como desacoplar ambientes de execução usando Contêineres (Docker) e Kubernetes desmonta o antipadrão do Monólito Distribuído (Capítulo 4) e sustenta os workers efêmeros do Cloud-Scale Data OS (Capítulo 11). Agora, unindo os Apêndices A e B à prática de produção de 2026, quatro ajustes de infraestrutura física garantem que seus contêineres de dados rodem com máxima velocidade e estabilidade:

  1. Reserva Explícita de Memória e Prevenção de `OOMKilled` (Exit 137): motores analíticos em processo como DuckDB, Polars e workers PyArrow/Spark usam memória de forma agressiva para buffers colunares e hash tables. Em um Pod Kubernetes (por exemplo, com limite resources.limits.memory: 16Gi), se você não configurar o limite interno do motor de dados para ~75% a 80% da RAM do contêiner (ex.: SET memory_limit = '12GB' no DuckDB), um pico momentâneo de alocação fará o kernel do Linux matar o contêiner com OOMKilled!
  2. Spill-to-Disk em Volumes NVMe Locais Efêmeros (Capítulo 6 + Apêndice A): o que acontece quando uma ordenação ou JOIN em um worker com 12 GB de RAM precisa processar 50 GB de dados? O motor faz Spill-to-Disk (despeja blocos temporários comprimidos no disco e os lê de volta). Se o diretório temporário (temp_directory) apontar para um volume de rede lento, o job congela; aponte sempre o diretório de spill para um disco SSD/NVMe local efêmero montado no nó!
  3. Paralelismo Alinhado aos Cores Reais da CPU (`threads`): dentro de um contêiner com limite de 4 vCPUs rodando em uma máquina hospedeira de 64 cores, ferramentas antigas às vezes detectavam os 64 cores do host e criavam 64 threads disputando apenas 4 vCPUs (causando CPU throttling severo). Configure explicitamente o número de threads alinhado à cota real de CPU do contêiner.
  4. Imagens Imutáveis Enxutas e Rede Intra-AZ Privada: construa imagens multi-stage enxutas (sem compiladores ou pacotes desnecessários que ampliem a superfície de ataque vista no Capítulo 10), injete segredos apenas em tempo de execução via Secrets Manager e agende pods que trocam alto volume de dados na mesma Availability Zone usando IPs privados e VPC Endpoints.
Checklist de configuração física de um Worker Containerizado de Dados em 2026
Parâmetro de InfraestruturaConfiguração Ingênua (Causa Falhas)Configuração de Produção (Módulo 4)
Memória RAM do Motor vs. PodDeixar o motor usar 100% da memória do host até sofrer OOMKilled (137) pelo Kubernetes.Limitar o motor a 75%–80% do limite do Pod (ex.: 12 GB em um Pod de 16 GB) e habilitar out-of-core spill.
Diretório de Spill TemporárioUsar o overlay filesystem padrão do contêiner ou disco de rede lento.Montar volume emptyDir / NVMe local efêmero dedicado para spill e shuffle comprimido com LZ4/Zstd.
Formato em Memória e DiscoLer CSVs em Pandas tradicional convertendo objetos linha a linha.Ler e escrever Parquet + Zstd sobre Apache Iceberg processando em buffers Apache Arrow (DuckDB/Polars).
Topologia de Rede e S3/GCSPods espalhados em múltiplas AZs saindo para o S3 via NAT Gateway pago.Afinidade de zona (Single-AZ para o job) + VPC Gateway Endpoint gratuito direto para o Object Storage.
Comando para experimentar (Gerador Automático de Perfil de Worker Containerizado DuckDB/Arrow)
# Calcule automaticamente os parâmetros seguros de memória, threads e spill-to-disk
# para um worker containerizado (Kubernetes / ECS / Cloud Run) a partir dos limites do Pod:
python3 - <<'PY'
import json

pod_limits = {"vcpu_cores": 4, "memory_gib": 16, "ephemeral_nvme_mount": "/mnt/nvme_scratch"}

config_worker_2026 = {
    "k8s_pod_limits": pod_limits,
    "duckdb_engine_settings": {
        "threads": pod_limits["vcpu_cores"],
        "memory_limit": f"{int(pod_limits['memory_gib'] * 0.78)}GB", # 78% do limite do Pod contra OOMKilled
        "temp_directory": f"{pod_limits['ephemeral_nvme_mount']}/duckdb_spill.tmp",
        "parquet_compression": "ZSTD"
    },
    "network_guardrails": {
        "zone_affinity": "single-az-batch-execution",
        "s3_routing": "vpc-gateway-endpoint-private-ip"
    }
}
print(json.dumps(config_worker_2026, indent=2, ensure_ascii=False))
PY
Laboratório avançado · Como todos os 4 Módulos se conectam em uma única arquitetura coesa?

Repare como todas as peças de Fundamentals of Data Engineering se encaixam perfeitamente: no Módulo 1 (Capítulos 1–4), você diagnosticou a maturidade da empresa, desenhou decisões reversíveis (Two-Way Doors) e estruturou as 6 Undercurrents; no Módulo 2 (Capítulos 5–9), você implementou contratos na origem, micro-particionamento no armazenamento, ingestão CDC/DLQ, modelagem (Kimball SCD / Data Vault / OBT), transformações idempotentes (MERGE) e Serving governado com Camada Semântica, RAG e Reverse ETL; no Módulo 3 (Capítulos 10–11), você blindou pessoas, processos e tecnologia com Menor Privilégio, Break-Glass e conformidade LGPD, preparando a transição para o Cloud-Scale Data OS e o Live Data Stack; e agora, no Módulo 4 (Apêndices A–B), você dominou a física dos formatos colunares (Parquet/Iceberg), da memória zero-copy (Apache Arrow), da compressão (Zstd) e da topologia de rede na nuvem!

Entrega da etapa

Defina a especificação final de infraestrutura de execução dos seus pipelines: estabeleça os limites de CPU, RAM (prevenção de OOMKilled) e diretório de Spill NVMe dos seus contêineres, combinados com a configuração de serialização (Parquet + Zstd + Arrow) e rede (Single-AZ + VPC Endpoint).

Conexão com o livro · Síntese prática dos Apêndices A e B com a execução moderna em contêineres (Capítulos 4, 6 e 11) · gerenciamento de memória Arrow/DuckDB/Polars, spill-to-disk em volumes locais NVMe e isolamento em Kubernetes.

Oficina síntese final · Módulo 4 de 4

Projeto prático e caderno do Módulo 4 (Conclusão da Trilha)

Consolide sua especificação técnica de Serialização, Compressão, Redes na Nuvem e Execução Containerizada (Apêndices A e B + práticas de 2026), valide suas decisões finais e exporte seu caderno completo.

Suas anotações nas 8 oficinas

Especificação de Infraestrutura de Dados (Apêndices A e B + Stack 2026)

Feche o documento de engenharia do seu projeto em quatro blocos:

Decisões de Infraestrutura na prática (Autoavaliação Final)

Teste seu domínio técnico sobre os Apêndices A e B em quatro cenários reais:

1. Um pipeline analítico lê diariamente 500 GB de arquivos CSV brutos para somar apenas 3 de 60 colunas, gastando horas de processamento e alto custo de leitura. Segundo o Apêndice A, por que o CSV causa esse gargalo e qual mudança entrega ganhos de até 100x?
2. Qual problema fundamental o projeto Apache Arrow resolveu na engenharia de dados (Apêndice A.2.3) e como ele sustenta ferramentas modernas como DuckDB e Polars em 2026?
3. Você vai executar um cluster efêmero de processamento distribuído (Spark / EMR / Ray) que fará shuffle intenso de terabytes de dados lidos de um bucket Object Storage na mesma região. Segundo o Apêndice B, como você deve alocar os nós e configurar a comunicação de rede?
4. Sua empresa mantém uma infraestrutura híbrida que transfere grandes volumes constantes de dados entre o datacenter local e a nuvem, e também distribui conjuntos de dados estáticos repetidamente para milhares de clientes externos. Quais recursos do Apêndice B reduzem os custos de Data Egress nesses dois casos?

Checklist de domínio do Módulo 4 e da Formação Completa

Marque os critérios que você consolidou ao concluir os 4 módulos de Engenharia de Dados:

Formação Concluída · Módulos 1, 2, 3 e 4

Parabéns! Você completou os 4 módulos de Engenharia de Dados com Critério.

Você percorreu toda a obra Fundamentals of Data Engineering (Capítulos 1 a 11 + Apêndices A e B) atualizada para o cenário prático de 2026. Revise qualquer módulo da trilha ou retorne ao catálogo principal de cursos.

Referências bibliográficas e fontes técnicas (Apêndices A e B + Ecossistema 2026)

REIS, Joe; HOUSLEY, Matt. Fundamentals of Data Engineering: Plan and Build Robust Data Systems. Sebastopol, CA: O'Reilly Media, 2022. ISBN 978-1-098-10830-4 (Appendix A: Serialization and Compression Technical Details; Appendix B: Cloud Networking). Artigos e especificações citados nos apêndices: SIMIC, Dejan (Apache Arrow: Read DataFrame with Zero Memory, 2020); PRINCE, Matthew; RAO, Nitin (AWS’s Egregious Egress, Cloudflare Blog, 2021); QUINN, Corey (Why Zoom Chose Oracle Cloud Over AWS and Maybe You Should Too, Last Week in AWS, 2020); especificações oficiais do Apache Parquet, Apache Arrow, Apache Avro, Apache Iceberg, Apache Hudi e Zstandard (RFC 8878).