Як конвертувати завдання Linux cron на "шлях Амазонки"?


112

На краще чи гірше, ми перенесли весь наш веб-додаток LAMP із спеціалізованих машин у хмару (машини Amazon EC2). Поки що це чудово, але те, як ми робимо крони, є недостатньо оптимальним. У мене є специфічне для Amazon питання про те, як найкраще керувати роботами cron у хмарі за допомогою "способу Amazon".

Проблема : у нас є кілька веб-серверів, і нам потрібно запускати крони для пакетних завдань, таких як створення RSS-каналів, запуск електронних листів, багато різних речей. Але завдання Cron потрібно виконувати лише на одній машині, оскільки вони часто записують у базу даних, тому вони б дублювали результати, якщо вони працюють на кількох машинах.

Поки ми одного із веб-серверів позначали як "майстра-веб-сервера", і у нього є кілька "спеціальних" завдань, яких інші веб-сервери не мають. Компроміс хмарних обчислень - це надійність - ми не хочемо "майстер-веб-сервер", оскільки це єдина точка відмови. Ми хочемо, щоб вони були однаковими і мали змогу підвищувати масштаби та зменшувати масштаби, не пам'ятаючи про те, щоб не виводити веб-сервер з кластера.

Як ми можемо переробити наш додаток для перетворення завдань Linux cron в перехідні елементи роботи, у яких немає жодної точки відмови?

Мої ідеї поки що:

  • Майте машинку, присвячену лише бігучим кронам. Це було б трохи зручніше, але все-таки було б єдиним пунктом невдачі і витрачало б гроші на додатковий примірник.
  • Деякі завдання можна було б перенести з кронів Linux на MySQL Events, однак я не є великим прихильником цієї ідеї, оскільки не хочу вкладати логіку програми в рівень бази даних.
  • Можливо, ми можемо запустити всі крони на всіх машинах, але змінити наші сценарії cron, щоб вони почалися з трохи логіки, яка реалізує механізм блокування, тому лише один сервер дійсно вживає дій, а інші просто пропускають. Я не прихильник цієї ідеї, оскільки це звучить потенційно баггі, і я вважаю за краще використовувати найкращу практику Amazon, а не прокочувати власну.
  • Я уявляю ситуацію, коли завдання десь заплановані, додаються до черги, і тоді кожен веб-сервер міг би бути працівником, який може сказати "ага, я візьму цю". Служба Amazon Simple Workflow звучить саме так, але я зараз про це не знаю багато, тому будь-яка конкретика буде корисною. Це здається важким для чогось такого простого, як крон? Це правильна послуга чи є більш підходящий сервіс Amazon?

