Comment convertir les tâches cron Linux à «la manière Amazon»?

112

Pour le meilleur ou pour le pire, nous avons migré l'ensemble de notre application Web LAMP des machines dédiées vers le cloud (machines Amazon EC2). Cela va très bien jusqu'à présent, mais la façon dont nous faisons des crons est sous-optimale. J'ai une question spécifique à Amazon sur la meilleure façon de gérer les tâches cron dans le cloud en utilisant «la manière Amazon».

Le problème : nous avons plusieurs serveurs Web et devons exécuter des crons pour des tâches par lots telles que la création de flux RSS, le déclenchement d'e-mails, de nombreuses choses différentes en fait. MAIS les travaux cron ne doivent être exécutés que sur une seule machine car ils écrivent souvent dans la base de données et dupliquent donc les résultats s'ils sont exécutés sur plusieurs machines.

Jusqu'à présent, nous avons désigné l'un des serveurs Web comme le "serveur Web principal" et il a quelques tâches "spéciales" que les autres serveurs Web n'ont pas. Le compromis pour le cloud computing est la fiabilité - nous ne voulons pas d'un «serveur Web maître» car c'est un point de défaillance unique. Nous voulons qu'ils soient tous identiques et qu'ils puissent être mis à l'échelle et à la baisse sans se souvenir de ne pas retirer le serveur Web maître du cluster.

Comment pouvons-nous repenser notre application pour convertir les tâches cron Linux en éléments de travail transitoires qui n'ont pas de point de défaillance unique?

Mes idées jusqu'à présent:

  • Avoir une machine dédiée à l'exécution de crons uniquement. Ce serait un peu plus gérable mais resterait un point de défaillance unique et gaspillerait de l'argent avec une instance supplémentaire.
  • Certains travaux pourraient éventuellement être déplacés des crons Linux vers MySQL Events, mais je ne suis pas un grand fan de cette idée car je ne veux pas mettre la logique d'application dans la couche de base de données.
  • Peut-être pouvons-nous exécuter tous les crons sur toutes les machines mais changer nos scripts cron pour qu'ils commencent tous avec un peu de logique qui implémente un mécanisme de verrouillage afin qu'un seul serveur agisse réellement et les autres sautent. Je ne suis pas fan de cette idée car elle semble potentiellement boguée et je préférerais utiliser une meilleure pratique d'Amazon plutôt que la nôtre.
  • J'imagine une situation où les travaux sont planifiés quelque part, ajoutés à une file d'attente et les serveurs Web pourraient alors être chacun un travailleur, qui peut dire "hé, je vais prendre celui-ci". Amazon Simple Workflow Service sonne exactement ce genre de chose, mais je ne sais pas grand chose à ce sujet actuellement, donc des détails seraient utiles. Cela semble assez lourd pour quelque chose d'aussi simple qu'un cron? Est-ce le bon service ou existe-t-il un service Amazon plus adapté?

Mise à jour: depuis que j'ai posé la question, j'ai regardé le webinaire d' Amazon Simple Workflow Service sur YouTube et remarqué à 34:40 ( http://www.youtube.com/watch?v=lBUQiek8Jqk#t=34m40s ), j'ai aperçu un diapositive mentionnant les tâches cron comme exemple d'application. Dans leur page de documentation, " Exemples AWS Flow Framework pour Amazon SWF ", Amazon déclare avoir un exemple de code pour les crons:

... > Tâches Cron Dans cet exemple, un workflow de longue durée exécute périodiquement une activité. La possibilité de continuer les exécutions en tant que nouvelles exécutions afin qu'une exécution puisse s'exécuter pendant de très longues périodes est démontrée. ...

J'ai téléchargé le kit SDK AWS pour Java ( http://aws.amazon.com/sdkforjava/ ) et bien sûr, enfoui dans des couches ridicules de dossiers, il y a du code java ( aws-java-sdk-1.3.6/samples/AwsFlowFramework/src/com/amazonaws/services/simpleworkflow/flow/examples/periodicworkflow).

Le problème est que, si je suis honnête, cela n'aide pas vraiment car ce n'est pas quelque chose que je peux facilement digérer avec mes compétences. Le même exemple est absent du SDK PHP et il ne semble pas y avoir de didacticiel expliquant le processus. Donc, fondamentalement, je cherche toujours des conseils ou des astuces.

À M
la source

Réponses:

38

Je me suis inscrit au support Amazon Gold pour leur poser cette question, voici leur réponse:

À M

