Come convertire i cron job di Linux in "alla maniera Amazon"?


112

Nel bene e nel male, abbiamo migrato tutta la nostra applicazione web LAMP da macchine dedicate al cloud (macchine Amazon EC2). Finora sta andando alla grande, ma il modo in cui facciamo i cron non è ottimale. Ho una domanda specifica per Amazon su come gestire al meglio i cron job nel cloud utilizzando "la modalità Amazon".

Il problema : abbiamo più server web e abbiamo bisogno di eseguire crons per lavori batch come la creazione di feed RSS, l'attivazione di e-mail, molte cose diverse in realtà. MA i cron job devono essere eseguiti solo su una macchina perché spesso scrivono nel database, quindi duplicherebbero i risultati se eseguiti su più macchine.

Finora, abbiamo designato uno dei server web come "server web principale" e ha alcuni compiti "speciali" che gli altri server web non hanno. Il compromesso per il cloud computing è l'affidabilità: non vogliamo un "server web master" perché è un singolo punto di errore. Vogliamo che siano tutti identici e che siano in grado di eseguire l'upscaling e il downscaling senza ricordarsi di non estrarre il server web principale dal cluster.

Come possiamo riprogettare la nostra applicazione per convertire i cron job di Linux in elementi di lavoro temporanei che non hanno un singolo punto di errore?

Le mie idee finora:

  • Avere una macchina dedicata solo alla corsa dei cron. Questo sarebbe un po 'più gestibile, ma sarebbe comunque un single-point-of-failure e sprecherebbe un po' di soldi per avere un'istanza in più.
  • Alcuni lavori potrebbero essere trasferiti da utenti Linux a eventi MySQL, tuttavia non sono un grande fan di questa idea in quanto non voglio inserire la logica dell'applicazione nel livello del database.
  • Forse possiamo eseguire tutti i cron su tutte le macchine ma modificare i nostri script cron in modo che inizino tutti con un po 'di logica che implementa un meccanismo di blocco in modo che solo un server effettui un'azione e gli altri saltino. Non sono un fan di questa idea in quanto suona potenzialmente buggata e preferirei utilizzare una best practice di Amazon piuttosto che eseguire la nostra.
  • Immagino una situazione in cui i lavori sono programmati da qualche parte, aggiunti a una coda e quindi i server web potrebbero essere ciascuno un lavoratore, che può dire "ehi, prendo questo". Amazon Simple Workflow Service suona esattamente questo genere di cose, ma al momento non ne so molto, quindi qualsiasi specifica sarebbe utile. Sembra un po 'pesante per qualcosa di semplice come un cron? È il servizio giusto o esiste un servizio Amazon più adatto?

