AMQP: подтверждение и предварительная выборка

Я пытаюсь разобраться в некоторых аспектах протокола AMQP. В настоящее время у меня есть проект с RabbitMQ и использую библиотеку python pika. Итак, вопрос касается подтверждения и предварительной выборки сообщений.

  1. Предположим, у нас есть очередь только с потребителем (наверняка эта очередь объявлена ​​эксклюзивной). Итак, я правильно понимаю: независимо от того, потребляю ли я с флагом подтверждения или без него? В любом случае я не смогу обрабатывать несколько сообщений одновременно, и нет других потребителей, которые могли бы принять некоторые из других сообщений, все еще находящихся в очереди. Еще лучше не включать подтверждение, потому что, возможно, это может снизить нагрузку на сервер AMQP.

  2. Счетчик предварительной выборки ничего не значит, если нет подтверждения. Верный?

  3. Я не уверен, как работает предварительная загрузка. У меня есть обратный вызов для нового сообщения, и в его заявлении finally я подтверждаю или отклоняю сообщение. Это единственная функция, независимо от того, насколько большим будет счетчик предварительной выборки - в любом случае другое сообщение не будет обработано до тех пор, пока не будет завершено текущее. Так зачем мне менять значение prefetch_count?

заранее спасибо.


person Serge    schedule 08.02.2014    source источник


Ответы (1)


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

И да, для autoack неустановленного значения требуется более простая логика брокера, поэтому он использует меньше ресурсов.

Что касается prefetch countprefetch size), эти параметры сообщают брокеру, насколько велика может быть полезная нагрузка, которая отправляется клиенту заранее в одно сообщение. Обычно он используется для экономии времени на сетевых операциях при ожидании нового сообщения. Когда prefetch size используется, клиент получит одно или несколько сообщений с общим размером, равным или меньшим предварительно установленному размеру предварительной обработки (и / или счетчику, который меньше).

Применяются оба правила prefetch count и prefetch size, если они установлены. Когда один из них установлен в ноль (не установлен), он не будет применяться.

Самая важная вещь: предварительная выборка определяет поведение для отправки сообщений перед тем, как клиент распаковал еще одно сообщение.

Вместе эти два параметра дают примерно следующее:

Предварительная загрузка с ограничением количества сообщений и предварительная отправка сообщений:

Условия:

  • Очередь: N сообщений x 1 КБ
  • Предварительная выборка: prefetch-size=5kb, prefetch-count=4
  • Автоупаковка: off

Рабочий процесс:

  • Брокер отправляет клиенту 4 сообщения (ограничено prefetch-count=4). 4 сообщения будут помечены как неподтвержденные и удалены из очереди (поэтому они не будут доставлены другим клиентам).
  • Клиент подтверждает 1 сообщение.
  • Брокер имеет -1 сообщение без упаковки (удалите это сообщение) и отправляет еще 1 сообщение клиенту (+1 не подтверждено, -1 из очереди, в то время как у клиента уже есть 3 сообщения без подтверждения).
  • Клиент подтверждает оставшиеся 3 сообщения + новое доставленное.
  • Брокер имеет -4 сообщения без подтверждения и отправляет 4 сообщения снова, +4 без подтверждения, -4 из очереди.
  • Клиент подтверждает 1 сообщение и терпит неудачу.
  • Брокер будет не подтвержден -1, а затем переместит остальных в очередь обратно, так что -3 не подтверждено и +3 очереди, чтобы они могли быть снова доставлены этому или другому клиенту.

Предварительная загрузка при больших сообщениях.

Условия:

  • Очередь: 1 сообщение x 5 КБ, N сообщений x 1 КБ
  • Предварительная выборка: prefetch-size=5kb, prefetch-count=2
  • Автоупаковка: off

Рабочий процесс:

  • Брокер отправляет 1 сообщение (ограничено prefetch-size=5kb) клиенту, и это сообщение помечается как неподтвержденное.
  • Клиент подтверждает 1 сообщение.
  • У брокера -1 сообщение не подтверждено, отправьте 2 сообщения еще раз (ограничено prefetch-count=2, обратите внимание, что только первое сообщение было 5 КБ, остальные - 1 КБ), и эти сообщения помечены как неподтвержденные.
  • Клиент подтверждает 1 сообщение и терпит неудачу.
  • Брокер переместит подтвержденное сообщение из очереди сообщений, а остальные неподтвержденные сообщения снова будут перемещены в очередь, к которой они принадлежат, так что они могут быть снова доставлены этому или другому клиенту.

С автоматическим подтверждением:

Условия:

  • Очередь: N сообщений x 1 КБ
  • Предварительная выборка: prefetch-size=5kb, prefetch-count=10
  • Автоупаковка: on

Рабочий процесс:

  • Хотя и prefetch-size, и prefetch-count игнорируются, если для no-ack установлено значение true (именно так функция автоматического подтверждения вызывается в RabbitMQ и в документах AMQP), сообщения будут отправляться клиенту одно за другим и удаляться из очереди после успешной отправки.

Обратите внимание, что AMQP имеет асинхронную архитектуру, поэтому при определенных условиях два клиента МОГУТ получать одно сообщение одновременно. Также неподтвержденное сообщение МОЖЕТ быть доставлено тому же клиенту обратно (особенно, если у вас один клиент).

Также посмотрите prefetch-size и официальная документация prefetch-count и немного поэкспериментируйте с этими вариантами.

P.S .: autoack в основном no-ack флаг AMQP установлен на true.

person pinepain    schedule 09.02.2014
comment
Отличный ответ, спасибо за примеры! Итак, правильно ли я понял: хотя клиент не может одновременно обрабатывать более 1 сообщения из очереди, он может предварительно выбрать некоторые сообщения (ограниченные числом и / или размером) в каком-то кеше, чтобы иметь к ним быстрый доступ (не ждать их от сервера)? Кажется, это реализовано внутри библиотеки AMQP и прозрачно для пользователя, поэтому я работаю с предварительной выборкой так же, как и без нее. - person Serge; 11.02.2014
comment
В случае отсутствия автоматической упаковки, как брокер узнает, сколько потребитель обработал? В вашем примере вы упомянули, что обрабатываются 3 сообщения, а затем брокер отправляет еще два. Не могли бы вы объяснить это еще раз? - person Akash Jain; 13.06.2015
comment
@AkashJain, в моем ответе было несколько ошибок, stackoverflow.com/posts/21662129/revisions, должны быть исправлены сейчас. Приносим извинения за неудобства. - person pinepain; 14.06.2015
comment
@Serge Клиент может обрабатывать несколько сообщений «одновременно», т.е. с нитками. Это требует большей координации и индивидуального отслеживания сообщений, но это вполне возможно. Единственное ограничение состоит в том, что это клиент читает сообщения с начала очереди ... оттуда до клиентских ACK / NACK / DCs, это ответственность клиента. - person user2864740; 14.09.2017