LINUX.ORG.RU

Помогите с логикой «распределенного» крона

 , , task queue


0

2

Хочется сделать подобие крона на ноде - чтобы задачи запускались по времени. Не хочу ставить выделенные вундервафли типа gearman, хочу простую встроенную библиотеку.

- Инстансов ноды может быть несколько, в т.ч. на разных железках.
- Есть редис под шареные локи.
- Сплитами сетки пренебрегаем.
- У части задач хотелось бы запуск именно по расписанию, а не через таймаут.
- Некоторые толстые задачи надо бить на чанки. Например, «перегенерить 10 миллионов постов»

Чего хотелось бы:

1. Чтобы задача не запускалась дважды в разных местах.
2. Чтобы при некотором разъезжании часов на серверах все не сходило с ума.
3. Чтобы если сервер с активной задачей выключили или задача упала, то очередь не вставала колом.
4. Чтобы логика у всех инстансов была равноправной

Мне НЕ нужна отказоустойчивость, нужна простота деплоя - чтобы можно было наскейлить докеровских образов, и они не передрались. Ну и чтобы некоторые таски вроде перестройки 10.000.000 постов можно было напилить на диапазоны и запустить параллельно. У меня очень простые задачи, не требующие особой надежности. Значение имеет только простота использования.

Пока получается такой лисапед:

1. Генерим по расписанию «ждущую» задачу, с таймстампом. По таймстампу можно проверять уникальность даже если часы разъехались.
2. Первый, кто успел, атомарно переносит задачу в редисе из сета «ждущих» в сет «выполняемых».
3. Если задача долго висит в «выполняемых», значит все подвисло/упало, и любой может вернуть ее в «ждущие»

Что пока не очень получается:

1. Не совсем понятно, что делать, если задача действительно выполняется долго (можно обновлять дополнительный timestamp, но если у серверов разъедутся часы, то кто-то может решить что наступил таймаут)
2. Непонятно, что делать, если задача выполняется так долго, что по расписанию пора запустить ее опять.
3. Может быть я чего-то не прочухал, и задачи начнут стягиваться на одну ноду, затупляя отклик вебсервера для части юзеров.

Подскажите, где можно почитать про подобные алгоритмы.

Возможно, я смешиваю в кучу понятие очереди задач и расписания. Надо и то и то. Например, чистить базу, пересчитывать статистику, отправлять письма с разным приоритетом (подтверждения с секретными ссылками, уведомления об обновлениях, рассылки), в фоновом режиме перегенерить содержимое постов.

Меня интересует именно логика, а не «поставь пакет ХХХ и пользуйся». И нужен именно вариант встроенного решения. Не вижу смысла возиться с выделенными серверами и микросервисами и мастер-процессами. У меня не те нагрузки, чтобы по-взрослому загоняться. Надо дешево и сердито - простота важнее.

★★★★★

Последнее исправление: Vit (всего исправлений: 2)

1. Генерим по расписанию «ждущую» задачу, с таймстампом. По таймстампу можно проверять уникальность даже если часы разъехались.

Разрешение таймстампа 1с. А даже если возникновение задач разделено временем, используется его уникальность. Простой нарастающий счётчик обладает этим свойством.

2. Первый, кто успел, атомарно переносит задачу в редисе из сета «ждущих» в сет «выполняемых».

Лучше что бы он «присваивал» себе задачу.

3. Если задача долго висит в «выполняемых», значит все подвисло/упало, и любой может вернуть ее в «ждущие»

Имхо лучше не любой, а контроль. Хотя...

Кроме того для этого и нужно знать, кто взял себе задачу. Если становится известно, что узел упал, его задачи одним махом освобождаются.

А если узел быстро восстановился, он может забрать свои задачи себе.

upd:

Непонятно, что делать, если задача выполняется так долго, что по расписанию пора запустить ее опять.

Значит это неправильное расписание. Задача тут не при чём.

ziemin ★★
()
Последнее исправление: ziemin (всего исправлений: 2)

Может попробовать сделать через оркестратор какой-нибудь - раздавать задачи нодам с какой-нибудь «мастер»-ноды? Или я не понял что тебе нужно?

alozovskoy ★★★★★
()

Mesos + Chronos + немного напильника и Scala.

Самому на коленке такое пилить не очень разумное решение, т.к. один только мультимастер с кворумами задолбаешься проектировать. А когда дойдешь до пессиместичных и оптимистичных алгоритмов расределения ресурсов(да, снапшотами там не отделаешься), то уже будет пора закапывать проект.

xpahos ★★★★★
()
Ответ на: комментарий от xpahos

Вот поэтому спрашиваю чего почитать, чтобы не вляпаться куда не надо. Мультимастера мне на надо. Точка отказа в виде общего редиса меня устраивает.

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

Нужно «всего лишь», чтобы при «облачном» деплое не возникало коллизий между инстансами вебни.

Vit ★★★★★
() автор топика
Ответ на: комментарий от ziemin

Разрешение таймстампа 1с. А даже если возникновение задач разделено временем, используется его уникальность. Простой нарастающий счётчик обладает этим свойством.

Что-то не догоняю. Если 10 инстансов пытаются ежедневно в 5 утра запустить задачу, как с помощью счетчика оставить только одну? По таймстампу я могу проверить, что «в 5 утра уже запускали, т.к маркер с этим временем уже создан». А с простым счетчиком как?

Имхо лучше не любой, а контроль. Хотя...

Редиска общая (и точка отказа в т.ч.), там операции атомарные. Вроде без разницы кто станет задачу восстанавливать - один сможет, остальные зафейлятся.

Тут другой момент - а что если на серверах часы сбились? Тот у которого часы на пару минут вперед уехали, станет гнобить все остальные, т.к. «задача висит 2 минуты, таймаут».

Как это разрулить?

Vit ★★★★★
() автор топика

Надо дешево и сердито - простота важнее

У тебя очень странные представления о простоте. Городить распределенную конструкцию из соплей и палок это конечно дешево и сердито.

Пара вопросиков. Зачем нужна распределенность? Почему шедулер и экзекьютор не сделать двумя строчками в кроне?

bj
()
Ответ на: комментарий от Vit

Тут другой момент - а что если на серверах часы сбились?

ntpd же. пускай каждый компонент решает свою задачу.

dib2 ★★★★★
()
Ответ на: комментарий от Vit

еще можно вокруг EXPIRE в редиске покрутить (т.е. чтобы решение о таймауте принимала редиска)

dib2 ★★★★★
()
Последнее исправление: dib2 (всего исправлений: 1)

детализируй политики выполнения задачи и что и как можно с ней делать при отклонении от нормативов

Например: в случае превышения лимита рестарт ждать прибить приостановить остановить заморозить т. е. формализовать все возможные состояния и предусмотреть реакции, а в случае перегрузки системы можно по описаниям задач выполнить те, которые допускают выполнение с опозданиями. По сути задача должна реализовывать некие ооп-интерфейсы, чтобы шедуллер мог эффективнее взаимодействовать с задачей.

Интересная задача, можно сильно заморачиваться с ней лучше найти как можно простое дешевое и надежное решение.

anonymous
()
Ответ на: комментарий от anonymous

Полностью проработанное ТЗ я выдать не готов. Пока только в общих чертах, в первом посте.

Задач, которые могут реально перегрузить все ресурсы у меня нет. Они все вспомогательные. Основное - это все-таки отдача веб-страничек.

Бывают просто вещи, которые зависят не от меня. Например, проверить размеры картинок, вставленных в пост, и слишком толстые заменить на ссылки. Там могут случиться непредсказуемые таймауты. Но наверное это можно на уровне самой задачи разрулить, чтобы не усложнять.

Меня интересует чисто практическая сторона вопроса. Чтобы имплементация была «встроенной библиотекой». То есть, чтобы на продакшен можно было раскатывать однотипные образы инстансов, без лишней конфигурации.

В качестве шареного ресурса для локов есть редис и монга.

Навороты вроде собственных мультимастеров с кворумами не нужны. Все в пределах одной стойки. Если сетка именно засплитится, то вариант с полным остановом задач меня устроит. Детектится просто - кто потерял доступ к редисовском мастеру или к кворуму монги, тот ждет.

Больше 3 физических серверов точно не будет еще несколько лет. Ну а потом можно будет еще много раз все переделать. Сейчас мне нужна именно простота исполнения и простота использования.

Все что я видел готового - слишком ынтырпрайзно, выделенные сервисы. А конкретно из пакетов под ноду - слишком убого. Поэтому пытаюсь понять общую логику, чтобы сделать свой лисапед, но максимально простой.

Vit ★★★★★
() автор топика
Последнее исправление: Vit (всего исправлений: 1)
Ответ на: комментарий от Vit

причем тут тз?

ты слишком зашедулился ;)

три машинки равноправные так что каждая может брать задачи и выполнять роль планировщика

завершение задачи не входит как-бы в обязанности планировщика - только прибить

anonymous
()
Ответ на: комментарий от Vit

библиотечка это интерфейс к RPC REST

только что толку от библиотечки если придется ждать результатов

это уже контейнерная перевозка получается...

anonymous
()
Ответ на: комментарий от Vit

может нода не подходит для таких задач?

есть другие хорошие платформы...

anonymous
()
Ответ на: комментарий от anonymous

Ну как-то так. Просто хотелось бы, чтобы не было явного выделения роли планировщика. Все три работают параллельно, а коллизии разруливают за счет атомарных операций редиса или монги.

Если быть точнее, то на каждом сервисе не один нодовский инстанс, а 4-6 (по количеству ядер). Можно в принципе вытащить эту логику в мастер-процесс, но не хочется. Мне просто интересно сделать полностью симметричную систему. Ведь без разницы, разруливать локи между процессами на разных серверах или на одном.

Vit ★★★★★
() автор топика
Ответ на: комментарий от anonymous

Не так. У меня УЖЕ есть куча запущенных нодовских процессов. Они загружены далеко не полностью, поэтому не будет большой беды, если помимо отдачи страничек они будут выполнять кроновские задачи.

У меня нет долгоиграющих задач (транскодить видео), непрерывно жрущих CPU. Даже если надо перестроить 10.000.000 постов из маркдауна, это нарезается на слайсы по 10-100 постов, и юзеры не заметят лагов.

Именно поэтому я хочу встроенную реализацию. Это конечно не ынтырпрайзно и не мегауниверсально, зато намного проще в использовании и не требует каких-то специальных настроек. Просто конкретно сейчас нет смысла усложнять систему (нода + редиска + монга).

Vit ★★★★★
() автор топика
Последнее исправление: Vit (всего исправлений: 1)
Ответ на: комментарий от Vit

все равноправные ноды

некоторая аналогия торентов

коллизии решаются локами

лочить интересно как бы вперед а не по текущему времени

если не может выполнить отдает обратно

anonymous
()
Ответ на: комментарий от anonymous

В общих словах-то все и так понятно. Но есть некоторые прикладные моменты. Например, как избежать коллизий со снятием задач, если на одном из серверов сбились часы.

Помогите с логикой «распределенного» крона (комментарий)

Понятно, что у часов будет синхронизаций. Но сейчас меня интересует именно логика. Ну вот просто интересно, можно ли сделать «красиво».

Vit ★★★★★
() автор топика
Ответ на: комментарий от Vit

со временем есть сложности, лучшая проверка архитектуры работа в условиях перехода на зимнее или летнее время

Атомную точность не сделаешь ntp как вариант но не очень надежно

самое надежное свой отсчет но остается проблема синхронизации отсчетов

однозначного решения нет

anonymous
()
Ответ на: комментарий от anonymous

https://github.com/ncb000gt/node-cron отдельно пакет, который пуляет события с учетом магии времени есть.

Если таймстампы в UTC, то при учете задержек локальное время пофик. А вот чего с таймаутами при рассинхронизации делать - ХЗ.

В конечном счете можно забить, т.к. ntpd хватит. Но интересно разобраться. Конечно без упорина типа самописной синхронизации через редис/монгу, это уже перебор будет.

Vit ★★★★★
() автор топика
Ответ на: комментарий от Vit

Vit, ты походу хороший мужик. Не знаю пригодится ли - но я со своей колокольни вижу так: - ты сказал что редиска общая; - ты сказал что если клиент потерял редиску (сеть сплитанулась) - он сливается и ждёт пока оно не починится; - ntpd на сервера запрещает ставит Ктулху великий и ужасный;

Тогда решение - использовать время с редиски. Для всего. С каким бы локальным временем не приперся клиент - брать локальное редисочное. 8-)

Удачи, Ы.

anonymous
()
Ответ на: комментарий от anonymous

Сенькс! ntpd будет обязательно. Дополнительная логика - просто из желания решить логическую задачу.

До меня вчера тоже допёрло, что если имеется «общий» узел для блокировок, то и часы на нем тоже получатся «общими». А если еще кроме метки из общих часов сделать чтобы воркеры апдейтили метку watchdog, то будет легко определить, задача просто тупит, или загнулась.

Вчера прикинул, чего будет если редис и монга начнут из-за сбоев мастера переизбирать. В принципе возможны аварийные стопы и дубли, но они быстро сами рассосутся. Для моих задач это не критично. И это надо чтобы одновременно и часы уплыли, и коррекция навернулась и сеть заглючила.

Остается добавить немного рандома к интервалам проверки, что в очередь попали новые задачи, они раскидаются равномерно по не занятым процессам.

Vit ★★★★★
() автор топика
Последнее исправление: Vit (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.