Оновлення. Оскільки я ставлю запитання, я переглянув вебінар служби Amazon Simple Workflow на YouTube і помітив о 34:40 ( http://www.youtube.com/watch?v=lBUQiek8Jqk#t=34m40s ), я побачив слайд, згадуючи завдання cron як зразок програми. На своїй сторінці документації " Зразки AWS Flow Framework для Amazon SWF " Amazon зазначають, що вони мають зразок коду для крони:

... > Завдання Cron У цьому прикладі тривалий робочий процес періодично виконує діяльність. Продемонстрована здатність продовжувати виконання, як нові, так що виконання може працювати протягом дуже тривалих періодів часу. ...

Я завантажив AWS SDK для Java ( http://aws.amazon.com/sdkforjava/ ) і впевнений, що достатньо закопаний у смішних шарах папок є якийсь код Java ( aws-java-sdk-1.3.6/samples/AwsFlowFramework/src/com/amazonaws/services/simpleworkflow/flow/examples/periodicworkflow).

Проблема полягає в тому, якщо я чесно кажучи, це не дуже допомагає, оскільки це не те, що я легко перетравлюю за допомогою набору навичок. Цей самий зразок відсутній у PHP SDK, і, здається, не буде навчального посібника, який ходить, хоч процес. Отже, я все ще полюю за порадами чи порадами.


Відповіді:


38

Я підписався на підтримку Amazon Gold, щоб задати їм це запитання, це була їх відповідь:

Том

Я зробив швидке опитування деяких своїх колег і підійшов порожнім на кроні, але після сну на ньому я зрозумів, що важливий крок може бути обмежений блокуванням. Тож я шукав "розподілене блокування робочих записів" і знайшов посилання на Zookeeper, проект 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

Крім того, я бачив посилання на використання memcached або подібний механізм кешування як спосіб створення замків з TTL. Таким чином ви встановлюєте прапор, TTL - 300 секунд, і жоден інший робітник не виконує завдання. Блокування автоматично зніметься після закінчення терміну дії TTL. Це концептуально дуже схоже на варіант SQS, про який ми говорили вчора.

Також див. Пухкий Google http://static.googleusercontent.com/external_content/untrusted_dlcp/research.google.com/en//archive/chubby-osdi06.pdf

Повідомте мене, якщо це допомагає, і не соромтесь задавати питання, ми чудово розуміємо, що наші послуги можуть бути складними і непростими як для початківців, так і для досвідчених розробників. Ми завжди раді запропонувати поради щодо архітектури та найкращих практик.

З найкращими побажаннями,

Веб-сервіси Ронана Г. Амазонки


13

Я думаю, що це відео відповідає на ваше точне запитання - це чіткий спосіб (масштабований і відмовлений):

Використання Cron у хмарі з Amazon Simple Workflow

Відео описує послугу SWF, використовуючи конкретний випадок використання впровадження кронштейнів.

Відносну складність розчину важко проковтнути, якщо ви йдете прямо з кронтабу. В кінці є тематичне дослідження, яке допомогло мені зрозуміти, що ця додаткова складність купує у вас. Я б запропонував переглянути тематичне дослідження та врахувати ваші вимоги щодо масштабованості та відмовостійкості, щоб вирішити, чи слід мігрувати зі свого існуючого рішення щодо кронатобу.


2
це чудова відповідь, оскільки він використовує добре підтримуваний інструмент від AWS, а SWF - потужний продукт. Єдиним недоліком, imo, є те, що SWF має значну криву навчання і з нею складно зробити складні речі. Принаймні, такий мій досвід роботи з навчальними посібниками Java
Дон Чейдл

11

Будьте обережні, використовуючи SQS для роботи на кронах, оскільки вони не гарантують, що лише "одну роботу бачить лише одна машина". Вони гарантують, що "принаймні один" отримає повідомлення.

Від: http://aws.amazon.com/sqs/faqs/#How_many_times_will_I_receive_each_message

З: Скільки разів я отримаю кожне повідомлення?

Amazon SQS розроблений, щоб забезпечити доставку всіх повідомлень у своїх чергах "принаймні один раз". Хоча більшість часу кожне повідомлення буде доставлено вашій програмі рівно один раз, ви повинні розробити свою систему так, щоб обробка повідомлення більше одного разу не створювала помилок чи невідповідностей.

Поки що я можу подумати про рішення, де у вас встановлений один екземпляр із встановленим екземпляром сервера Gearman Job: http://gearman.org/ . На цій же машині ви налаштовуєте завдання cron, які виробляють команду для виконання завдання cronjob у фоновому режимі. Тоді один із ваших веб-серверів (робітників) почне виконувати це завдання, це гарантує, що його виконає лише один. Не має значення, скільки у вас працівників (особливо коли ви використовуєте автоматичне масштабування).

Проблеми з цим рішенням:

  • Сервер Gearman є єдиною точкою відмови, якщо ви не налаштуєте його з розподіленим сховищем, наприклад, використовуючи memcached або якусь базу даних
  • Тоді, використовуючи кілька серверів Gearman, ви повинні вибрати той, який створює завдання через cronjob, тому ми знову повернемося до тієї ж проблеми. Але якщо ви можете жити з таким видом єдиної точки відмови, використовуючи Gearman, це виглядає цілком вдалим рішенням. Тим більше, що для цього вам не потрібен великий екземпляр (мікро екземпляра в нашому випадку достатньо).

Ну а повідомлення залишаються на сервері після їх отримання. Видалити їх слід згодом на розробника. Поки вони обробляються, вони не можуть отримати доступ до іншого сервера.
Frederik Wordenskjold

2
@FrederikWordenskjold Це неправильно, навіть після того, як повідомлення було надано одному клієнту, воно все одно може бути передане іншому, оскільки реплікація стану SQS є асинхронною. Можна навіть надати копію повідомлення "після", яке було видалено!
Кріс Пітман

Ця відповідь застаріла. Зараз існує 2 види черг. Використовуйте FIFO, щоб отримати точну обробку одного разу: повідомлення доставляється один раз і залишається доступним, поки споживач не обробить і не видалить його. Дублікати не вводяться в чергу. aws.amazon.com/sqs/features
Лукас Ліесіс

10

Amazon щойно випустила нові функції для Elastic Beanstalk. З документів :

AWS Elastic Beanstalk підтримує періодичні завдання для
рівнів робочого середовища в середовищах, що мають заздалегідь задану конфігурацію з стеком рішення, який містить "v1.2.0" у назві контейнера. "

Тепер ви можете створити середовище, що містить cron.yamlфайл, який налаштовує завдання планування:

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

Я б уявив, що страхування від його запуску лише один раз у автоматичному масштабі використовується через чергу повідомлень (SQS). Коли демон крона викликає подію, він ставить цей виклик у чергу SQS, а повідомлення в черзі оцінюється лише один раз. Документи кажуть, що виконання може затягнутися, якщо SQS має багато повідомлень для обробки.


Чи можете ви також включити якийсь вміст із посилань?
Роберт

6

Я вже втретє зіткнувся з цим питанням і подумав, що підкачуся. У нас ця проблема стояла вже деякий час. Я до сих пір дійсно відчуваю AWS відсутня функція тут.

У нашому випадку, подивившись на можливі рішення, ми вирішили, що у нас є два варіанти:

  • Налаштуйте сервер cronjob, який виконує завдання, які слід виконувати лише один раз за часом, автоматично масштабуйте його та переконайтесь, що він замінений, коли певна статистика CloudWatch не є такою, якою повинна бути. Ми використовуємо cloud-initсценарії для запуску роботи кронштейнів. Звичайно, це відбувається із простоєм, що призводить до пропущених клопотів (коли щохвилини виконуєш певні завдання, як у нас).
  • Використовуйте логіку, яка rcronвикористовує. Звичайно, магія насправді rcronсама по собі не полягає в логіці, яку ви використовуєте для виявлення несправного вузла (ми використовуємо keepalivedтут) та "оновлення" іншого вузла для управління.

Ми вирішили піти з другим варіантом, просто тому, що це блискуче швидко, і ми вже мали досвід роботи з веб-серверами, які виконували ці роботи (в нашу епоху до AWS).

Зрозуміло, це рішення призначене спеціально для заміни традиційного підходу з однорядковим дробовим завданням, де визначальним є фактор часу (наприклад, "я хочу, щоб робота А працювала один раз на 5 години ранку" , або як у нашому випадку "Я хочу роботу B бігати раз на хвилину " ). Якщо ви використовуєте cronjobs для запуску логічної обробки пакетної обробки, вам слід по- справжньому поглянути SQS. Немає активно-пасивної дилеми, тобто ви можете використовувати один сервер або всю робочу силу для обробки своєї черги. Я б також запропонував розглянути SWFмасштаб вашої робочої сили (хоча, auto scalingможливо, це вдасться зробити і в більшості випадків).

Залежно від іншої сторони було те, чого ми хотіли уникнути.


6

12 лютого / 16 лютого Amazon веде блог про планування роботи SSH за допомогою AWS Lambda . Я думаю, це відповідає на питання.


1
Чи можливо додати динамічні кройовки або графіки за допомогою лямбда AWS?
Санджай Кумар Н.С.

Так, ви можете викликати Lambda подіями Cloudwatch. Час, як ви вважаєте за потрібне.
Michael


4

Шлях "Амазонки" має бути розподілений, тобто об'ємні крони повинні бути розділені на багато менших робочих місць і передані правильним машинам.

Використовуючи чергу SQS з типом, встановленим на FIFO, склейте її, щоб забезпечити виконання кожної роботи лише однією машиною. Він також терпить відмови, оскільки черги буферуються, поки машина не повернеться назад.

Обробка FIFO - один раз : повідомлення надсилається один раз і залишається доступним, поки споживач не обробить і не видалить його. Дублікати не вводяться в чергу.

Також врахуйте, чи дійсно вам потрібно "пакетно" проводити ці операції. Що станеться, якщо оновлення однієї ночі значно більше очікуваного? Навіть при динамічному ресурсному обробці ваша обробка може затягнутися, чекаючи, поки з'явиться достатньо машини. Натомість зберігайте свої дані в SDB, повідомляйте машини про оновлення за допомогою SQS та створюйте свій RSS-канал на ходу (з кешування).

Пакетні завдання - це час, коли ресурси обробки були обмежені, а "живі" послуги мали перевагу. У хмарі це не так.


Спасибі - мені подобається напрямок, який ви описуєте.
Том

5
Попереджуйте, що SQS гарантує лише те, що повідомлення в кінцевому рахунку буде переглянуто машиною, а не те, що повідомлення бачитиме лише один сервер. Все, що ви помістите у чергу SQS, має бути ідентичним.
Річард Херт

Моя робота з Cron повинна працювати щодня, і з SQS ви можете затримати лише до 15 хвилин. Одним із варіантів може бути додавання користувальницького тегу до повідомлення з цільовим часом його виконання та повернення його в чергу, якщо цей час ще не досягнуто - але це справді виглядає німим. Також мені ще потрібна робота з кроном, щоб спочатку заповнити чергу. Здається, проблема з курячим яйцем :) Але я все ж вважаю, що SQS - це правильна річ, оскільки вона гарантує масштабованість та відмовостійкість
Raffaele Rossi,

"Пакетні завдання - це час, коли обробка ресурсів була обмежена, а" живі "послуги мали перевагу. У хмарі це не так." Це стосується деяких, але не всіх видів діяльності. Наприклад, обробка журналів трафіку - це щось краще, ніж пакетний процес, ніж живий.
Jordan Reiter

1

Навіщо ви будували своє? Чому б не використати щось на зразок кварцу (з кластерним плануванням). Дивіться документацію.

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


Я використовував Quartz.NET у рішенні SaaS, яке значною мірою покладалося на заплановані завдання. Деякі, де виконуються завдання з обслуговування системи, але більшість - там, де заплановані кінцеві користувачі. Усі наші завдання писали в черги повідомлень (amq), для яких ми мали будь-яку кількість ідентичних служб. API дуже хороший і дозволяє створювати потужні графіки. Ми не кластеризували декілька екземплярів Quartz, але це підтримує це.
Джеріко Сандхорн

1

Ми робимо те, що у нас є один конкретний сервер, який є частиною нашого кластеру веб-додатків позаду ELB, а також присвоює певне ім’я DNS, щоб ми могли виконувати завдання на цьому конкретному сервері. Це також має перевагу, що якщо це завдання призведе до сповільнення роботи цього сервера, ELB видалить його з кластера, а потім поверне його, коли робота закінчиться, і вона знову оздоровиться.

Працює як чемпіон.


1

Один із способів підтвердити, що ваше вираження cron працює амазонським способом, - це запустити його за допомогою команди події. Наприклад:

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

Якщо вираз розкладу недійсний, це не вдасться.

Більше ресурсів: https://docs.aws.amazon.com/cli/latest/reference/events/put-rule.html



0

Оскільки ніхто не згадував подію CloudWatch , я б сказав, що це AWS спосіб виконання завдань на крон. Він може виконувати багато дій, таких як функція лямбда, завдання ECS.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.