Como compactar pequenos ficheiros em Lakehouse: passo a passo
Este tutorial mostra como compactar pequenos ficheiros (small files) em Lakehouse para reduzir overhead de metadata e melhorar o desempenho de leitura. Compactar ficheiros é útil em cenários de ingestão contínua ou quando pequenos ficheiros Delta degradam consultas e aumentam custos.
Pré-requisitos
- Conta com acesso a Microsoft Fabric e permissões para o Lakehouse.
- Workspace com um Lakehouse que contenha tabelas Delta com muitos ficheiros pequenos.
- Ambiente para executar PySpark (notebook no Fabric ou Synapse/Purview compatível).
- Conhecimentos básicos de Delta Lake e Spark SQL.
Passo 1: Identificar tabelas com muitos ficheiros pequenos
É importante saber quais tabelas têm muitos ficheiros pequenos. Uma forma prática é consultar o sistema de metadados Delta para ver o número de ficheiros e o tamanho total.
-- Exemplo SQL no SQL endpoint ou notebook
DESCRIBE DETAIL delta.`/lakehouse///`;
Procure um tamanho total baixo por ficheiro (averageFileSize) ou um número elevado de ficheiros (numFiles). Se averageFileSize for muito pequeno (por ex. < 10 MB), há ganho em compactar.
Passo 2: Planeamento da compactação (repartição/partitioning)
Decida o tamanho alvo por ficheiro e se vai usar repartição por coluna. Objectivo comum: ficheiros entre 50 MB e 256 MB. Para tabelas particionadas, compacte por partição para evitar shuffles desnecessários.
Passo 3: Compactar usando repartition/coalesce com PySpark
Este método lê a tabela Delta e regrava-a com menos ficheiros usando repartition ou coalesce. Repartition cria shuffle (mais preciso), coalesce reduz partições sem shuffle (rápido quando já existe boa distribuição).
from pyspark.sql import SparkSession
spark = SparkSession.builder.getOrCreate()
# Ler Delta table
df = spark.read.format("delta").load("/lakehouse///")
# Exemplo: target ~100 MB por ficheiro -> ajustar número de partições
# Calcula número de partições simples (opcional)
# num_partitions = max(1, int(total_size_bytes / (100 * 1024 * 1024)))
# Reparticionar e sobrescrever a mesma tabela (atenção à concorrência)
df.repartition(10).write.format("delta").mode("overwrite").option("dataChange", "false").save("/lakehouse///")
Nota: usar option("dataChange","false") quando apenas se reorganizam ficheiros sem alterar dados para manter histórico mínimo. Teste sempre em ambiente não produtivo.
Passo 4: Compactar por partição (quando aplicável)
Se a tabela for particionada por uma coluna (ex.: dt), compacte cada partição independentemente para evitar custosos shuffles.
# Exemplo PySpark por partição
from pyspark.sql.functions import col
partitions = [row['partition'] for row in spark.sql("SHOW PARTITIONS delta.`/lakehouse/<...>/`").collect()]
for p in partitions:
part_path = f"/lakehouse////dt={p}"
df_part = spark.read.format("delta").load(part_path)
df_part.coalesce(1).write.format("delta").mode("overwrite").option("dataChange","false").save(part_path)
Escolha coalesce(1) apenas para partições pequenas; caso contrário escolha um número adequado.
Passo 5: Compactação usando OPTIMIZE (se disponível)
Em ambientes com suporte a comandos Delta OPTIMIZE (por ex. Databricks ou Fabric com SQL endpoints), usar OPTIMIZE é a forma mais simples e integrada.
-- Exemplo SQL
OPTIMIZE delta.`/lakehouse///`
ZORDER BY (coluna_importante);
OPTIMIZE compacta ficheiros e, com ZORDER, melhora a colocação de dados para consultas por coluna. Nem todos os ambientes suportam ZORDER.
Passo 6: Agendar e automatizar a compactação
Depois do processo manual, automatize a tarefa com um job agendado (notebook job ou pipeline). Execute a compactação fora de horários de pico e inclua pontos de controlo e alertas.
# Exemplo de pseudocódigo para agendamento
# 1. Verificar tabelas com small files
# 2. Para cada tabela com averageFileSize < threshold -> executar compactação
# 3. Registar resultado e métricas
Verificar o resultado
Confirme a redução do número de ficheiros e o aumento do tamanho médio por ficheiro usando DESCRIBE DETAIL ou LIST no sistema de ficheiros. Execute queries de leitura e compare tempos antes/depois e custos de leitura.
DESCRIBE DETAIL delta.`/lakehouse///`;
-- Ou listar ficheiros
ls /lakehouse////
Conclusão
Compactar pequenos ficheiros em Lakehouse melhora o desempenho e reduz custos de I/O. Próximos passos: automatizar com jobs, testar OPTIMIZE e monitorizar queries. Dica: comece por uma cópia de teste da tabela antes de reescrever a produção — qual partição ou tamanho alvo fará maior diferença no seu cenário?