Introdução
Agendamento
Na aula 03 discutimos sobre processos de ETL / ELT.
No exemplo da aula, implementamos uma pipeline de dados que extrai informações de um banco de dados PostgreSQL, transforma esses dados e os carrega em um data warehouse Clickhouse.
Exercício
Answer
A cada dois minutos.
Um tempo baixo para que conseguíssemos simular uma rotina diária sem esperar tanto.
Exercício
Answer
De forma rudimentar, esperando 120
segundos em um loop infinito.
# Recorte de parte do docker-compose.yml
command: >
bash -c "
pip install -r /app/requirements.txt &&
echo 'Inicializando banco de dados warehouse...' &&
python src/init_database.py &&
echo 'Iniciando ETL (executará a cada 2 minutos)...' &&
while true; do
echo 'Executando ETL...' &&
python src/etl_vendas.py &&
echo 'ETL concluído. Aguardando 2 minutos...' &&
sleep 120
done
"
Exercício
Answer
A query de SQL utilizada para extrair os dados extraía informações desde o segundo zero do minuto atual. Entretanto, caso o processo de ETL demorasse mais que um minuto, parte dos dados não seriam ingeridos/tratados.
Ainda, o máximo que obtínhamos de controle era o tempo de espera. Não havia como, por exemplo, executar o processo de ETL às 3 da manhã todos os dias.
Simulando a atividade
Vamos simular a execução de um processo que precisa ser agendado. Para isto, vamos partir dos seguintes arquivos:
Exercise
Agora considere os arquivos:
app.py
Dockerfile
Exercise
Exercise
Answer
Assim que possível!
Após a execução, o processo encerra. Então, instantaneamente o container é reiniciado e ocorre novo print
.
Exercise
Anteriormente, já discutimos por que o time.sleep
não é uma boa solução. Vamos buscar uma alternativa melhor!
Cron
O cron é um agendador de tarefas do Unix que permite executar scripts ou comandos em intervalos regulares.
Ele opera em segundo plano como um daemon, verificando a cada minuto um arquivo de configuração chamado crontab
(cron table) para saber quais tarefas devem ser executadas.
Daemon
Um daemon é um tipo especial de programa que roda em segundo plano em sistemas Unix e semelhantes.
Ele geralmente inicia junto com o sistema e fica aguardando por eventos ou condições específicas para executar suas tarefas (Ex: sshd
).
As tarefas são definidas usando uma sintaxe de cinco campos para especificar o minuto, a hora, o dia do mês, o mês e o dia da semana em que o comando deve rodar:
* * * * *
| | | | |
| | | | ----- Dia da semana (0 - 7, onde 0 ou 7 é Domingo)
| | | ------- Mês (1 - 12)
| | --------- Dia do mês (1 - 31)
| ----------- Hora (0 - 23)
------------- Minuto (0 - 59)
Info
- Um asterisco (
*
) em um campo significa "todos os valores possíveis" para aquele campo. - Valores específicos podem ser listados, separados por vírgulas (ex:
1,15
no campo de minutos significa "no minuto 1 e no minuto 15"). - Intervalos podem ser especificados com um hífen (ex:
1-5
no campo de horas significa "da 1h às 5h"). - Passos podem ser definidos com uma barra (ex:
*/10
no campo de minutos significa "a cada 10 minutos").
Isso torna o cron extremamente útil para tarefas rotineiras, como backups de banco de dados ou limpeza de arquivos temporários.
Exercise
Atualização para o uso do cron
Vamos utilizar o cron para agendar a execução do nossa tarefa (por enquanto, apenas um print
).
Para isto, considere os arquivos:
Exercise
app.py
Será igual ao primeiro arquivo app.py
proposto nesta aula.
crontab.txt
Info
A linha acima agenda a execução do app.py
a cada minuto (de cada hora, de cada dia, de cada mês, etc.).
A saída padrão e a saída de erro são redirecionadas para o arquivo /var/log/cron.log
.
Atenção!
Deixe uma linha em branco no final do arquivo crontab.txt
. O cron exige isto.
Dockerfile
Atualizaremos para uso do cron
:
FROM python:3.12-slim
# Instala o cron
RUN apt-get update && apt-get install -y cron && rm -rf /var/lib/apt/lists/*
WORKDIR /app
COPY app.py .
COPY crontab.txt .
# Adiciona o crontab ao cron do sistema
RUN crontab crontab.txt
# Cria um arquivo de log para o cron
RUN touch /var/log/cron.log
CMD ["cron", "-f"]
docker-compose.yml
De importante, apenas a atualização no nome do container!
Exercise
Se aguardar um minuto ou dois, irá perceber que não terá nenhum feedback. Isto ocorre porque os logs foram redirecionados para o arquivo /var/log/cron.log
(dentro do container).
Exercise
Answer
O comando docker exec python-scheduler-cron cat /var/log/cron.log
é utilizado para acessar o container em execução chamado python-scheduler-cron
e executar o comando cat /var/log/cron.log
dentro dele.
Isso permite visualizar o conteúdo do arquivo de log do cron, onde estão registrados os resultados das execuções agendadas.
Exercise
Exercise
Answer
O cron é um agendador simples.
Suas limitações incluem:
- Sem dependências: Não consegue gerenciar dependências entre tarefas
- Sem estado: Não rastreia se tarefas anteriores falharam ou tiveram sucesso
- Sem retry: Não tem mecanismos automáticos de reexecução em caso de falha
- Sem paralelização inteligente: Executa tarefas de forma isolada
- Monitoramento limitado: Logging básico, sem dashboards ou alertas
- Sem fluxo condicional: Não pode executar tarefas baseadas em resultados de outras
- Sem gestão de recursos: Não controla uso de CPU, memória ou concorrência
Com o cron
, tudo isto precisaria ser implementado pelo script iniciado ou por ferramentas externas.
Se quisermos um controle mais avançado sobre a execução das tarefas, precisamos considerar outras soluções.
Em ambientes de produção, o uso do cron pode não ser a melhor escolha devido às suas limitações. É importante avaliar outras opções que ofereçam mais robustez e recursos para o agendamento de tarefas.
Vamos discutir algumas alternativas na próxima página!
Exercise