Jak przekonwertować zadania crona w Linuksie na „sposób Amazon”?

112

Na dobre lub na złe przeprowadziliśmy migrację całej naszej aplikacji internetowej LAMP z dedykowanych maszyn do chmury (maszyny Amazon EC2). Jak dotąd idzie świetnie, ale sposób, w jaki robimy crony, jest nieoptymalny. Mam pytanie dotyczące Amazona, jak najlepiej zarządzać zadaniami cron w chmurze przy użyciu „sposobu Amazon”.

Problem : mamy wiele serwerów internetowych i musimy uruchamiać crony do zadań wsadowych, takich jak tworzenie kanałów RSS, wyzwalanie wiadomości e-mail, a właściwie wiele różnych rzeczy. ALE zadania crona muszą być uruchamiane tylko na jednym komputerze, ponieważ często zapisują w bazie danych, więc zduplikowałyby wyniki, gdyby były uruchamiane na wielu komputerach.

Do tej pory wyznaczyliśmy jeden z serwerów WWW jako „główny serwer WWW” i ma on kilka „specjalnych” zadań, których nie mają inne serwery sieciowe. Kompromisem za przetwarzanie w chmurze jest niezawodność - nie chcemy „głównego serwera internetowego”, ponieważ jest to pojedynczy punkt awarii. Chcemy, aby wszystkie były identyczne i aby można było przeskalować w górę lub w dół bez pamiętania, aby nie usuwać głównego serwera internetowego z klastra.

Jak możemy przeprojektować naszą aplikację, aby konwertować zadania Linux cron na przejściowe elementy pracy, które nie mają ani jednego punktu awarii?

Moje dotychczasowe pomysły:

  • Miej maszynę przeznaczoną tylko do uruchamiania cronów. Byłoby to trochę łatwiejsze w zarządzaniu, ale nadal stanowiłoby pojedynczy punkt awarii i zmarnowałoby trochę pieniędzy na posiadanie dodatkowej instancji.
  • Niektóre zadania można by przenieść z cronów Linuksa do MySQL Events, jednak nie jestem wielkim fanem tego pomysłu, ponieważ nie chcę umieszczać logiki aplikacji w warstwie bazy danych.
  • Być może możemy uruchomić wszystkie crony na wszystkich maszynach, ale zmienić nasze skrypty cron, aby wszystkie zaczęły się od odrobiny logiki, która implementuje mechanizm blokujący, więc tylko jeden serwer faktycznie podejmuje działanie, a inne po prostu pomijają. Nie jestem fanem tego pomysłu, ponieważ brzmi to potencjalnie błędnie i wolałbym skorzystać z najlepszych praktyk Amazon, zamiast tworzyć własne.
  • Wyobrażam sobie sytuację, w której zadania są gdzieś zaplanowane, dodane do kolejki, a następnie każdy z serwerów WWW może być pracownikiem, który może powiedzieć „hej, wezmę to”. Amazon Simple Workflow Service brzmi dokładnie w ten sposób, ale obecnie niewiele o nim wiem, więc wszelkie szczegóły byłyby pomocne. Wydaje się, że coś tak prostego jak cron wydaje się ciężkie? Czy jest to właściwa usługa, czy może istnieje bardziej odpowiednia usługa Amazon?