J'ai fait un rapide sondage auprès de certains de mes collègues et suis venu vide sur le cron, mais après avoir dormi dessus, j'ai réalisé que l'étape importante pouvait être limitée au verrouillage. J'ai donc recherché le "verrouillage des tâches cron distribuées" et trouvé une référence à Zookeeper, un projet Apache.

http://zookeeper.apache.org/doc/r3.2.2/recipes.html

http://highscalability.com/blog/2010/3/22/7-secrets-to-successfully-scaling-with-scalr-on-amazon-by-se.html

J'ai également vu une référence à l'utilisation de Memcached ou d'un mécanisme de mise en cache similaire comme moyen de créer des verrous avec un TTL. De cette façon, vous définissez un indicateur, avec un TTL de 300 secondes et aucun autre travailleur cron n'exécutera le travail. Le verrou sera automatiquement libéré après l'expiration du TTL. Ceci est conceptuellement très similaire à l'option SQS dont nous avons discuté hier.

Regarde aussi; Potelé de Google http://static.googleusercontent.com/external_content/untrusted_dlcp/research.google.com/en//archive/chubby-osdi06.pdf

Faites-moi savoir si cela aide, et n'hésitez pas à poser des questions, nous sommes très conscients que nos services peuvent être complexes et intimidants pour les développeurs débutants et chevronnés. Nous sommes toujours heureux d'offrir des conseils d'architecture et de bonnes pratiques.

Meilleures salutations,

Services Web Ronan G. Amazon

À M
la source
13

Je pense que cette vidéo répond exactement à votre question - cronjobs à la manière aws (évolutive et tolérante aux pannes):

Utilisation de Cron dans le cloud avec Amazon Simple Workflow

La vidéo décrit le service SWF en utilisant le cas d'utilisation spécifique de l'implémentation de cronjobs.

La complexité relative de la solution peut être difficile à avaler si vous venez directement d'un crontab. Il y a une étude de cas à la fin qui m'a aidé à comprendre ce que cette complexité supplémentaire vous achète. Je suggérerais de regarder l'étude de cas et de prendre en compte vos exigences en matière d'évolutivité et de tolérance aux pannes pour décider si vous devez migrer à partir de votre solution crontab existante.

Nathan Buesgens
la source
2
c'est une excellente réponse car il utilise un outil bien pris en charge d'AWS, et SWF est un produit puissant. Le seul inconvénient, imo, est que SWF a une courbe d'apprentissage importante et qu'il peut être difficile de faire des choses compliquées. Au moins c'était mon expérience avec les didacticiels Java
Don Cheadle
11

Soyez prudent lorsque vous utilisez SQS pour les cronjobs, car ils ne garantissent pas qu'un seul travail est vu par une seule machine. Ils garantissent qu '«au moins un» recevra le message.

De: http://aws.amazon.com/sqs/faqs/#How_many_times_will_I_receive_each_message

Q: Combien de fois vais-je recevoir chaque message?

Amazon SQS est conçu pour fournir une livraison «au moins une fois» de tous les messages dans ses files d'attente. Bien que la plupart du temps, chaque message soit livré à votre application une seule fois, vous devez concevoir votre système de sorte que le traitement d'un message plus d'une fois ne crée aucune erreur ou incohérence.

Jusqu'à présent, je peux penser à la solution où vous avez une instance avec l'instance Gearman Job Server installée: http://gearman.org/ . Sur la même machine, vous configurez des tâches cron qui produisent une commande pour exécuter votre tâche cronjob en arrière-plan. Ensuite, l'un de vos serveurs Web (workers) commencera à exécuter cette tâche, il garantit qu'un seul la prendra. Peu importe le nombre de travailleurs dont vous disposez (en particulier lorsque vous utilisez la mise à l'échelle automatique).

Les problèmes avec cette solution sont:

  • Le serveur Gearman est un point de défaillance unique, sauf si vous le configurez avec un stockage distribué, par exemple en utilisant Memcached ou une base de données
  • Ensuite, en utilisant plusieurs serveurs Gearman, vous devez en sélectionner un qui crée la tâche via cronjob, nous revenons donc au même problème. Mais si vous pouvez vivre avec ce type de point de défaillance unique en utilisant Gearman, cela semble être une très bonne solution. Surtout que vous n'avez pas besoin de grande instance pour cela (une micro-instance dans notre cas suffit).
