Обработка сообщений с циклическим перебором с помощью SQS (или других решений mq в AWS) - PullRequest
0 голосов
/ 19 марта 2020

Контекст

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

В настоящее время для планирования чанков я использую очередь SQS, поэтому при создании задания я сбрасываю все чанки в очередь SQS, и рабочие берут чанки. Он работает как FIFO.

Итак, чтобы подвести итог, что делает, что:

A job - это много ресурсоемких вычислений. Он состоит из нескольких независимых блоков, которые имеют примерно одинаковый размер.

A chunk - это вычисление с интенсивным использованием процессора, с которым могут работать работники. Независимо от других блоков и может быть вычислен сам без дополнительного контекста.

Сервер создает задания. Когда задание создано, сервер помещает все чанки задания в очередь (и, по существу, забывает о заданиях).

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

Проблема

Когда все задания запланированы чанки добавляются в очередь, и когда запланировано следующее задание, оно не будет запущено до тех пор, пока не будет выполнено первое задание. Таким образом, в сценарии, где задание A (первое) занимает 4 часа, а задание B (второе) занимает 5 минут, задание B не запустится в первые несколько часов и будет только завершается примерно через 4 часа 5 минут, поэтому, если запланировано большое задание, оно эффективно заблокирует все остальные вычисления. Очередь будет выглядеть следующим образом:

A1 A2 A3 A4 A5 A6 A7 A8 A9 A9 ... A100 B1 B2

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

A1 B1 A2 B2 A3 A4 A5 A6 A7 A8 A9 A10 ... A100

Если третья работа поступает после того, как A1 и B1 были получены, она должна не блокируется:

A2 B2 C1 A3 C2 A4 C3 A5 C4 A6 A7 A8 A9 A10 ... A100

При заказе таких кусков я могу гарантировать следующее:

  1. Для каждой работы первое задание выбирается относительно быстро.
  2. Для каждой работы наблюдается постоянный ощутимый прогресс (некоторые новые куски всегда завершаются)
  3. Короткие работы (не много фрагменты) заканчиваются относительно быстро.

Решения

Я знаю, что не могу переупорядочить очередь SQS сама по себе, поэтому мне, возможно, придется сделать что-то вроде:

  1. Изменение технологий. Может быть, какая-то очередь поддерживает это "из коробки" в AWS
  2. Когда планируется запланировать новое задание, сервер просто берет все порции из очереди, перемешивает в новых порциях, возвращает все в queue.
  3. Каким-то образом достичь желаемого поведения с помощью приоритетной очереди (возможно, RabbitMQ).

Есть ли какое-то простое и безопасное решение для этого? как мне это сделать?

...