Melhores Práticas para DAGs em Produção
Guia de boas práticas para criar DAGs robustos, escaláveis e fáceis de manter.
Índice
- 1. Idempotência
- 2. Atomicidade
- 3. Use Variáveis de Ambiente para Secrets
- 4. Configurar Timeouts Adequados
- 5. Sensores: Escolha o Modo Correto
- Checklist de Produção
1. Idempotência
Toda tarefa deve ser idempotente — executá-la múltiplas vezes deve produzir o mesmo resultado que executá-la uma vez.
DAGs idempotentes permitem backfill e reruns seguros sem corromper dados.
1
2
3
4
5
6
7
8
9
10
# ❌ Não idempotente
def inserir_dados(**context):
db.execute("INSERT INTO tabela VALUES (%s)", context["ds"])
# ✅ Idempotente
def inserir_dados(**context):
db.execute("""
INSERT INTO tabela VALUES (%s)
ON CONFLICT (data) DO UPDATE SET updated_at = NOW()
""", context["ds"])
2. Atomicidade
Cada task deve fazer uma coisa bem definida. Evite tasks que fazem extração + transformação + carga ao mesmo tempo.
1
2
✅ Estrutura recomendada:
extrair_dados >> transformar_dados >> carregar_dados >> validar_dados
3. Use Variáveis de Ambiente para Secrets
Nunca coloque credenciais hardcoded em DAGs. Use Connections ou Variables do Airflow, ou integração com Vault/Secret Manager.
1
2
3
4
5
6
7
from airflow.models import Variable
# ✅ Correto
api_key = Variable.get("minha_api_key", deserialize_json=False)
# ❌ Errado
api_key = "sk-1234abcd..."
4. Configurar Timeouts Adequados
Sempre defina execution_timeout nas tasks e dagrun_timeout no DAG.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from datetime import timedelta
default_args = {
"execution_timeout": timedelta(hours=2),
"retries": 2,
"retry_delay": timedelta(minutes=10),
"retry_exponential_backoff": True,
}
with DAG(
dag_id="meu_dag",
default_args=default_args,
dagrun_timeout=timedelta(hours=6),
...
) as dag:
...
5. Sensores: Escolha o Modo Correto
| Situação | Modo |
|---|---|
| Espera curta (< 5 min) | poke |
| Espera longa (> 30 min) | reschedule |
| Muitos sensores simultâneos | reschedule |
Veja o guia completo: Sensores — Poke vs Reschedule
Checklist de Produção
- DAGs são idempotentes
- Tasks têm
execution_timeoutdefinido - Sensores usam o modo correto
- Credentials estão em Connections/Variables
- Há alertas configurados (
on_failure_callback) - DAGs têm
catchup=False(se não necessário) - Dependências entre DAGs usam
ExternalTaskSensorouTriggerDagRunOperator