Maciej Majewski
la source
Eh bien, les messages restent sur le serveur après avoir été reçus. C'est au développeur de les supprimer par la suite. Pendant leur traitement, ils ne sont pas accessibles par un autre serveur.
Frederik Wordenskjold
2
@FrederikWordenskjold C'est incorrect, même après qu'un message a été donné à un client, il peut toujours être donné à un autre, car la réplication de l'état SQS est asynchrone. Vous pouvez même recevoir une copie d'un message "après" sa suppression!
Chris Pitman
Cette réponse est obsolète Il existe actuellement 2 types de files d'attente. Utilisez FIFO pour obtenir un traitement Exactly-Once: un message est remis une fois et reste disponible jusqu'à ce qu'un consommateur le traite et le supprime. Les doublons ne sont pas introduits dans la file d'attente. aws.amazon.com/sqs/features
Lukas Liesis
10

Amazon vient de publier de nouvelles fonctionnalités pour Elastic Beanstalk. À partir de la documentation :

AWS Elastic Beanstalk prend en charge les tâches périodiques pour les
niveaux d' environnement de travail dans les environnements exécutant une configuration prédéfinie avec une pile de solutions qui contient «v1.2.0» dans le nom du conteneur. "

Vous pouvez maintenant créer un environnement contenant un cron.yamlfichier qui configure les tâches de planification:

version: 1
cron:
- name: "backup-job"          # required - unique across all entries in this file
  url: "/backup"              # required - does not need to be unique
  schedule: "0 */12 * * *"    # required - does not need to be unique
- name: "audit"
  url: "/audit"
   schedule: "0 23 * * *"

J'imagine que l'assurance de ne l'exécuter qu'une seule fois dans un environnement à mise à l'échelle automatique est utilisée via la file d'attente de messages (SQS). Lorsque le démon cron déclenche un événement, il place cet appel dans la file d'attente SQS et le message dans la file d'attente n'est évalué qu'une seule fois. La documentation indique que l'exécution peut être retardée si SQS a de nombreux messages à traiter.

user541905
la source
Pourriez-vous également inclure du contenu à partir des liens?
Robert
6

Je suis tombé sur cette question pour la troisième fois maintenant et j'ai pensé que je participerais. Nous avons ce dilemme depuis un certain temps maintenant. Je reste vraiment l' impression AWS manque une fonctionnalité ici.