Aktualizacja: Od czasu zadania pytania obejrzałem webinarium Amazon Simple Workflow Service na YouTube i zauważyłem o 34:40 ( http://www.youtube.com/watch?v=lBUQiek8Jqk#t=34m40s ). slajd wspominający o zadaniach cron jako przykładowej aplikacji. Na swojej stronie dokumentacji „ AWS Flow Framework samples for Amazon SWF ” Amazon podaje, że ma przykładowy kod dla cronów:

... > Zadania Cron W tym przykładzie długotrwały przepływ pracy okresowo wykonuje działanie. Pokazana jest możliwość kontynuowania wykonywania jako nowych egzekucji, tak aby wykonanie mogło działać przez bardzo długi czas. ...

Ściągnąłem AWS SDK dla Java ( http://aws.amazon.com/sdkforjava/ ) i na pewno zakopany w śmiesznych warstwach folderów jest kod java ( aws-java-sdk-1.3.6/samples/AwsFlowFramework/src/com/amazonaws/services/simpleworkflow/flow/examples/periodicworkflow).

Problem polega na tym, że jeśli mam być szczery, to nie pomaga, ponieważ nie jest to coś, co mogę łatwo strawić dzięki moim umiejętnościom. Brakuje tej samej próbki w PHP SDK i nie wydaje się, aby istniał samouczek, który omawia ten proces. Zasadniczo więc wciąż szukam porad lub wskazówek.

Tomek
źródło
2
Prawdopodobnie powiązane: stackoverflow.com/questions/8812025/scheduling-a-job-on-aws-ec2
Ilmari Karonen

Odpowiedzi:

38

Zapisałem się do wsparcia Amazon Gold, aby zadać im to pytanie, to była ich odpowiedź:

Tomek

Zrobiłem szybką ankietę wśród niektórych moich kolegów i wyszedłem pusty na cronie, ale po spaniu na nim zdałem sobie sprawę, że ważny krok może ograniczać się do blokowania. Poszukałem więc „rozproszonego blokowania zadań crona” i znalazłem odniesienie do Zookeepera, projektu 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

Widziałem również odniesienie do używania memcached lub podobnego mechanizmu buforowania jako sposobu tworzenia blokad z TTL. W ten sposób ustawiasz flagę z TTL 300 sekund i żaden inny pracownik cron nie wykona zadania. Blokada zostanie automatycznie zwolniona po wygaśnięciu TTL. Jest to koncepcyjnie bardzo podobne do opcji SQS, o której rozmawialiśmy wczoraj.

Zobacz także; Pulchny http://static.googleusercontent.com/external_content/untrusted_dlcp/research.google.com/en//archive/chubby-osdi06.pdf

Daj mi znać, jeśli to pomoże, i nie krępuj się zadawać pytań. Jesteśmy świadomi, że nasze usługi mogą być złożone i zniechęcające zarówno dla początkujących, jak i doświadczonych programistów. Zawsze chętnie służymy poradami dotyczącymi architektury i najlepszych praktyk.

Z poważaniem,

Ronan G. Amazon Web Services

Tomek
źródło
13

Myślę, że ten film odpowiada dokładnie na twoje pytanie - cronjobs the aws way (skalowalny i odporny na błędy):

Korzystanie z Cron w chmurze z Amazon Simple Workflow

Film opisuje usługę SWF przy użyciu konkretnego przypadku użycia implementacji cronjobs.

Względna złożoność rozwiązania może być trudna do przełknięcia, jeśli pochodzisz bezpośrednio z pliku crontab. Na końcu znajduje się studium przypadku, które pomogło mi zrozumieć, co daje ta dodatkowa złożoność. Sugerowałbym obejrzenie tego studium przypadku i rozważenie wymagań dotyczących skalowalności i odporności na błędy, aby zdecydować, czy należy migrować z istniejącego rozwiązania crontab.

Nathan Buesgens
źródło
2
to świetna odpowiedź, ponieważ używa dobrze obsługiwanego narzędzia z AWS, a SWF to potężny produkt. Jedynym minusem, imo, jest to, że SWF ma znaczną krzywą uczenia się i może być trudny do wykonania skomplikowanych rzeczy. Przynajmniej takie było moje doświadczenie z samouczkami Java
Don Cheadle,
11

Zachowaj ostrożność przy używaniu SQS do cronjobów, ponieważ nie gwarantują one, że tylko „jedno zadanie będzie widoczne tylko dla jednej maszyny”. Gwarantują, że „przynajmniej jeden” otrzyma wiadomość.

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

P: Ile razy otrzymam każdą wiadomość?

Amazon SQS został zaprojektowany tak, aby dostarczać „przynajmniej raz” wszystkie wiadomości w swoich kolejkach. Chociaż w większości przypadków każda wiadomość zostanie dostarczona do aplikacji dokładnie raz, należy zaprojektować system tak, aby przetwarzanie wiadomości więcej niż jeden raz nie powodowało żadnych błędów ani niespójności.

Na razie mogę pomyśleć o rozwiązaniu, w którym masz jedną instancję z zainstalowaną instancją Gearman Job Server: http://gearman.org/ . Na tym samym komputerze konfigurujesz zadania cron, które generują polecenie wykonania zadania cronjob w tle. Wtedy jeden z twoich serwerów WWW (pracowników) zacznie wykonywać to zadanie, co gwarantuje, że tylko jeden go podejmie. Nie ma znaczenia, ilu masz pracowników (zwłaszcza gdy używasz automatycznego skalowania).

Problemy z tym rozwiązaniem to:

  • Serwer Gearmana to pojedynczy punkt awarii, chyba że skonfigurujesz go z rozproszoną pamięcią masową, na przykład używając memcached lub jakiejś bazy danych
  • Następnie korzystając z wielu serwerów Gearman, musisz wybrać taki, który tworzy zadanie za pomocą cronjob, więc znowu wracamy do tego samego problemu. Ale jeśli możesz żyć z tego rodzaju pojedynczym punktem awarii, użycie Gearmana wygląda na całkiem dobre rozwiązanie. Zwłaszcza, że ​​nie potrzebujesz do tego dużej instancji (w naszym przypadku wystarczy mikro).
Maciej Majewski
źródło
Cóż, wiadomości pozostają na serwerze po ich odebraniu. Od programisty zależy ich późniejsze usunięcie. Podczas przetwarzania nie ma do nich dostępu inny serwer.
Frederik Wordenskjold
2
@FrederikWordenskjold To jest niepoprawne, nawet po przekazaniu wiadomości jednemu klientowi można ją przekazać innemu, ponieważ replikacja stanu SQS jest asynchroniczna. Możesz nawet otrzymać kopię wiadomości „po” jej usunięciu!
Chris Pitman
Ta odpowiedź jest nieaktualna. Obecnie istnieją 2 rodzaje kolejek. Użyj FIFO, aby uzyskać dokładne jednorazowe przetwarzanie: wiadomość jest dostarczana raz i pozostaje dostępna, dopóki konsument ją nie przetworzy i nie usunie. Duplikaty nie są wprowadzane do kolejki. aws.amazon.com/sqs/features
Lukas Liesis
10

Amazon właśnie udostępnił nowe funkcje dla Elastic Beanstalk. Z dokumentów :

AWS Elastic Beanstalk obsługuje okresowe zadania
warstw środowiska roboczego w środowiskach ze wstępnie zdefiniowaną konfiguracją ze stosem rozwiązań zawierającym „v1.2.0” w nazwie kontenera. "

Możesz teraz utworzyć środowisko zawierające cron.yamlplik konfigurujący zadania planowania:

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

Wyobrażałbym sobie, że ubezpieczenie uruchomienia go tylko raz w środowisku autoskalowanym jest wykorzystywane przez kolejkę komunikatów (SQS). Kiedy demon Cron wyzwala zdarzenie, umieszcza to wywołanie w kolejce SQS, a wiadomość w kolejce jest oceniana tylko raz. Dokumentacja mówi, że wykonanie może zostać opóźnione, jeśli SQS ma wiele komunikatów do przetworzenia.

user541905
źródło
Czy mógłbyś również dołączyć jakąś treść z linków?
Robert
6

Natknąłem się na to pytanie po raz trzeci i pomyślałem, że się wtrącę. Od jakiegoś czasu mamy ten dylemat. Wciąż naprawdę poczuć AWS brakuje funkcji tutaj.

W naszym przypadku, po przyjrzeniu się możliwym rozwiązaniom, zdecydowaliśmy, że mamy dwie możliwości:

  • Skonfiguruj serwer cronjob, który uruchamia zadania, które powinny być uruchamiane tylko raz na raz, automatycznie skaluj je i upewnij się, że jest zastępowany, gdy niektóre statystyki CloudWatch nie są takie, jakie powinny być. Używamy cloud-initskryptów, aby uruchomić cronjobs. Oczywiście wiąże się to z przestojami, co prowadzi do pominięcia cronjobów (podczas wykonywania niektórych zadań co minutę, tak jak my).
  • Użyj logiki, która rcronużywa. Oczywiście magia nie jest tak naprawdę rcronsama w sobie, jest w logice, której używasz do wykrywania uszkodzonego węzła (używamy keepalivedtutaj) i „ulepszania” innego węzła do nadrzędnego.

Zdecydowaliśmy się na drugą opcję, po prostu dlatego, że jest niesamowicie szybka i mieliśmy już doświadczenie z serwerami internetowymi obsługującymi te cronjobs (w naszej erze przed AWS).

Oczywiście to rozwiązanie ma na celu zastąpienie tradycyjnego podejścia cronjob z jednym węzłem, w którym decydującym czynnikiem jest czas (np. „Chcę, aby zadanie A było uruchamiane raz dziennie o 5 rano” lub jak w naszym przypadku „Chcę zadanie B uruchomić raz na minutę ” ). Jeśli używasz cronjobs do wyzwalania logiki przetwarzania wsadowego, naprawdę powinieneś się przyjrzeć SQS. Nie ma dylematu aktywny-pasywny, co oznacza, że ​​możesz użyć jednego serwera lub całej siły roboczej do przetwarzania swojej kolejki. Sugerowałbym również rozważenie SWFmożliwości skalowania siły roboczej (chociaż auto scalingw większości przypadków może to również zadziałać).

Chcieliśmy uniknąć uzależnienia od innej osoby trzeciej.

Jaap Haagmans
źródło
6

W dniach 12/16 lutego Amazon opublikował na blogu temat planowania zadań SSH przy użyciu AWS Lambda . Myślę, że to odpowiada na pytanie.

Tomek
źródło
1
Czy można dodać dynamiczne cronjoby lub harmonogramy za pomocą AWS lambda?
Sanjay Kumar NS
Tak, możesz mieć wywoływane Lambdy przez zdarzenia Cloudwatch. Ustaw czas według własnego uznania.
Michael Quale
4

Dystrybucja polega na dystrybucji „Amazon”, co oznacza, że ​​nieporęczne pliki cron należy podzielić na wiele mniejszych zadań i przekazać odpowiednim maszynom.

Używając kolejki SQS z typem ustawionym na FIFO, sklej ją razem, aby upewnić się, że każde zadanie jest wykonywane tylko przez jedną maszynę. Toleruje również awarie, ponieważ kolejki będą buforować, dopóki maszyna nie zacznie się obracać.

FIFO Exactly-Once Processing : Wiadomość jest dostarczana raz i pozostaje dostępna, dopóki konsument ją nie przetworzy i nie usunie. Duplikaty nie są wprowadzane do kolejki.

Zastanów się również, czy naprawdę potrzebujesz grupować te operacje. Co się stanie, jeśli aktualizacje z jednej nocy będą znacznie większe niż oczekiwano? Nawet przy dynamicznym pozyskiwaniu zasobów przetwarzanie może zostać opóźnione w oczekiwaniu na uruchomienie wystarczającej liczby maszyn. Zamiast tego przechowuj dane w SDB, powiadamiaj maszyny o aktualizacjach za pośrednictwem SQS i twórz swój kanał RSS w locie (z buforowaniem).

Zadania wsadowe pochodzą z czasów, gdy zasoby przetwarzania były ograniczone, a usługi „na żywo” miały pierwszeństwo. W chmurze tak nie jest.

vsekhar
źródło
Dzięki - podoba mi się kierunek, który opisujesz.
Tom
5
Ostrzegamy, że SQS gwarantuje tylko, że wiadomość zostanie ostatecznie zobaczona przez maszynę, a nie, że wiadomości będą widziane tylko przez jeden serwer. Wszystko, co umieszczasz w kolejce SQS, powinno być idempotentne.
Richard Hurt
Moje zadanie crona powinno działać codziennie, a dzięki SQS możesz opóźnić tylko do 15 minut. Jedną z opcji może być dodanie do wiadomości niestandardowego tagu z docelowym czasem wykonania i umieszczenie go z powrotem w kolejce, jeśli ten czas jeszcze nie został osiągnięty - ale to naprawdę wygląda głupio. Ponadto nadal potrzebuję zadania cron, aby początkowo wypełnić kolejkę. Wydaje się, że to problem z jajkiem kurzego :) Ale nadal uważam, że SQS jest właściwym rozwiązaniem, ponieważ gwarantuje skalowalność i odporność na błędy
Raffaele Rossi
„Zadania wsadowe pochodzą z czasów, gdy zasoby przetwarzania były ograniczone, a usługi„ na żywo ”miały pierwszeństwo. W chmurze tak nie jest”. Dotyczy to niektórych, ale nie wszystkich rodzajów działalności. Na przykład przetwarzanie dzienników ruchu jest lepsze jako proces wsadowy niż na żywo.
Jordan Reiter,
1

Dlaczego miałbyś budować własne? Dlaczego nie użyć czegoś takiego jak Quartz (z planowaniem klastrowym). Zobacz dokumentację.

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

Rama Nallamilli
źródło
Użyłem Quartz.NET w rozwiązaniu SaaS, które w dużym stopniu opierało się na zaplanowanych zadaniach. Niektóre z nich to zadania związane z konserwacją systemu, ale większość to czynności zaplanowane przez użytkowników końcowych. Wszystkie nasze zadania trafiały do ​​kolejek wiadomości (amq), dla których mieliśmy dowolną liczbę idempotentnych usług. Interfejs API jest bardzo dobry i umożliwia tworzenie rozbudowanych harmonogramów. Nie skupiliśmy wielu instancji Quartz, ale obsługuje to.
Jerico Sandhorn
1

To, co robimy, to jeden konkretny serwer, który jest częścią naszego klastra aplikacji internetowych za ELB, który również ma przypisaną określoną nazwę DNS, abyśmy mogli uruchamiać zadania na tym konkretnym serwerze. Ma to również tę zaletę, że jeśli to zadanie spowoduje spowolnienie serwera, ELB usunie go z klastra, a następnie zwróci go po zakończeniu zadania i ponownie stanie się zdrowy.

Działa jak mistrz.

Patrick Steil
źródło
1

Jedną z metod sprawdzenia, czy wyrażenie cron działa w sposób Amazon, jest uruchomienie go za pomocą polecenia events. Na przykład:

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

Jeśli wyrażenie harmonogramu jest nieprawidłowe, to się nie powiedzie.

Więcej zasobów: https://docs.aws.amazon.com/cli/latest/reference/events/put-rule.html

Kevin Eid
źródło
0

Ponieważ nikt nie wspomniał o wydarzeniu CloudWatch , powiedziałbym, że jest to sposób AWS na wykonywanie zadań cron. Może uruchamiać wiele akcji, np. Funkcję Lambda, zadanie ECS.

wanghq
źródło