Aggiornamento: da quando ho posto la domanda ho guardato il webinar Amazon Simple Workflow Service su YouTube e ho notato che alle 34:40 ( http://www.youtube.com/watch?v=lBUQiek8Jqk#t=34m40s ) ho intravisto un diapositiva che menziona cron jobs come applicazione di esempio. Nella loro pagina di documentazione, " Esempi di AWS Flow Framework per Amazon SWF ", Amazon afferma di avere un codice di esempio per crons:

... > Cron jobs In questo esempio, un flusso di lavoro a lunga esecuzione esegue periodicamente un'attività. Viene dimostrata la capacità di continuare le esecuzioni come nuove esecuzioni in modo che un'esecuzione possa essere eseguita per periodi di tempo molto estesi. ...

Ho scaricato l'SDK AWS per Java ( http://aws.amazon.com/sdkforjava/ ) e sicuramente sepolto all'interno di ridicoli livelli di cartelle c'è del codice java ( aws-java-sdk-1.3.6/samples/AwsFlowFramework/src/com/amazonaws/services/simpleworkflow/flow/examples/periodicworkflow).

Il problema è che, se devo essere onesto, questo non aiuta davvero perché non è qualcosa che posso digerire facilmente con le mie abilità. Lo stesso esempio non è presente nell'SDK PHP e non sembra esserci un tutorial che accompagni il processo. Quindi, in pratica, sto ancora cercando consigli o suggerimenti.


Risposte:


38

Mi sono iscritto al supporto di Amazon Gold per porre loro questa domanda, questa è stata la loro risposta:

Tom

Ho fatto un rapido sondaggio ad alcuni dei miei colleghi e sono uscito vuoto sul cron, ma dopo averci dormito ho capito che il passaggio importante potrebbe essere limitato al blocco. Quindi ho cercato "blocco del job cron distribuito" e ho trovato un riferimento a Zookeeper, un progetto 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

Inoltre ho visto riferimenti all'uso di memcached o un meccanismo di cache simile come un modo per creare blocchi con un TTL. In questo modo imposti un flag, con un TTL di 300 secondi e nessun altro cron worker eseguirà il lavoro. Il blocco verrà rilasciato automaticamente allo scadere del TTL. Questo è concettualmente molto simile all'opzione SQS di cui abbiamo discusso ieri.

Vedi anche; Il paffuto http://static.googleusercontent.com/external_content/untrusted_dlcp/research.google.com/en//archive/chubby-osdi06.pdf di Google

Fammi sapere se questo aiuta e sentiti libero di fare domande, siamo molto consapevoli che i nostri servizi possono essere complessi e scoraggianti sia per i principianti che per gli sviluppatori esperti. Siamo sempre felici di offrire consigli sull'architettura e sulle migliori pratiche.

I migliori saluti,

Ronan G. Amazon Web Services


13

Penso che questo video risponda alla tua domanda esatta: cronjobs in aws (scalabile e tollerante ai guasti):

Utilizzo di Cron nel cloud con Amazon Simple Workflow

Il video descrive il servizio SWF utilizzando il caso d'uso specifico dell'implementazione di cronjobs.

La relativa complessità della soluzione può essere difficile da digerire se provieni direttamente da un crontab. C'è un caso di studio alla fine che mi ha aiutato a capire cosa ti fa guadagnare quella complessità extra. Suggerirei di guardare il case study e di considerare i requisiti di scalabilità e tolleranza ai guasti per decidere se è necessario migrare dalla soluzione crontab esistente.


2
questa è un'ottima risposta in quanto utilizza uno strumento ben supportato da AWS e SWF è un prodotto potente. L'unico svantaggio, imo, è che SWF ha una curva di apprendimento significativa e può essere difficile fare cose complicate con. Almeno questa è stata la mia esperienza con i tutorial Java
Don Cheadle

11

Fai attenzione quando usi SQS per cronjobs, poiché non garantiscono che "un solo lavoro è visto da una sola macchina". Garantiscono che "almeno uno" riceverà il messaggio.

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

D: Quante volte riceverò ogni messaggio?

Amazon SQS è progettato per fornire la consegna "almeno una volta" di tutti i messaggi nelle sue code. Sebbene la maggior parte delle volte ogni messaggio verrà consegnato all'applicazione esattamente una volta, è necessario progettare il sistema in modo che l'elaborazione di un messaggio più di una volta non crei errori o incongruenze.

Finora posso pensare alla soluzione in cui hai un'istanza con l'istanza Gearman Job Server installata: http://gearman.org/ . Sulla stessa macchina si configurano i cron job che producono il comando per eseguire l'attività cronjob in background. Quindi uno dei tuoi server web (lavoratori) inizierà a eseguire questa attività, garantisce che solo uno la prenderà. Non importa quanti lavoratori hai (specialmente quando utilizzi il ridimensionamento automatico).

I problemi con questa soluzione sono:

  • Il server Gearman è un singolo punto di errore, a meno che non lo si configura con l'archiviazione distribuita, ad esempio utilizzando memcached o un database
  • Quindi utilizzando più server Gearman devi selezionarne uno che crea attività tramite cronjob, quindi di nuovo torniamo allo stesso problema. Ma se riesci a convivere con questo tipo di singolo punto di errore utilizzando Gearman sembra una soluzione abbastanza buona. Soprattutto che non hai bisogno di una grande istanza per quello (la microistanza nel nostro caso è sufficiente).

Ebbene, i messaggi rimangono sul server dopo che sono stati ricevuti. Spetta allo sviluppatore eliminarli in seguito. Durante l'elaborazione, non è possibile accedervi da un altro server.
Frederik Wordenskjold

2
@FrederikWordenskjold Ciò non è corretto, anche dopo che un messaggio è stato dato a un client, può ancora essere dato a un altro, poiché la replica dello stato SQS è asincrona. Puoi persino ricevere una copia di un messaggio "dopo" che è stato cancellato!
Chris Pitman

Questa risposta è obsoleta Ci sono 2 tipi di code ora. Usa FIFO per ottenere l'elaborazione Exactly-Once: un messaggio viene consegnato una volta e rimane disponibile fino a quando un consumatore non lo elabora e lo elimina. I duplicati non vengono introdotti nella coda. aws.amazon.com/sqs/features
Lukas Liesis

10

Amazon ha appena rilasciato nuove funzionalità per Elastic Beanstalk. Dai documenti :

AWS Elastic Beanstalk supporta attività periodiche per i
livelli dell'ambiente di lavoro in ambienti che eseguono una configurazione predefinita con uno stack di soluzioni che contiene "v1.2.0" nel nome del contenitore. "

È ora possibile creare un ambiente contenente un cron.yamlfile che configura le attività di pianificazione:

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 * * *"

Immagino che l'assicurazione di eseguirlo solo una volta in un ambiente a scalabilità automatica venga utilizzata tramite la coda dei messaggi (SQS). Quando il demone cron attiva un evento, inserisce quella chiamata nella coda SQS e il messaggio nella coda viene valutato solo una volta. I documenti dicono che l'esecuzione potrebbe essere ritardata se SQS ha molti messaggi da elaborare.


Potresti includere anche alcuni contenuti dai link?
Robert

6

Mi sono imbattuto in questa domanda per la terza volta e ho pensato di intervenire. Abbiamo questo dilemma da un po 'di tempo. Ho ancora davvero sento AWS manca una caratteristica qui.

Nel nostro caso, dopo aver esaminato le possibili soluzioni, abbiamo deciso di avere due opzioni:

  • Configura un server cronjob che esegue i lavori che dovrebbero essere eseguiti solo una volta alla volta, ridimensionalo automaticamente e assicurati che sia sostituito quando alcune statistiche di CloudWatch non sono quelle che dovrebbero essere. Usiamo cloud-initscript per far funzionare i cronjob. Ovviamente, questo comporta un tempo di inattività, che porta a cronjobs persi (quando si eseguono determinate attività ogni minuto, come facciamo noi).
  • Usa la logica che rcronusa. Ovviamente, la magia non è realmente in rcronsé, è nella logica che usi per rilevare un nodo guasto (usiamo keepalivedqui) e "aggiornare" un altro nodo da master.

Abbiamo deciso di optare per la seconda opzione, semplicemente perché è straordinariamente veloce e avevamo già esperienza con server web che eseguono questi cronjob (nella nostra era pre-AWS).

Ovviamente, questa soluzione è pensata specificamente per sostituire il tradizionale approccio cronjob a un nodo, dove la tempistica è il fattore decisivo (ad esempio "Voglio che il lavoro A venga eseguito una volta al giorno alle 5 del mattino" , o come nel nostro caso "Voglio il lavoro B da eseguire una volta al minuto " ). Se usi cronjobs per attivare la logica di elaborazione batch, dovresti davvero dare un'occhiata SQS. Non esiste un dilemma attivo-passivo, il che significa che puoi utilizzare un singolo server o un'intera forza lavoro per elaborare la tua coda. Suggerirei anche di cercare SWFdi ridimensionare la forza lavoro (anche se auto scalingnella maggior parte dei casi potrebbe essere in grado di fare il trucco).

La dipendenza da un'altra terza parte era qualcosa che volevamo evitare.




4

Il modo "Amazon" deve essere distribuito, il che significa che i cron ingombranti dovrebbero essere suddivisi in molti lavori più piccoli e consegnati alle macchine giuste.

Utilizzando la coda SQS con il tipo impostato su FIFO, incollala insieme per assicurarti che ogni lavoro venga eseguito da una sola macchina. Tollera anche i guasti poiché le code verranno bufferizzate fino a quando una macchina non esegue il backup.

Elaborazione FIFO Exactly-Once : un messaggio viene consegnato una volta e rimane disponibile finché un consumatore non lo elabora e lo elimina. I duplicati non vengono introdotti nella coda.

Considera anche se hai davvero bisogno di "batch" queste operazioni. Cosa succede se gli aggiornamenti di una notte sono notevolmente maggiori del previsto? Anche con le risorse dinamiche, la tua elaborazione potrebbe subire ritardi in attesa di un numero sufficiente di macchine per girare. Archivia invece i tuoi dati in SDB, notifica alle macchine gli aggiornamenti tramite SQS e crea il tuo feed RSS al volo (con memorizzazione nella cache).

I lavori batch risalgono a un'epoca in cui le risorse di elaborazione erano limitate e i servizi "live" avevano la precedenza. Nel cloud, non è così.


Grazie - mi piace la direzione che stai descrivendo.
Tom

5
Tieni presente che SQS garantisce solo che un messaggio verrà visto da una macchina alla fine, non che i messaggi saranno visti solo da un singolo server. Tutto ciò che inserisci in una coda SQS dovrebbe essere idempotente.
Richard Hurt

Il mio cron job dovrebbe essere eseguito quotidianamente e con SQS puoi ritardare solo fino a 15 minuti. Un'opzione potrebbe essere l'aggiunta di un tag personalizzato al messaggio con il tempo di destinazione per eseguirlo e rimetterlo in coda se quel tempo non è ancora raggiunto, ma sembra davvero una cosa stupida. Inoltre ho ancora bisogno di un cron job per popolare inizialmente la coda. Sembra un problema da uovo di gallina :) Ma continuo a pensare che SQS sia la cosa giusta da usare, perché garantisce scalabilità e tolleranza ai guasti
Raffaele Rossi

