Создайте общий планировщик заданий

Я пытаюсь создать общий планировщик заданий, чтобы расширить свои архитектурные знания и способность думать о вопросах проектирования системы в интервью. До сих пор то, что я придумал, ниже. Можете ли вы указать, где я должен работать, чтобы быть всеобъемлющим в моем подходе к решению этой проблемы?

Я прочитал много ресурсов в Интернете, но вам нужно определенное руководство для продвижения вперед.

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

Использовать случаи

Создать/прочитать/обновить/удалить задания

Изучите задания, которые были запущены в прошлое (тип работы, время, детали)

Ограничения

Сколько заданий будет выполняться в системе за секунду?

= # заданий/час из-за пользователей + # заданий/час из-за машин

= 1m * 0,5/day/24/3600 + 1m/50 * 20/24/3600

~ = 12 заданий/сек

Сколько данных система должна хранить?

Рассуждение: я только сохраняю детали выполнения задания, фактическое работа (script исполнение) выполняется > на других машинах, а некоторые из собранные данные - это время окончания, состояние успеха/отказа и т.д. Это > все, скорее всего, текст, возможно, с графикой для иллюстрации. я будет хранить данные → всех заданий, выполняемых в системе, через планировщик заданий (т.е. за последние 10 лет)

= (Размер страницы, на которой заданы детали задания + размер данных, собранных по заданию) * Количество заданий * 365 > дней * 10 лет = 1 МБ * 900 000 * 365 * 10

~ = 3600 000 000 МБ

= 3600 000 ГБ

= 3600 ТБ = 3,6 PB

Абстрактная конструкция

Основываясь на приведенной выше информации, нам не нужно слишком много машины для хранения данных. Я бы разбил дизайн на следующее:

Уровень приложения: обслуживает запросы, показывает детали пользовательского интерфейса.

Уровень хранения данных: действует как большая хеш-таблица: хранит сопоставления ключевое значение (ключевыми были бы задания, организованные dateTime, которые они запускали, в то время как значения будут показывать детали этих заданий). Это значит, что легкий поиск исторических и/или запланированных заданий.

Узкие места:

Трафик: 12 заданий/сек не слишком сложны. Если это всплески, мы можем используйте балансировщик нагрузки для распределения заданий на разные серверы для выполнение.

Данные: при 3,6 ТБ нам нужна хеш-таблица, которая может быть легко запрашивается для быстрого доступа к заданиям, выполненным в выражение.

Масштабирование абстрактного дизайна

Характер этого планировщика заданий заключается в том, что каждая работа обладает одним из несколько состояний: Ожидание, Ошибка, Успех, Прекращено. Нет бизнес-логики Возвращает небольшие данные.

Для обработки трафика мы можем иметь сервер приложений, который обрабатывает 12 запросов/сек и резервную копию, если этот сбой не выполняется. В В будущем мы можем использовать балансировщик нагрузки для уменьшения количества запросов переход на каждый сервер (при условии, что > 1 сервер находится в производстве) Преимущество из этого было бы сократить количество запросов/сервера, увеличить доступности (в случае сбоя одного сервера и обработки трафика spike-y а).

Для хранения данных, чтобы хранить 3,6 ТБ данных, нам понадобится несколько машин удерживать его в базе данных. Мы можем использовать db noSQL или SQL db. Учитывая, как последнее имеет более широкое применение и поддержку сообщества, которые помогут в вопросах устранения неполадок и используется крупными фирмами в настоящий момент, я выберет mySQL db.

По мере роста данных я бы принял следующие стратегии для обработки это:

1) Создайте уникальный индекс на хеше

2) Увеличьте mySQL db вертикально, добавив больше памяти

3) Разделите данные путем окантовки

4) Используйте стратегию репликации ведущего-подчиненного с мастер-мастером репликация для обеспечения избыточности данных

Заключение

Следовательно, это будет мой дизайн компонентов планировщика заданий.

Ответ 1

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

Некоторые из ключевых проблем: (в определенном порядке)

  • Отмена - вы часто хотите убить долгое задание или запретить запуск.
  • Приоритет - вы часто хотите, чтобы задания с высоким приоритетом выполнялись с предпочтением задания с низким приоритетом. Но, реализуя это так, что задания с низким приоритетом не ждут вечно в системе, где генерируется много заданий, является "нетривиальным".
  • Ресурсы - некоторые задания могут планироваться только в системах с определенными ресурсами. Например. для некоторых из них потребуются большие объемы памяти или быстрый локальный диск или быстрый доступ к сети. Выделение их эффективно сложно.
  • Зависимости - некоторые задания могут выполняться только после завершения других заданий и, следовательно, не могут быть запланированы до определенного времени.
  • Сроки - некоторые задания должны быть завершены к определенному времени. (или, по крайней мере, быть запущенным в заданное время.)
  • Разрешения. Некоторые пользователи могут отправлять задания только определенным группам ресурсов или определенным свойствам или определенному количеству заданий и т.д.
  • Квоты - некоторые системы предоставляют пользователям определенное количество системного времени, и выполнение задания вычитается из этого. Это может существенно повлиять на число в вашем примере.
  • Подвеска - некоторые системы позволяют задавать задания и приостанавливать работу и возобновлять их позже.

Я уверен, что есть куча больше - попробуйте просмотреть документы в slurm или grid-engine для большего количества идей.

Дальнейшие действия:

  • В вашем абстрактном дизайне, возможно, понадобится более подробная информация для поддержки этих продвинутых понятий.
  • Вам не нужно часто обращаться к большинству данных 3.6 ТБ - разделить его на последние и старые данные, и у вас будет гораздо более управляемый размер базы данных, если вы разрешите доступ к старым данным медленнее (и нажмите диск).
  • У вас, вероятно, есть разные категории пользователей, по крайней мере, "администраторы" и "пользователи". Что это означает для структуры приложения.
  • Реальное приложение планирования заданий способно обрабатывать больше запросов в секунду - slurm предлагает устойчивую 33/секунду с более высокими очередями, но я понимаю, что она может значительно превышать это.
  • Обычно требуется отправлять задания или запрашивать состояние задания через интерфейсы, отличные от веб-страницы, - что это означает для структуры вашего приложения. (Я бы использовал простой API-интерфейс для основного ядра и имел веб-интерфейс как немой переводчик, и все дополнительные методы используют один и тот же API или используют REST API с простым веб-интерфейсом)
  • Как вы обнаруживаете сбой сервера? Достаточно ли для этого достаточно двух серверов? Это общепринято для использования мер, основанных на кворуме, для этого или тестов на подключение к третьему серверу. Что вы делаете, если неудавшийся сервер возвращается в сеть?

Ответ 2

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

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

Часто предполагалось, что писать такую ​​услугу легко. Это не так.

Некоторые другие вещи, о которых нужно подумать.

Что произошло, когда сообщение завершилось с ошибкой. Заблуждается? Вы откатываете? Как вы масштабируете свою архитектуру. Можете ли вы добавить новых клиентов/потребителей легко?

Ответ 3

Значительная часть того, что вы описали, была реализована различными структурами для планирования заданий и их выполнения. Тот, о котором я знаю - Quartz. Хотя я бы реализовал несколько вещей по-разному в Quartz, он хорошо документирован и даст вам много идей о рабочих местах и ​​об обструкции, с которыми они обычно сталкиваются.

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

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

И еще один, я не вижу параллели между выполнением задания и серверами сообщений, поэтому я не комментирую в этом направлении.