Утешение - гарантированный заказ с горизонтальной масштабируемостью - PullRequest
2 голосов
/ 29 января 2020

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

Существует ли существующий шаблон на утешение, как решить эту проблему? Я узнал, что некоторые брокеры, такие как kafka и activemq, поддерживают это, что, указав идентификатор во время публикации, гарантирует, что все сообщения с таким идентификатором будут выстроены только для одного потребителя; Таким образом, соблюдая порядок событий.

Ответы [ 3 ]

2 голосов
/ 31 января 2020

(выдержка из моего блога, которую я еще не опубликовал)

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

Термин " группы потребителей " был популяризирован Apache Kafka, приложением доставки журналов. В Kafka группы потребителей - это группы потребителей, которые формируют «логического потребителя» для чтения из одной топи c. Потребитель в группе потребителей Kafka подключается к одному или нескольким разделам внутри topi c Kafka и читает последовательные записи журнала из файла раздела. Когда записи («сообщения») добавляются к разделу в топике Kafka c, раздел выбирается с помощью ключевого атрибута, определенного издателем.

Это обеспечивает форму « sticky load -балансирование"таким образом, что записи с одним и тем же ключом попадают в один и тот же раздел и поэтому обрабатываются одним и тем же потребителем.

Та же (и лучшая) функциональность может быть достигнута в Solace с использованием иерархической топологии Структура c и расширенные возможности фильтра topi c от Solace.

Использование разделов Solace для разбиения

При определении иерархии или таксономии topi c укажите один уровень топи c иерархия в качестве ключа раздела. Например, для системы ввода заказов ваша структура topi c может иметь вид:

estore/order/[ORDER_ID_PARTITION_KEY]/more/specific/rest/of/topic

Ключ обычно представляет собой ha sh важного атрибута опубликованных данных, так как обсуждается в главном пункте. В нашем примере ключевым атрибутом будет идентификатор заказа, большое целое число. Предположим для простоты, что ключ раздела имеет следующий вид: Идентификатор заказа по модулю 8: целое число от 0,7 до 8 возможных значений для до 8 возможных разделов.

Настройка балансировки нагрузки слипанием в Solace настройте как минимум столько же очередей, сколько число потребителей в «группе потребителей» ... скажем, две! Однако, чтобы обеспечить простое масштабирование в будущем, рассмотрите возможность настройки большего количества очередей и привязки потребителей к нескольким очередям:

enter image description here

Обратите внимание на использование многоуровневого подстановочного знака Solace > в конце подписки.

В этом примере электронного магазина, если шлюз / API клиента был расширен, чтобы разрешать различные типы событий заказа (например, new, amend, cancel) , было бы желательно, чтобы события, связанные с одним и тем же идентификатором заказа до go с одним и тем же внутренним процессором. Это будет гарантировать, что new ордер не будет получен одним процессором, а cancel будет перенаправлен на другой. Всякий раз, когда издатель генерирует событие типа «заказ», 3-й уровень топи c используется для ввода сообщения в конкретный раздел путем взятия по модулю 8 (или любого другого) идентификатора заказа.

Можно иметь очень большое количество разделов , используя этот подход, практически без изменений в архитектурном шаблоне, используя темы для определения раздела (поскольку темы и подписки в Solace "дешевы"). Это обеспечивает гибкость в будущем за счет возможности добавления большего числа потребителей в группу потребителей путем перебалансировки подписок на ключ в новом количестве очередей. Просто начните с довольно большого пространства ключей ha sh, или по модулю ... таким образом, издателю никогда не придется беспокоиться об изменении своего алгоритма ключа разделения!

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

Надеюсь, это поможет!

1 голос
/ 30 января 2020

По сути, вы ищете балансировку нагрузки: сообщения с определенным ключом назначаются одному и тому же потребителю, в то время как общие сообщения с разными ключами могут распределяться между разными потребителями. Посмотрите на этот блог моего коллеги Мата Хоббиса, в котором описано, как это можно сделать с помощью Solace PubSub +: https://solace.com/blog/sticky-load-balancing-in-solace-pubsub-event-broker/

1 голос
/ 29 января 2020

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

ActiveMQ (и JMS в целом) поддерживает идею «группировки сообщений», которую вы упоминается в вашем вопросе (где все сообщения в одной группе имеют одинаковое значение идентификатора свойства группировки). Брокер выбирает единственного потребителя для получения всех сообщений в определенной группе, чтобы сообщения обрабатывались последовательно (т.е. по порядку). Поскольку упорядочены только определенные c групп сообщений, это может позволить одновременное потребление сообщений из нескольких групп. Однако основная семантика очереди «первым пришел - первым вышел» остается в силе, поэтому, если у вас много сообщений в каждой группе или в небольшом количестве групп, ваш общий параллелизм потребителей будет все еще довольно низким и, безусловно, много ниже, чем если бы вам не нужен был заказ вообще. Несмотря на то, что я говорю здесь конкретно об ActiveMQ, для любого брокера сообщений нет никакого реального способа обойти это, поэтому то же самое применимо к Solace (при условии, что он даже поддерживает группирование сообщений в первую очередь).

...