2012-01-16 2 views
1

У нас есть веб-приложение, которое использует IMAP для условного вставки сообщений в почтовые ящики пользователей в определенные пользователем моменты времени.Лучшее решение для запуска нескольких интенсивных заданий в определенное время

Каждое из этих «заданий» хранится в БД MySQL с отметкой времени, когда должно выполняться задание (могут быть месяцы в будущем). Работы могут быть отменены пользователем в любое время.

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

В настоящее время у нас есть система, в которой у нас есть скрипт cron, работающий каждую минуту или около того, что получает все задания из БД, которые необходимо доставить в следующие X минут. Затем он разбивает их на партии заданий Z, и для каждой партии выполняет асинхронный запрос POST обратно на тот же сервер со всеми данными для этих заданий Z (для достижения «поддельной» многопоточности). Затем сервер обрабатывает каждую партию Z-заданий, которые поступают через HTTP.

Причина, по которой мы используем async HTTP POST для многопоточности, а не что-то вроде pnctl_fork, так это то, что мы можем добавлять другие серверы и вместо них использовать POST-данные вместо них, а также запускать задания, а не текущий сервер.

Так что мой вопрос - есть ли лучший способ сделать это?

Я ценю работу очереди, как beanstalkd доступны для использования, но они подходят модели, имеющие для выполнения заданий в определенное время?

Кроме того, поскольку нам нужно поддерживать задания в БД в любом случае (потому что нам нужно предоставить пользователям пользовательский интерфейс для управления заданиями), добавив рабочую очередь там, где-то на самом деле нужно добавлять дополнительные накладные расходы, а не уменьшать Это?

Я уверен, что есть более эффективные способы достижения того, что нам нужно - любые предложения будут высоко оценены!

Мы используем PHP для всего этого, поэтому решение на основе PHP/совместимое решение действительно то, что мы ищем.

+0

Лучше, каким образом? Вы можете указать, что именно вам не нравится в текущей настройке. – Ranty

+0

Похоже, вы делаете вещи относительно разумно. Часто для максимальной масштабируемости будет наилучшим решением, ориентированное на обслуживание архитектуры (SOA), что, по-вашему, похоже на то, что вы делаете с публикацией через HTTP на другие серверы. См .: http://en.wikipedia.org/wiki/Service-oriented_architecture –

+0

Добавленные накладные расходы HTTP-запросов кажутся мне расточительными, и мне было интересно, есть ли лучший способ добиться того же результата (т.е. распространить обработку загрузка через серверы). Также мы разделяем текущие ожидающие задания на партии заданий Z, но этот номер z довольно произволен и не реагирует на фактическое использование памяти или время, затрачиваемое на выполнение процессов. Но на самом деле я просто хочу проверить, что это не сумасшедший способ делать вещи и что я не пропустил гораздо более простой или более эффективный способ сделать это! :-) –

ответ

0

Beanstalkd был бы разумным способом сделать это. Он имеет концепцию put-with-delay, поэтому вы можете регулярно заполнять очередь из вашего основного хранилища сообщением, которое можно зарезервировать и запустить, в X секундах (время, когда вы хотите запустить - время).

Рабочие будут работать в обычном режиме, подключаясь к демону beanstalkd и ожидая сохранения нового задания. Это также было бы намного более эффективным без накладных расходов на HTTP-соединение. В качестве примера я публиковал сообщения в Amazon SQS (по http). Это едва ли могло сыграть 20 QPS, но Beanstalkd принимал более тысячи в секунду без каких-либо усилий.

Отредактировано для добавления: Вы не можете удалить вакансию, не зная ее идентификатора, хотя вы можете сохранить ее на улице. OTOH, пользователи должны иметь возможность удалять задания в любое время и в последнюю минуту? Вам не нужно ставить задание в очередь за недели или месяцы заранее, и поэтому у вас будет только один DB-ридер, который будет запускать каждый, скажем, от 1 до 5 минут, чтобы поставить следующие несколько заданий в очередь, и все еще есть столько работников, сколько вам нужно, с эффективностью, которую они могут принести.

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

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

+0

Работники Beanstalkd обычно запускались из командной строки в цикле, а не по HTTP-запросу. У меня есть несколько сообщений об использовании на http://www.phpscaling.com/tag/beanstalkd/ –

+0

Проблема с использованием beanstalkd, которая делает его непригодным для нашего использования (насколько я вижу), заключается в том, что мы необходимо, чтобы пользователи могли отменить задания после их создания. Глядя на beanstalkd, похоже, нет способа отслеживать и отменять/обновлять отдельные задания, когда они находятся в очереди. Или я чего-то не хватает? –