Dans notre cas, après avoir examiné les solutions possibles, nous avons décidé que nous avions deux options:

  • Configurez un serveur cronjob qui exécute les tâches qui ne doivent être exécutées qu'une seule fois à la fois, mettez-le à l'échelle automatiquement et assurez-vous qu'il est remplacé lorsque certaines statistiques CloudWatch ne sont pas ce qu'elles devraient être. Nous utilisons des cloud-initscripts pour exécuter les cronjobs. Bien sûr, cela s'accompagne d'un temps d'arrêt, conduisant à des cronjobs manqués (lors de l'exécution de certaines tâches toutes les minutes, comme nous le faisons).
  • Utilisez la logique qui rcronutilise. Bien sûr, la magie n'est pas vraiment en rcronsoi, c'est dans la logique que vous utilisez pour détecter un nœud défaillant (nous l'utilisons keepalivedici) et "mettre à niveau" un autre nœud vers le master.

Nous avons décidé d'opter pour la deuxième option, simplement parce qu'elle est extrêmement rapide et que nous avons déjà de l'expérience avec les serveurs Web exécutant ces cronjobs (dans notre ère pré-AWS).

Bien sûr, cette solution est conçue spécifiquement pour remplacer l'approche traditionnelle de cronjob à un nœud, où le timing est le facteur décisif (par exemple "Je veux que le travail A s'exécute une fois par jour à 5 heures du matin" , ou comme dans notre cas "Je veux le travail B à exécuter une fois par minute " ). Si vous utilisez cronjobs pour déclencher la logique de traitement par lots, vous devriez vraiment jeter un coup d'œil à SQS. Il n'y a pas de dilemme actif-passif, ce qui signifie que vous pouvez utiliser un seul serveur ou une main-d'œuvre entière pour traiter votre file d'attente. Je suggérerais également de chercher à mettre SWFà l'échelle votre main-d'œuvre (bien auto scalingque cela puisse également faire l'affaire dans la plupart des cas).

Dépendre d'un autre tiers était quelque chose que nous voulions éviter.

Jaap Haagmans
la source
6

Le 12 février 2016, Amazon a publié un blog sur la planification de tâches SSH à l'aide d'AWS Lambda . Je pense que cela répond à la question.

À M
la source
1
Est-il possible d'ajouter des tâches cron dynamiques ou des planifications à l'aide d'AWS lambda?
Sanjay Kumar NS
Oui, vous pouvez invoquer les Lambda par les événements Cloudwatch. Chronométrez-le comme bon vous semble.
Michael Quale
4

La méthode «Amazon» doit être distribuée, ce qui signifie que les crons volumineux doivent être divisés en plusieurs petits travaux et confiés aux bonnes machines.

À l'aide de la file d'attente SQS dont le type est défini sur FIFO, collez-les ensemble pour vous assurer que chaque travail est exécuté par une seule machine. Il tolère également les échecs, car les files d'attente seront mises en mémoire tampon jusqu'à ce qu'une machine redémarre.

Traitement FIFO Exactly-Once : Un message est livré une fois et reste disponible jusqu'à ce qu'un consommateur le traite et le supprime. Les doublons ne sont pas introduits dans la file d'attente.

Demandez-vous également si vous avez vraiment besoin de «grouper» ces opérations. Que se passe-t-il si les mises à jour d'une nuit sont considérablement plus importantes que prévu? Même avec des ressources dynamiques, votre traitement peut être retardé en attendant qu'un nombre suffisant de machines démarre. Au lieu de cela, stockez vos données dans SDB, informez les machines des mises à jour via SQS et créez votre flux RSS à la volée (avec mise en cache).

Les travaux par lots datent d'une époque où les ressources de traitement étaient limitées et où les services «en direct» avaient la priorité. Dans le cloud, ce n'est pas le cas.

vsekhar
la source
Merci - j'aime la direction que vous décrivez.
Tom
5
Soyez averti que SQS garantit seulement qu'un message sera finalement vu par une machine, pas que les messages ne seront vus que par un seul serveur. Tout ce que vous mettez dans une file d'attente SQS doit être idempotent.
Richard Hurt
Mon travail cron doit s'exécuter quotidiennement et avec SQS, vous ne pouvez retarder que jusqu'à 15 minutes. Une option pourrait être d'ajouter une balise personnalisée au message avec l'heure cible pour l'exécuter et le remettre dans la file d'attente si cette heure n'est pas encore atteinte - mais cela semble vraiment stupide. De plus, j'ai toujours besoin d'un travail cron pour remplir initialement la file d'attente. Cela semble un problème d'oeuf de poule :) Mais je pense toujours que SQS est la bonne chose à utiliser, car il garantit l'évolutivité et la tolérance aux pannes
Raffaele Rossi
"Les jobs batch datent d'une époque où les ressources de traitement étaient limitées et où les services" live "prenaient le dessus. Dans le cloud, ce n'est pas le cas." Cela est vrai pour certaines activités, mais pas toutes. Par exemple, le traitement des journaux de trafic est quelque chose de mieux en tant que traitement par lots qu'en direct.
Jordan Reiter
1

Pourquoi construiriez-vous le vôtre? Pourquoi ne pas utiliser quelque chose comme Quartz (avec la planification en cluster). Consultez la documentation.

http://quartz-scheduler.org/documentation/quartz-2.x/configuration/ConfigJDBCJobStoreClustering

Rama Nallamilli
la source
J'ai utilisé Quartz.NET dans une solution SaaS qui reposait fortement sur des tâches planifiées. Certains étaient des tâches de maintenance du système, mais la plupart des activités planifiées par les utilisateurs finaux. Toutes nos tâches ont été écrites dans des files d'attente de messages (amq) pour lesquelles nous disposions d'un nombre quelconque de services idempotents. L'API est très bonne et permet des horaires puissants. Nous n'avons pas regroupé plusieurs instances de Quartz, mais cela le prend en charge.
Jerico Sandhorn
1

Ce que nous faisons, c'est que nous avons un serveur particulier qui fait partie de notre cluster d'applications Web derrière un ELB également attribué un nom DNS spécifique afin que nous puissions exécuter les travaux sur ce serveur spécifique. Cela présente également l'avantage que si ce travail entraîne le ralentissement de ce serveur, l'ELB le supprime du cluster, puis le renvoie une fois le travail terminé et qu'il redevient sain.

Fonctionne comme un champion.

Patrick Steil
la source
1

Une méthode pour vérifier que votre expression cron fonctionne de la manière Amazon consiste à l'exécuter via la commande events. Par exemple:

aws events put-rule --name "DailyLambdaFunction" --schedule-expression "<your_schedule_expression>

Si votre expression de planification n'est pas valide, cela échouera.

Plus de ressources: https://docs.aws.amazon.com/cli/latest/reference/events/put-rule.html

Kevin Eid
la source
0

Puisque personne n'a mentionné CloudWatch Event , je dirais que c'est la façon AWS de faire des tâches cron. Il peut exécuter de nombreuses actions, telles que la fonction Lambda, la tâche ECS.

Wanghq
la source