Non eseguiamo lavori Cron a Nextdoor

Background

A Nextdoor, eseguiamo molti lavori pianificati per vari scopi importanti, come l’invio di decine di milioni di e-mail di digest ai nostri utenti ogni giorno, la generazione di report interni sulla nostra crescita e alcune attività operative. Come molte altre società internet (ad esempio, Airbnb e Quora), abbiamo iniziato con Cron e abbiamo finito per costruire la nostra sostituzione cron, che abbiamo chiamato Nextdoor Scheduler.

Utilizziamo Nextdoor Scheduler da oltre 18 mesi e ne siamo estremamente soddisfatti.

Quindi, qual è il problema con Cron?

Ci sono quattro problemi principali con Cron.

Innanzitutto, il modo in cui usiamo Cron non era scalabile. Abbiamo eseguito tutti i lavori Cron su una macchina scheduler muscoloso (c3.8xlarge). Man mano che abbiamo guadagnato la trazione, Cron jobs ha spinto la macchina al limite, in termini di utilizzo delle risorse di calcolo.

In secondo luogo, la modifica del crontab in testo normale è soggetta a errori per la gestione dei lavori, ad esempio, l’aggiunta di lavori, l’eliminazione di lavori o la pausa dei lavori. Ad esempio, un asterisco aggiuntivo ha impedito l’esecuzione di tutti i lavori di produzione l’altro giorno:

1 * * * * * /opt/nextdoor/some_job.sh

In terzo luogo, abbiamo sostenuto un sacco di overhead operativo con Cron. Abbiamo quasi duecento lavori di produzione che vengono eseguiti migliaia di volte al giorno, a frequenza diversa (ad esempio, minuziosamente, ogni ora, settimanalmente). Il fallimento del lavoro è comune. La persona oncall ha dovuto riavviare manualmente i lavori falliti più volte al giorno, a volte dopo la mezzanotte. Ecco un esempio di una tipica esperienza oncall: 1) ottenere paging con la riga di comando del lavoro fallito; 2) ssh nella macchina scheduler; 3) copia & incolla la riga di comando per eseguire nuovamente il lavoro fallito. Questo non è certamente un bene per la felicità di ingegneria-sì, ci preoccupiamo per la felicità dei nostri dipendenti!

In quarto luogo, abbiamo avuto poca visibilità per i lavori di produzione durante il runtime. Non c’era un modo semplice per sapere quali lavori erano in esecuzione o se ci sono riusciti.

Decisione

Abbastanza è abbastanza. Abbiamo deciso di costruire un cron-replacement. Ma perché non abbiamo usato soluzioni open source? Non siamo riusciti a trovarne uno adatto. Parliamo python. Volevamo sfruttare i componenti infrastrutturali esistenti in azienda. Volevamo costruirlo, capirlo e possederlo.

Per risolvere il problema di scalabilità, abbiamo reso ogni lavoro un’attività asincrona che può essere eseguita su un cluster di macchine Taskworker. Possiamo facilmente configurare i lavori eseguiti su Taskworker per riprovare automaticamente quando falliscono, il che richiede solo una singola modifica del codice di riga. I nostri ingegneri oncall amano questa funzione di auto-riprova!

Per sostituire Cron, abbiamo usato l’eccellente modulo python ApScheduler per pianificare i lavori, che ci ha permesso di gestire i lavori a livello di codice — abbiamo costruito API REST, strumenti da riga di comando e interfaccia utente web human-friendly.

Architettura

L’immagine seguente mostra l’architettura del nostro sistema di pianificazione.

Nextdoor Scheduler è implementato con Python / Tornado. Viene eseguito come un singolo processo daemon (processo di pianificazione) su una singola macchina, che consiste di tre componenti.

  1. Scheduler (o Scheduler principale). Sostituisce cron e pianifica i lavori da eseguire. Quando un lavoro viene attivato per l’esecuzione, il processo di pianificazione pubblica semplicemente un messaggio per il lavoro su Amazon SQS. Un cluster di macchine Taskworker afferrare i messaggi da Amazon SQS ed eseguire i lavori corrispondenti. Come accennato in precedenza, usiamo APScheduler per implementare core scheduler.
  2. API di pianificazione. Fornisce un’interfaccia REST per gestire i lavori, ad esempio aggiungendo lavori, mettendo in pausa/riprendendo un lavoro, rimuovendo lavori, modificando lavori e dando il via manualmente a un lavoro. Abbiamo creato strumenti da riga di comando in cima a Scheduler API per rendere le operazioni facili, ad esempio, mettendo in pausa un gruppo di lavori tutti in una volta.
  3. Interfaccia utente web. Si tratta di una singola pagina app parlando di API Scheduler. Abbiamo usato Backbone.js e Bootstrap per implementare l’interfaccia utente Web. Gli operatori umani utilizzano principalmente l’interfaccia utente Web per interagire con Nextdoor Scheduler.

Le informazioni di tutti i lavori e le esecuzioni dei lavori vengono memorizzate in un archivio dati. Usiamo Postgres principalmente qui a Nextdoor.

Web UI

Gli ingegneri amano Web UI di Nextdoor Scheduler, che fornisce un modo intuitivo per gestire i lavori, piuttosto che trattare con blackbox-come Cron ai vecchi tempi.

Pagina Lavori

In questa pagina, possiamo vedere quali lavori abbiamo e quando verranno eseguiti la prossima volta. Possiamo anche fare clic su “Esecuzione personalizzata” per avviare manualmente un lavoro.

Modifica di un lavoro

Possiamo facilmente modificare un lavoro, ad esempio, cambiare il suo programma e metterlo in pausa con un solo clic! Questo è molto meglio che modificare il testo normale crontab ai vecchi tempi.

Pagina Esecuzioni

Infine, abbiamo una grande visibilità per quali lavori sono in esecuzione e se hanno successo o meno.

Stendere

Scrivere codice è facile. Productionization è difficile. Quando abbiamo terminato l’implementazione di Nextdoor Scheduler, avevamo quasi 200 lavori Cron di produzione che dovevano migrare al nuovo sistema.

Abbiamo applicato ciò che abbiamo imparato dal progetto Taskworker per implementare il sistema di pianificazione Nextdoor. Quattro passi:

  1. Abbiamo scuro lanciato Nextdoor Scheduler alla produzione – nessun lavoro di produzione erano in esecuzione con il nuovo sistema ancora.
  2. Abbiamo aggiunto un interruttore di funzionalità alla classe base di tutti i lavori.
  3. Abbiamo lentamente e con attenzione attivato gli interruttori di funzionalità per ogni lavoro nell’arco di due settimane.
  4. Abbiamo spento la vecchia macchina di pianificazione muscolosa che eseguiva Cron.

Lieto fine

Con il nuovo Scheduler Nextdoor, siamo in grado di eseguire un’istanza EC2 di scheduler molto più economica (c3.2xlarge) rispetto a prima (c3.8xlarge), mantenendo il carico super basso mentre scarichiamo i lavori da eseguire su macchine Taskworker distribuite.

Ecco il confronto dell’utilizzo della CPU tra la vecchia macchina di pianificazione (grafico in alto) e la nuova macchina di pianificazione (grafico in basso):

Abbiamo utilizzato i lavori di pianificazione per oltre 18 mesi. Siamo felici finora. Se sei interessato a lavorare su questo tipo di problemi e altre interessanti sfide infrastrutturali, stiamo assumendo!

Lascia un commento

Il tuo indirizzo email non sarà pubblicato.