Design clássico · Sênior
Agendador de tarefas distribuído
Projeto de entrevista clássico. Pontos centrais: agendamento de jobs e locks distribuídos.
Resposta curta
Projeto de entrevista clássico. Pontos centrais: agendamento de jobs e locks distribuídos. Um agendador de jobs é um programa que executa jobs automaticamente em horários ou intervalos definidos. Um job é uma instância de uma tarefa e é composto da tarefa, da agenda e dos parâmetros para executá-la.
01 · CONTEXTO E REQUISITOS
O que um agendador de jobs precisa fazer
Um agendador de jobs é um programa que executa jobs automaticamente em horários ou intervalos definidos. Um job é uma instância de uma tarefa e é composto da tarefa, da agenda e dos parâmetros para executá-la.
Os requisitos funcionais centrais são dois: agendar jobs para execução imediata, em data futura ou em recorrência, e deixar o usuário acompanhar o status deles.
O guia da Hello Interview sugere assumir 10k jobs por segundo e lista três perguntas de aprofundamento: executar o job dentro de 2s do horário agendado, escalar até essa vazão e garantir execução ao menos uma vez.
02 · O DESENHO BÁSICO
Da API ao worker
O desenho deste artigo separa quatro responsabilidades: a API aceita e consulta jobs, o banco guarda o estado, o agendador decide o que venceu e os workers executam. Entre o agendador e os workers fica uma fila de execução.
O cliente pede à API para agendar um job: imediato, em data futura ou recorrente.
A API grava o job no banco com a tarefa, a agenda e os parâmetros de execução.
O agendador consulta o banco pelos jobs cujo horário chegou.
O agendador coloca cada job devido na fila de execução.
Um worker retira o job da fila, executa a tarefa e registra o status no banco, que é o que o usuário consulta.
03 · EXECUÇÃO AO MENOS UMA VEZ
Quando o worker cai no meio do job
Em uma fila como o SQS, se a mensagem não for apagada antes do fim do prazo de visibilidade, ela volta a ficar visível e outro consumidor pode recuperá-la.
Isso cobre falhas de aplicação, quedas e problemas de conectividade, e garante que a mensagem não se perca mesmo que o primeiro processamento falhe. O prazo pode ser estendido por programa com ChangeMessageVisibility.
O custo é a duplicidade: a documentação do SQS não garante que uma mensagem não seja entregue mais de uma vez dentro do prazo de visibilidade. O Cloud Scheduler também promete execução ao menos uma vez: o job roda ao menos uma vez por execução agendada e, em raras circunstâncias, pode rodar várias vezes para a mesma instância da agenda.
| O que garante | O que não garante | |
|---|---|---|
| Fila com prazo de visibilidade | A mensagem volta a ficar visível se não for apagada antes do prazo | Não garante que a mensagem não seja entregue mais de uma vez |
| Cloud Scheduler | O job roda ao menos uma vez por execução agendada | Pode rodar várias vezes para a mesma instância da agenda |
| CronJob do Kubernetes | Cria um Job aproximadamente uma vez por horário | Pode criar dois Jobs ou nenhum |
04 · MAIS DE UM AGENDADOR
O banco como árbitro
O Airflow suporta mais de um agendador ao mesmo tempo, tanto por desempenho quanto por resiliência, e o agendador em alta disponibilidade aproveita o banco de metadados já existente.
Dois agendadores leem o mesmo banco de metadados, sem canal direto entre eles.
Só um agendador por vez pode estar na seção crítica do laço de agendamento.
O banco faz valer essa regra com bloqueios de linha (SELECT ... FOR UPDATE).
Quem está na seção crítica seleciona o que está pronto, respeitando limites de concorrência, e enfileira para execução.
Essa é uma forma de coordenar vários agendadores: bloqueios no banco garantem que só um deles entre na seção crítica.
Outra forma é eleger um líder por lease, tema da próxima seção.
05 · LEASES E FENCING
Um líder por vez, mesmo com pausas
Um lease é um mecanismo para travar um recurso compartilhado e coordenar a atividade entre membros de um conjunto. O Kubernetes o usa para manter ativa uma só instância de um componente, com as demais em espera.
O prazo do lease evita que um cliente que caiu segure o lock para sempre. Mas, se uma pausa do cliente durar mais que o prazo e ele não perceber que o lease expirou, ele pode fazer uma alteração insegura.
Um agendador adquire o lease e age como líder; a outra instância fica em espera.
O lease tem prazo, para que um líder que caiu não segure o lock para sempre.
O líder pode pausar por mais tempo que o prazo, sem perceber que o lease expirou, e ainda tentar escrever.
O outro agendador adquire o lease e recebe um token maior que o do primeiro.
Quando o antigo líder volta e escreve com o token menor, o banco, que lembra do maior token já processado, rejeita a escrita.
06 · QUANDO O HORÁRIO PASSA
Atrasos e execuções que se sobrepõem
O CronJob do Kubernetes traz duas regras para horários que passam. Se o prazo de início é perdido, ele pula aquela instância e as próximas continuam agendadas. Com a política Forbid, se a execução anterior ainda não terminou, a nova execução é pulada.
Perguntas frequentes
O que é Agendador de tarefas distribuído?
Projeto de entrevista clássico. Pontos centrais: agendamento de jobs e locks distribuídos.
O que o design de Agendador de tarefas distribuído cobre?
Ele está organizado nestas seções: O que um agendador de jobs precisa fazer, Da API ao worker, Quando o worker cai no meio do job, O banco como árbitro, Um líder por vez, mesmo com pausas e Atrasos e execuções que se sobrepõem.
Quanto tempo leva Agendador de tarefas distribuído e qual é o nível?
Leva cerca de 16 minutos para ler e tem nível Sênior.
Agora projete você mesmo
Rode este caso como uma entrevista na escola de System Design: você toma as decisões, o tutor as questiona e você vê a nota do seu desenho.