Как обеспечить, чтобы сообщения с одним и тем же идентификатором человека выполнялись одноэлементно, а разные - параллельно? - PullRequest
0 голосов
/ 01 февраля 2019

У меня есть azure function, который я хочу обработать несколько сообщений в parallel, но чтобы сообщения с одинаковым Person Id выполнялись singleton.

Сценарий 1: У меня есть n количество сообщений, каждое из которых имеет одинаковый Person Id.Каждое сообщение должно быть выполнено в той последовательности, в которой оно было получено, но singleton.

Сценарий 2: У меня n количество сообщений.Некоторые из них имеют Person Id:1.Некоторые из них имеют Person Id:2.Сообщения с разными личными идентификаторами могут быть выполнены в parallel, но сообщения с одинаковыми Person Id должны выполняться в той последовательности, в которой они поступили, и singleton способом.

Как этого добиться?

Редактировать: Мое приложение работает на Consumption Plan, поэтому я не могу предсказать, как и когда мое приложение будет масштабироваться.Функция Azure изначально получает аренду для всех разделов.Похоже, что функция Azure изначально получает аренду для всех разделов, когда приложение не масштабируется.Решение, предложенное @juunas в комментариях, беспокоит меня, что мое приложение никогда не масштабируется и может закончить выполнение пакетов последовательно одним экземпляром функции Azure, потому что моя функция не будет получать миллионы точек данных последовательно.Эвристика для масштабирования под Consumption Plan не известна.

Возможно, каким-то образом объединить концентратор событий в упорядоченной гарантии с долговечными функциями параллельного шаблона?

Редактировать 2:

Рассмотрим две функции:

  1. Appender Функция: Поддерживает упорядоченный список в cache, добавляя Person Id вместе с любым другим обязательным атрибутом.Не обязательно функция Azure.
  2. Processor Функция: Использовать долговременную функцию Singleton Pattern (также может хранить информацию о Идентификаторе человека, который обрабатывается в cache)

Поток:

  1. Appender, после добавления, отправляет сообщение на queue с только Person Id в сообщении.Person Id будет использоваться как instance id, как упомянуто в документации .
  2. Processor, если экземпляр функции еще не существует, начнется выполнение определенного Person Id сообщений в кеше.
  3. Если экземпляр Processor уже существует, сообщение будет проигнорировано.

Проблема:

Сценарий, в котором Processor полностью опустошает кэшированное Person Id упорядоченное сообщение, но параллельно Appender добавляет другое сообщение до выхода Processor, поэтому новое сообщение не выполняется.Теперь кэш будет содержать 1 сообщение, необработанное, и не будет вызываться никакая функция azure для его обработки, пока Appender не добавит еще одно сообщение того же Person Id.

. Может быть, я должен использовать Durable Function Monitor Как-то по шаблону?

Редактировать 3: Другим подходом, который я рассмотрел, было использование шаблона Monitor.Вместо того чтобы игнорировать сообщение, если выполняется функция с определенным instance id, оно будет ожидать через определенные промежутки времени.Само сообщение очереди будет просто Person Id с другими его атрибутами, расположенными в упорядоченной последовательности в cache.Это гарантирует, что каждое сообщение будет выполнено в правильной последовательности (используя список, поддерживаемый в cache).Однако при использовании подхода с монитором вместе с очередью может возникнуть следующая проблема, упомянутая в примере синглтона :

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

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

1 Ответ

0 голосов
/ 06 февраля 2019

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

Эта функция Azure будет последовательно обрабатывать все рабочие элементы в очереди для этого человека.Он запросит базу данных, чтобы получить всю работу для этого человека, а не только какую-либо работу.

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

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

Я полагаю, что мета-ошибка здесь заключается в том, чтобы настаивать на решении проблемы с функциями, очередями или другими примитивами Azure.Обычная база данных (например, таблицы Azure или SQL) выполняет эту работу.

...