RabbitMQ — использовать несколько очередей по приоритету

У меня есть требование обновить нашу инфраструктуру производителя/потребителя.

Текущая установка выглядит так:

  • Набор из 3 очередей с разным приоритетом (низкий, средний, высокий).
  • When one our customers generate a task (i.e Process an image):
    • The Producer add the message to the relevant queue.
    • Один из рабочих обращается к нему.

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

Предлагаемые изменения:

  • У каждого клиента (или группы) должен быть выделенный Потребитель (или группа).
  • Когда Потребители простаивают, они должны обрабатывать сообщения других клиентов.

Например, у нас есть набор сообщений:

 1. Producer: Customer1, Queue: High, Payload: {}, Created: Today 16:00:00
 2. Producer: Customer2, Queue: High, Payload: {}, Created: Today 16:00:01
 3. Producer: Customer1, Queue: High, Payload: {}, Created: Today 16:00:02
 4. Producer: Customer1, Queue: High, Payload: {}, Created: Today 16:00:03

И у нас есть следующие потребители:

1. Consumer1: Dedicated for Customer1
2. Consumer2: Dedicated for Customer1
3. Consumer3: Dedicated for Customer2

Ожидаемый результат:

1. Consumer1 will address Message#1
2. Consumer2 will address Message#2
3. Consumer3 will address Message#3
4. Message#4 Any of the Consumers can address it, since Consumer1/3 are dedicated to the given Producer and Consumer2 will be idle.

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

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

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


person eldad87    schedule 13.09.2017    source источник


Ответы (1)


Не существует формулы, которая обеспечивала бы справедливое формирование очередей для каждого типа рабочей нагрузки; Важно сколько, насколько равномерно и сколько времени занимает обработка задач. Тем не менее, я сомневаюсь, что федеративные очереди помогут в обеспечении справедливости.

Вы можете работать с очередями с приоритетом и приоритеты потребителей. В сочетании с небольшим числом prefetch можно составить расписание, соответствующее вашим потребностям. ожидания клиента.

Однако ни один из этих механизмов не будет ограничивать ваших клиентов в зависимости от используемой ими емкости; Если клиент отправляет слишком много высокоприоритетных медленных задач за короткое время, он все равно заблокирует других ваших клиентов.

Поскольку вы предполагаете, что один потребитель на клиента возможен, я понимаю, что количество клиентов не очень велико. Решением, которое следует рассмотреть, было бы наличие очередей с приоритетом для каждого клиента. Сообщения из всех этих очередей могут быть выбраны в циклическом режиме буферной очередью, которая используется несколькими рабочими процессами, как показано на этой диаграмме из связанный вопрос на SE:

в очереди

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

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

person istepaniuk    schedule 17.05.2019