Балансировка нагрузки секций между несколькими экземплярами приложения

Чтобы масштабировать приложение обработки событий, можно запускать несколько экземпляров приложения и распределять нагрузку между собой. В более старых и устаревших версиях можно сбалансировать нагрузку между несколькими экземплярами EventProcessorHost программы и событиями проверка point при получении событий. В более новых версиях (начиная с версии 5.0) то же самое делается с помощью EventProcessorClient (.NET и Java) или EventHubConsumerClient (Python и JavaScript). При использовании событий модель разработки упрощается. Вы можете подписаться на интересующие вас события, зарегистрируя обработчик событий. Если используется старая версия клиентской библиотеки, см. следующие руководства по миграции: .NET, Java, Python и JavaScript.

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

Примечание.

Масштабирование в Центрах событий базируется на идее секционированных потребителей. В отличие от шаблона конкурирующих потребителей, секционированный потребительский шаблон обеспечивает высокий уровень масштабирования путем удаления конфликтного узкого места и упрощения сквозного параллелизма.

Пример сценария

В качестве примера рассмотрим компанию по обеспечению безопасности дома, которая отслеживает 100 000 домов. Каждую минуту она получает данные от различных датчиков, таких как датчики движения, датчики открытия дверей и окон, датчики разбития стекла и т. п., установленных в каждом из домов. Компания предоставляет веб-сайт для жителей, чтобы наблюдать за деятельностью своего дома почти в реальном времени.

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

Приложение-получатель

При проектировании потребителя в распределенной среде сценарий должен обрабатывать следующие требования:

  1. Масштаб. Создайте несколько потребителей и каждый потребитель возьмет на себя ответственность за чтение нескольких секций Центров событий.
  2. Балансировка нагрузки. Изменяйте количество потребителей динамически. Например, при добавлении нового типа датчика в каждый дом (например, детектора угарного газа) увеличивается число событий. В этом случае оператор (человек) увеличивает число экземпляров потребителя. Затем пул потребителей может перебалансировать количество секций, которыми они владеют, для распределения нагрузки на вновь добавленных потребителей.
  3. Беспрепятственное возобновление в случае сбоев. Если у потребителя (потребитель А) происходит сбой (например, работа виртуальной машины, где размещается этот потребитель, аварийно завершается), другие пользователи могут выбирать секции, принадлежащие потребителю A, и продолжать работу. Кроме того, точка продолжения, называемая контрольной точкой или смещением, должна находиться в точке пересечения, в которой произошел сбой потребителя А, или немного раньше этого.
  4. Использование событий: в то время как предыдущие три пункта имеют дело с управлением потребителем, должен быть код, чтобы использовать события и сделать с ним что-то полезное. Например, он может агрегировать их и выгружать в хранилище BLOB-объектов.

Обработчик событий или клиент-потребитель

Разрабатывать собственное решение для выполнения этих требований не нужно. Эту функциональность реализуют пакеты SDK Центров событий Azure. В пакетах SDK для .NET или Java используется клиент обработчика событий (EventProcessorClient), а в пакетах SDK для Python и JavaScript используется EventHubConsumerClient. В старой версии пакета SDK он был узлом обработчика событий (EventProcessorHost), поддерживающим эти функции.

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

Владение секцией

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

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

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

Пространство имен Центров событий Имя концентратора событий Группа потребителей Ответственный ИД раздела Время последнего изменения
mynamespace.servicebus.windows.net myeventhub myconsumergroup 3be3f9d3-9d9e-4c50-9491-85ece8334ff6 0 2020-01-15T01:22:15
mynamespace.servicebus.windows.net myeventhub myconsumergroup f5cc5176-ce96-4bb4-bbaa-a0e3a9054ecf 1 2020-01-15T01:22:17
mynamespace.servicebus.windows.net myeventhub myconsumergroup 72b980e9-2efc-4ca7-ab1b-ffd7bece8472 2 2020-01-15T01:22:10
:
:
mynamespace.servicebus.windows.net myeventhub myconsumergroup 844bd8fb-1f3a-4580-984d-6324f9e208af 15 2020-01-15T01:22:00

Каждый экземпляр обработчика событий принимает владение секцией и начинает обработку секции с последней известной контрольной точки. В случае отказа обработчика (завершения работы виртуальной машины) другие экземпляры обнаруживают отказ, проверив время последнего изменения. Другие экземпляры пытаются получить владение секциями, принадлежащими ранее неактивным экземпляром. Хранилище проверка point гарантирует, что только один из экземпляров успешно получает право владения секцией. Таким образом, в любой момент времени события из секции поступают не более чем одному обработчику.

Получение сообщений

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

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

Контрольная точка

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

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

Когда производится добавление контрольной точки, чтобы отметить событие как обработанное, в хранилище контрольных точек добавляется или обновляется запись с указанием смещения события и его порядкового номера. Частота обновления контрольной точки выбирается пользователем. Обновление после каждого успешно обработанного события может оказать негативное влияние на производительность и повысить затраты, поскольку оно каждый раз активирует операцию записи в нижележащем хранилище контрольных точек. Кроме того, создание контрольных точек после каждого события характерно для модели обмена сообщениями в очереди, для которой может быть лучше использовать очередь Служебной шины, а не концентратор событий. Идея Центров событий заключается в том, что вы получаете доставку по принципу "хотя бы раз" в масштабе. Если сделать нижележащие системы идемпотентными, будет легко производить восстановление после сбоев или перезапусков, вследствие которых одни и те же события принимаются по нескольку раз.

Следуйте этим рекомендациям при использовании Хранилище BLOB-объектов Azure в качестве хранилища проверка point:

  • Используйте отдельный контейнер для каждой группы потребителей. Вы можете использовать одну и ту же учетную запись хранения, но использовать один контейнер для каждой группы.
  • Не используйте контейнер для других компонентов и не используйте учетную запись хранения для других действий.
  • служба хранилища учетная запись должна находиться в том же регионе, в который находится развернутое приложение. Если приложение находится в локальной среде, попробуйте выбрать ближайший регион.

На странице учетной записи служба хранилища в портал Azure в разделе службы BLOB-объектов убедитесь, что следующие параметры отключены.

  • Иерархическое пространство имен
  • Обратимое удаление BLOB-объекта
  • Управление версиями

Потокобезопасность и экземпляры процессора

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

Следующие шаги

См. следующие краткие руководства.