Масштабируемая система очередей заданий для крупномасштабного планирования задач
Сценарий:
TL;DR - Мне нужна система очередей для запуска заданий на основе будущей метки времени, а НЕ в порядке ее вставки
У меня есть база данных MySQL записей, в которой подробно описываются конкретные события, которые необходимо выполнить (которые будут состоять в основном из серии арифметических вычислений и вставки/обновления базы данных) в точной последовательности на основе временных меток. Время вставки записи и когда событие будет "выполнено", не имеет корреляции и определяется внешними факторами. Таблица также содержит второй столбец миллисекунд, который увеличивает точность синхронизации.
Эта таблица является частью "очереди" заданий, которая будет содержать записи, настроенные для выполнения в любом месте от нескольких секунд до нескольких дней в будущем, и потенциально может содержать до тысячи записей, добавляемых каждую секунду. Очередь должна анализироваться постоянно (каждую секунду?) - возможно, выполнив выбор всех временных меток, срок действия которых истек в течение этой секунды и сортировка по миллисекундам, а затем выполнение каждого события, детализированного записями.
Проблема
В настоящее время серверная часть полностью написана на PHP на сервере apache с MySQL (т.Е. стандартной архитектурой LAMP). Прямо сейчас единственный способ, который я могу придумать для достижения того, что я указал, - это написать пользовательский скрипт очереди заданий PHP, который будет выполнять синтаксический анализ и выполнение, зацикливаясь каждую секунду с использованием этого метода. Насколько мне известно, других систем трудоустройства не существует который может ставить задания в очередь в соответствии с указанной меткой времени/миллисекундой, а не временем ввода.
Однако этот метод звучит довольно неосуществимо с точки зрения процессора даже на бумаге - мне приходится выполнять огромный запрос MySQL каждую секунду и выполнять какую-то функцию для каждой полученной строки, с возможностью ее выполнения в течение секунды времени выполнения, что приведет к задержкам во времени синтаксического анализа и испортит сценарий цикла.
Я, конечно, пытаюсь создать решение, которое будет масштабируемым, если в системе будет большой трафик, и это решение с треском провалится, так как оно будет продолжать отставать по мере увеличения числа записей.
Вопросы
Я бы предпочел придерживаться стандартной архитектуры LAMP, но есть ли какая-либо другая технология, которую я могу хорошо интегрировать в стек, которая лучше приспособлена для решения того, что я пытаюсь здесь сделать?
Существует ли полностью другой метод для точного запуска события на указанную будущую дату без беспорядочной возни с постоянной проверкой очереди?
Если ни один из вышеперечисленных вариантов не подходит, есть ли лучший способ зациклить PHP-скрипт в фоновом режиме? В худшем случае я могу согласиться с длительным временем выполнения и разделить задачу между несколькими "рабочими".
Обновление
RabbitMQ был хорошим предложением, но, к сожалению, не выполняет задачу, как только она "истекает" - она должна пройти сначала встаньте в очередь и дождитесь выполнения всех предстоящих задач, срок действия которых еще не истек. Время истечения срока действия имеет широкий диапазон от нескольких секунд до нескольких дней, и очередь необходимо каким-то образом сортировать каждый раз, когда добавляется новое событие, чтобы время истечения срока действия всегда было в порядке в очереди. Насколько мне известно, в RabbitMQ это невозможно, и это тоже звучит не очень эффективно. Есть ли альтернатива или программное исправление?
1 answers
Иногда для того, чтобы квадратный колышек поместился в круглое отверстие, требуется слишком много усилий. Хотя использование MySQL для создания очередей может быть эффективным, масштабировать его становится намного сложнее. Я бы предположил, что это может быть возможностью для RabbitMQ.
В принципе, вы бы настроили очередь сообщений, в которую вы можете поместить события. Затем у вас будет архитектура "разветвления", в которой ваши работники будут обрабатывать каждую очередь. Каждый работник будет прослушивать очередь и проверять, не произошло ли конкретное событие нуждается в обработке. Я полагаю, что комбинация "Рабочих очередей" и методов "Маршрутизации", доступных в Rabbit, позволит достичь того, что вы ищете, масштабируемым и надежным способом.
Я бы представил себе систему, которая работает примерно так:
- создайте работников для прослушивания очередей, используя ключи маршрутизации, чтобы сократить количество сообщений, которые они получают
- каждый работник проверяет сообщения, чтобы узнать, нужно ли их выполнять сейчас
- если сообщение должно быть выполнено, выполните его и подтвердите - в противном случае повторно отправьте сообщение для дальнейшей обработки. Для этого доступны некоторые простые методы .
Поскольку вам нужно больше масштаба, вы добавляете больше работников. RabbitMQ чрезвычайно надежен и прост в кластеризации, а также когда вы в конечном итоге закрываете свой сервер очередей. Существуют также другие облачные системы массового обслуживания, такие как Iron.Ввод-вывод и STORMMQ