Nous n’exécutons pas de travaux Cron chez Nextdoor

Contexte

Chez Nextdoor, nous exécutons de nombreux travaux planifiés à diverses fins importantes, telles que l’envoi quotidien de dizaines de millions d’e-mails digest à nos utilisateurs, la génération de rapports internes sur notre croissance et certaines tâches opérationnelles. Comme beaucoup d’autres sociétés Internet (par exemple, Airbnb et Quora), nous avons commencé avec Cron et avons fini par créer notre propre remplacement cron, que nous avons appelé Nextdoor Scheduler.

Nous utilisons Nextdoor Scheduler depuis plus de 18 mois et nous en sommes extrêmement satisfaits.

Alors, quel est le problème avec Cron?

Il y a quatre problèmes principaux avec Cron.

Tout d’abord, la façon dont nous utilisons Cron n’était pas évolutive. Nous avons exécuté tous les travaux Cron sur une machine de planification musclée (c3.8xlarge). Au fur et à mesure que nous gagnions du terrain, les travaux Cron ont poussé la machine à ses limites, en termes d’utilisation des ressources de calcul.

Deuxièmement, la modification du crontab en texte brut est sujette aux erreurs pour la gestion des tâches, par exemple, l’ajout de tâches, la suppression de tâches ou la mise en pause de tâches. Par exemple, un astérisque supplémentaire a empêché tous les travaux de production de fonctionner l’autre jour:

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

Troisièmement, nous avons subi beaucoup de frais généraux opérationnels avec Cron. Nous avons près de deux cents emplois de production qui sont exécutés des milliers de fois par jour, à des fréquences différentes (par exemple, minutieusement, toutes les heures, toutes les semaines). L’échec d’un emploi est courant. La personne en appel devait redémarrer manuellement les travaux ayant échoué plusieurs fois par jour, parfois après minuit. Voici un exemple d’expérience oncall typique: 1) soyez paginé avec la ligne de commande du travail ayant échoué; 2) ssh dans la machine du planificateur; 3) copiez & collez la ligne de commande pour relancer le travail ayant échoué. Ce n’est certainement pas bon pour le bonheur de l’ingénierie — oui, nous nous soucions du bonheur de nos employés!

Quatrièmement, nous avions peu de visibilité pour les travaux de production pendant l’exécution. Il n’y avait pas de moyen facile de savoir quels emplois fonctionnaient ou s’ils réussissaient.

Décision

Assez c’est assez. Nous avons décidé de construire un remplacement de cron. Mais pourquoi n’avons-nous pas utilisé de solutions open source ? Nous ne pouvions tout simplement pas en trouver un qui nous convienne. Nous parlons python. Nous voulions tirer parti des composants d’infrastructure existants dans l’entreprise. Nous voulions le construire, le comprendre et le posséder.

Pour résoudre le problème d’évolutivité, nous avons fait de chaque tâche une tâche asynchrone pouvant s’exécuter sur un cluster de machines Taskworker. Nous pouvons facilement configurer les tâches qui s’exécutent sur Taskworker pour qu’elles réessayent automatiquement lorsqu’elles échouent, ce qui ne nécessite qu’un seul changement de code de ligne. Nos ingénieurs oncall adorent cette fonction de nouvelle tentative automatique!

Pour remplacer Cron, nous avons utilisé l’excellent module python ApScheduler pour planifier les travaux, ce qui nous a permis de gérer les travaux par programmation — nous avons construit des API REST, des outils de ligne de commande et une interface Web conviviale.

Architecture

L’image suivante montre l’architecture de notre système de planificateur.

Nextdoor Scheduler est implémenté avec Python/Tornado. Il est exécuté en tant que processus démon unique (processus planificateur) sur une seule machine, composée de trois composants.

  1. Planificateur (ou Planificateur principal). Il remplace cron et planifie l’exécution des tâches. Lorsqu’une tâche est déclenchée pour s’exécuter, le processus du planificateur publie simplement un message pour la tâche sur Amazon SQS. Un cluster de machines de travail des tâches récupère les messages d’Amazon SQS et exécute les tâches correspondantes. Comme mentionné ci-dessus, nous utilisons APScheduler pour implémenter le planificateur principal.
  2. API du planificateur. Il fournit une interface REST pour gérer les tâches, par exemple l’ajout de tâches, la pause/ reprise d’une tâche, la suppression de tâches, la modification de tâches et le démarrage manuel d’une tâche. Nous avons créé des outils en ligne de commande au-dessus de l’API Scheduler pour faciliter les opérations, par exemple en interrompant un groupe de tâches en même temps.
  3. Interface utilisateur Web. C’est une application d’une seule page qui parle à l’API du planificateur. Nous avons utilisé Backbone.js et Bootstrap pour implémenter l’interface utilisateur Web. Les opérateurs humains utilisent principalement l’interface utilisateur Web pour interagir avec Nextdoor Scheduler.

Les informations de toutes les tâches et exécutions de tâches sont stockées dans un magasin de données. Nous utilisons Postgres principalement ici chez Nextdoor.

Interface utilisateur Web

Les ingénieurs adorent l’interface utilisateur Web de Nextdoor Scheduler, qui offre un moyen intuitif de gérer les tâches plutôt que de traiter le Cron semblable à une boîte noire dans l’ancien temps.

Page Emplois

Sur cette page, nous pouvons voir quels emplois nous avons et quand ils seront exécutés la prochaine fois. Nous pouvons également cliquer sur « Exécution personnalisée » pour lancer manuellement une tâche.

Modification d’une tâche

Nous pouvons facilement modifier un travail, par exemple, modifier son calendrier et le mettre en pause en un seul clic! C’est bien mieux que de modifier crontab en texte brut dans l’ancien temps.

Page Exécutions

Enfin, nous avons une grande visibilité sur les emplois en cours et s’ils réussissent ou non.

Déployer

Écrire du code est facile. La production est difficile. Au moment où nous avons terminé la mise en œuvre de Nextdoor Scheduler, nous avions près de 200 tâches Cron de production qui devaient migrer vers le nouveau système.

Nous avons appliqué ce que nous avons appris du projet Taskworker pour déployer le système de planificateur Nextdoor. Quatre étapes:

  1. Nous avons lancé le planificateur Nextdoor en production – aucun travail de production ne fonctionnait encore avec le nouveau système.
  2. Nous avons ajouté un commutateur de fonctionnalité à la classe de base de toutes les tâches.
  3. Nous avons lentement et soigneusement activé les commutateurs de fonctions pour chaque travail pendant deux semaines.
  4. Nous avons arrêté l’ancienne machine de planification costaude qui exécutait Cron.

Fin heureuse

Avec le nouveau planificateur Nextdoor, nous sommes en mesure d’exécuter une instance EC2 du planificateur beaucoup moins chère (c3.2xlarge) qu’auparavant (c3.8xlarge), tout en maintenant la charge très faible car nous déchargeons les tâches pour les exécuter sur des machines de travail distribuées.

Voici la comparaison de l’utilisation du PROCESSEUR entre l’ancienne machine de planification (graphique du haut) et la nouvelle machine de planification (graphique du bas):

Nous utilisons des emplois de planificateur depuis plus de 18 mois. Nous sommes heureux jusqu’à présent. Si vous êtes intéressé à travailler sur ce genre de problèmes et d’autres défis d’infrastructure intéressants, nous embauchons!

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée.