Как организовать отказоустойчивую распределённую обработку заданий?
Всем привет
Я занимаюсь написанием дата-майнера, который должен с определёнными интервалами собирать и обрабатывать данные из разных источников. При этом у разных источников могут быть разные интервалы - от одной минуты до двух часов.
Как мне видится эта задача: будет какой то центральный воркер, который будет знать откуда и с какой периодичностью брать задания. В нужные моменты времени он будет создавать задания и добавлять их в очередь. Вспомогательные воркеры ничего не знают о периодичности, они лишь следят за очередью, берут и выполняют задания из неё. Если воркер упадёт, то команда не заметит потери бойца - другие воркеры продолжат работать. Всё верно, или такие задачи решаются иначе?
И у меня есть еще вопрос - как хранить задания? Пока видится табличка в базе данных ms sql, в которую главный воркер будет добавлять задания, а другие - будут брать строки с заданиями. Но не совсем понятно, можно ли сделать появление заданий событийным, а не чтобы каждый воркер с интервалом проверял базу данных?
Еще вопрос, если воркер попытается взять данные, поставит лок на таблицу, чтобы другие кто то другой параллельно не взял задание, и при этом упадёт, то лок так и останется висеть, как с этим бороться?
Можно ли эту задачу решить так, чтобы задание упавшего воркера не исчезло вместе с ним? Чтобы это задание смог взять другой воркер? Для этого мне видится следующий вариант - сделать в табличке поле "начало решения задачи", в которую поместить время, когда задача была взята. И если время станет слишком старым (например, спустя минуту), то другой воркер возьмёт себе это задание, и обновит поле "начало решения задачи".
Если написал глупостей, не смейтесь, никогда раньше таких систем не писал) Лучше подскажите как это делают серьёзные люди в серьезных местах)
p.s. Использую C#, хостинг бд - MS SQL в Azure. Для решения могу использовать любые инструменты, которые даёт ажур.
1. Зачем вам база данных если все делается в одном приложении. В БД сохраняйте только при закрытии приложения и считывайте единожды при запуске.
2. Сделайте менеджер заданий, пусть он потокам отдает новые, если новый нет то потоки повесить на ожидание ивента. Пришло что-то выставили ивент в сигнальное состояние. Потоки запустились. Отмечать выполнение задания тамже. Пока задание выполняется можно сохранить обьект на поток в котором задание выполняется. Если поток аварийно завершиться, то менеджер сможет проверить состояние потока через thread.Join(10). Поток мертв, скидываем флаг задания.
Андрей: Так все также и будет, только раскиданное по процессам. Один процесс-манеджер, к которому все будут обращаться и получать задания. Также раз в минуту или пол минуты передавать свой статус, что мол жив. Нет статуса за 1-2 минуты, значит пал смертью храбрых, задание другому.