Como automatizar a limpeza de ficheiros no Data Lake com Azure Synapse Analytics
Automatizar a remoção de ficheiros obsoletos no Data Lake ajuda a controlar custos, melhorar o desempenho de operações de ingestão e indexação, e manter a organização. Neste tutorial explico porque seguir um padrão com Azure Synapse Analytics (Synapse Pipelines) a orquestrar e uma Azure Function a executar a lógica de limpeza é uma abordagem prática e escalável. Darei exemplos concretos, parâmetros típicos e boas práticas para evitar apagar dados por engano.
Pré-requisitos
- Conta Azure com permissões para criar recursos (Synapse workspace, Storage, Function).
- Azure Synapse Analytics workspace com Synapse Pipelines habilitado.
- ADLS Gen2 (Storage account) com um container de dados e alguns prefixos (por exemplo logs/ ou staging/).
- Azure Function App (Consumption ou Premium) com identity ou chave para apagar ficheiros.
- Familiaridade básica com JSON e PowerShell/Python para testar localmente.
Passo 1: Conceito e porquê da arquitectura
Em vez de realizar operações massivas directamente em Synapse (que pode aumentar custos e complexidade), o padrão separa orquestração de execução: Synapse Pipelines atua como scheduler e orquestrador; a Azure Function contém a lógica de listagem e eliminação no ADLS Gen2. Vantagens: escalabilidade (a Function pode escalar com a carga), logging e telemetria centralizados, reutilização da Function por outros pipelines e menor superfície de risco na remoção de ficheiros.
Exemplo concreto: numa empresa que acumula 100k ficheiros pequenos por mês, apagar ficheiros com mais de 90 dias pode reduzir uma sobrecarga de leitura/listagem e custos operacionais. Adicionalmente, um pipeline diário que verifique um prefixo com 10k ficheiros costuma completar em menos de 5 minutos com a Function, dependendo do tamanho e da latência da conta de armazenamento.
Passo 2: Criar a Azure Function para apagar ficheiros antigos
A Function recebe parâmetros (container, prefix, idade em dias, modo_preview) e apaga ficheiros com lastModified anterior à data limite. Aqui está um exemplo robusto em Python (usa azure-storage-blob), que inclui logging, um modo preview para não apagar nada durante testes e retorno com contagem limitada para evitar payloads muito grandes.
import os
import logging
from datetime import datetime, timezone, timedelta
from azure.storage.blob import ContainerClient
conn_str = os.environ.get('AZURE_STORAGE_CONNECTION_STRING')
def main(req):
data = req.get_json()
container = data.get('container')
prefix = data.get('prefix','')
days = int(data.get('days',30))
preview = bool(data.get('preview',True))
client = ContainerClient.from_connection_string(conn_str, container)
cutoff = datetime.now(timezone.utc) - timedelta(days=days)
deleted = []
for blob in client.list_blobs(name_starts_with=prefix):
try:
if blob.last_modified and blob.last_modified < cutoff:
logging.info(f"Candidate: {blob.name} last_modified={blob.last_modified}")
if not preview:
client.get_blob_client(blob).delete_blob()
deleted.append(blob.name)
else:
# preview mode: apenas registar
deleted.append(f"PREVIEW:{blob.name}")
except Exception as e:
logging.error(f"Erro a processar {blob.name}: {e}")
return {
'status': 200,
'deleted_count': len([d for d in deleted if not str(d).startswith('PREVIEW')]),
'preview': preview,
'sample': deleted[:50]
}
Passo 3: Habilitar autenticação e acesso ao ADLS Gen2
Tem duas opções principais: usar AZURE_STORAGE_CONNECTION_STRING nos Application Settings da Function (rápido para dev) ou atribuir uma Managed Identity e usar RBAC (recomendado para produção). Para ambientes críticos, crie uma Managed Identity para a Function e atribua a role "Storage Blob Data Contributor" ao nível do container ou da conta de storage. Isto evita expor chaves e facilita a rotação de credenciais.
Exemplo: numa política de segurança, conceda a role apenas ao container de destino; em alternativa, use políticas mais restritas como Azure AD + ACLs POSIX se precisar de controlo por ficheiro.
Passo 4: Criar um Synapse Pipeline que chama a Function
No Synapse Studio crie um Pipeline com um Web Activity que faz POST à URL da Function. Passe os parâmetros JSON (container, prefix, days, preview). Isto permite agendar, monitorizar execuções e integrar condições antes e depois da limpeza.
{
"method": "POST",
"url": "https://.azurewebsites.net/api/",
"headers": {
"Content-Type": "application/json"
},
"body": {
"container": "dados",
"prefix": "logs/",
"days": 90,
"preview": true
}
}
Passo 5: Adicionar lógica de retry e notificação
Configure no Web Activity propriedades de retry (ex.: 3 tentativas com 30 s entre cada) e timeout (por exemplo 5 m). Use uma Activity "If Condition" para avaliar o campo deleted_count no output e, em caso de valores superiores a um limiar (ex.: >1000), encaminhe para uma Logic App que notifique a equipa via e-mail ou Teams. Em erros, registe a execução e envie alertas automáticos.
Passo 6: Agendar e testar o Pipeline
Use um Trigger de schedule no Synapse Pipeline (ex.: diário às 02:00). Execute testes com preview=true e days=1 num prefixo de desenvolvimento para confirmar o comportamento. Depois, faça um teste controlado com preview=false num prefixo de staging e limite de dias (por exemplo 180) antes de aplicar em produção. Verifique sempre os logs da Azure Function e os detalhes do run no Synapse para confirmar deleted_count e sample.
Verificar o resultado
Confirme no Storage Explorer ou no portal da Storage account que os ficheiros com lastModified anteriores ao cutoff foram removidos. No Synapse Pipeline verifique os run details do Web Activity: deve devolver deleted_count, flag preview e uma lista de amostra. Consulte também o Application Insights (se configurado) para métricas de latência e erros.
Conclusão
Este padrão com Synapse Pipelines a orquestrar uma Azure Function é simples, reutilizável e permite automatizar a limpeza do Data Lake com segurança. Em produção, recomenda-se usar Managed Identity, instrumentar com Application Insights, e começar com modo preview e limites progressivos. Dica final: mantenha sempre um prefixo de dev e um processo de validação antes de aplicar regras a dados críticos para não correr o risco de perda acidental.