"I lavori in batch risalgono a un'epoca in cui le risorse di elaborazione erano limitate e i servizi" live "avevano la precedenza. Nel cloud, non è così". Questo è vero per alcune ma non per tutte le attività. Ad esempio, l'elaborazione dei registri del traffico è qualcosa che è meglio come elaborazione batch che live.
Jordan Reiter

1

Perché dovresti costruirne uno tuo? Perché non usare qualcosa come Quartz (con Clustered Scheduling). Vedere la documentazione.

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


Ho usato Quartz.NET in una soluzione SaaS che faceva molto affidamento su attività pianificate. Alcuni erano attività di manutenzione del sistema, ma la maggior parte erano attività pianificate dagli utenti finali. Tutte le nostre attività scrivevano su code di messaggi (amq) per le quali avevamo un numero qualsiasi di servizi idempotenti. L'API è molto buona e consente programmi potenti. Non abbiamo raggruppato più istanze di Quartz, ma lo supporta.
Jerico Sandhorn

1

Quello che facciamo è avere un particolare server che fa parte del nostro cluster di applicazioni web dietro un ELB anche assegnato a un nome DNS specifico in modo che possiamo eseguire i lavori su quel server specifico. Questo ha anche il vantaggio che se quel lavoro fa rallentare il server, l'ELB lo rimuoverà dal cluster e poi lo restituirà una volta che il lavoro è finito e si ripristina.

Funziona come un campione.




0

Poiché nessuno ha menzionato CloudWatch Event , direi che è il modo in cui AWS esegue i cron job. Può eseguire molte azioni, come la funzione Lambda, l'attività ECS.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.