Параллелизм в Функциях Azure

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

Внимание

План потребления Flex в настоящее время находится в предварительной версии.

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

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

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

Функции предоставляют два основных способа управления параллелизмом:

Статический параллелизм

По умолчанию большинство триггеров поддерживают статическую модель конфигурации уровня узла. В этой модели каждый тип триггера имеет ограничение параллелизма для каждого экземпляра. Однако для большинства триггеров можно также запросить определенное параллелизм для каждого экземпляра для этого типа триггера. Например, у триггера служебной шины есть как параметр MaxConcurrentCalls, так и параметр MaxConcurrentSessions в файле host.json. Эти параметры вместе управляют максимальным количеством сообщений, которые каждая функция одновременно обрабатывает на каждом экземпляре. У других типов триггеров есть встроенные механизмы балансировки нагрузки вызовов между экземплярами. Например, Центры событий и Azure Cosmos DB используют схему на основе секционирования.

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

Параллелизм триггера HTTP

Применяется только к плану потребления Flex (предварительная версия)

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

Размер экземпляра (МБ) Параллелизм по умолчанию*
2048 16
4096 32

*Для приложений Python параллелизм триггера HTTP по умолчанию для всех размеров экземпляров имеет значение 1.

Эти значения по умолчанию должны работать хорошо в большинстве случаев, и вы начинаете с них. Учитывайте, что при заданном количестве HTTP-запросов увеличение значения параллелизма HTTP уменьшает количество экземпляров, необходимых для обработки HTTP-запросов. Аналогичным образом уменьшение значения параллелизма HTTP требует больше экземпляров для обработки той же нагрузки.

Если вам нужно точно настроить параллелизм HTTP, это можно сделать с помощью Azure CLI. Дополнительные сведения см. в разделе "Настройка ограничений параллелизма HTTP".

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

Определение оптимальной статической параллелизма

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

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

Динамический параллелизм

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

Примечание.

Динамический параллелизм в настоящее время поддерживается только для триггеров BLOB-объектов Azure, очереди Azure и Служебной шины и требует использования версий, перечисленных в разделе поддержки расширений ниже.

Льготы

Применение динамического параллелизма обеспечивает перечисленные ниже преимущества.

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

Конфигурация динамического параллелизма

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

По умолчанию динамический параллелизм отключен. Когда динамический параллелизм включен, начальное значение параллелизма для каждой функции равно 1, и оно корректируется до оптимального уровня, зависящего от узла.

Вы можете включить динамический параллелизм в приложении-функции, добавив следующие параметры в файл host.json:

    { 
        "version": "2.0", 
        "concurrency": { 
            "dynamicConcurrencyEnabled": true, 
            "snapshotPersistenceEnabled": true 
        } 
    } 

Если SnapshotPersistenceEnabled равно true (это значение по умолчанию), определенные значения параллелизма периодически сохраняются в хранилище, и новые экземпляры начинают работу именно с этих значений, а не с 1 с последующим повторным обучением.

Диспетчер параллелизма

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

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

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

Поддержка расширений.

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

Расширение Версия Description
Хранилище очередей версия 5.x (расширение служба хранилища) У триггера хранилища очередей Azure есть собственный цикл опроса сообщений. При использовании статической конфигурации параллелизм регулируется параметрами конфигурации BatchSize/NewBatchThreshold. В режиме динамического параллелизма эти значения конфигурации игнорируются. Динамический параллелизм интегрируется в цикл обработки сообщений, поэтому количество сообщений, получаемых в каждой итерации, корректируется динамически. При включении регуляторов (перегрузке узла) обработка сообщений приостанавливается до момента их отключения. При отключении регуляторов параллелизм увеличивается.
Хранилище BLOB-объектов версия 5.x (расширение служба хранилища) На внутреннем уровне триггер хранилища BLOB-объектов Azure использует ту же инфраструктуру, что и триггер очереди Azure. При обработке новых или обновленных BLOB-объектов сообщения записываются в управляемую платформой очередь управления, и эта очередь обрабатывается с применением той же логики, что и для триггера очереди. Когда включен динамический параллелизм, управление параллелизмом для обработки этой очереди управления осуществляется динамически.
Служебная шина версия 5.x Сейчас триггер служебной шины поддерживает три модели выполнения. Динамический параллелизм затрагивает эти модели выполнения следующим образом:

Одна обработка раздела или очереди отправки: каждое вызов функции обрабатывает одно сообщение. При использовании статической конфигурации параллелизм регулируется параметром MaxConcurrentCalls конфигурации. При использовании динамического параллелизма это значение конфигурации игнорируется, а параллелизм корректируется динамически.
Обработка отдельных разделов или очередей на основе сеанса: каждый вызов функции обрабатывает одно сообщение. В зависимости от количества активных сеансов для раздела или очереди каждый экземпляр арендует один или несколько сеансов. Сообщения в каждом сеансе обрабатываются последовательно, чтобы гарантировать определенный порядок в сеансе. Если динамическое параллелизм не используется, параллелизм регулируется параметром MaxConcurrentSessions . Если динамический параллелизм включен, параметр MaxConcurrentSessions игнорируется, а количество сеансов, обрабатываемых каждым экземпляром, корректируется динамически.
Пакетная обработка: каждый вызов функции обрабатывает пакет сообщений, управляемый параметром MaxMessageCount . Поскольку пакетные вызовы осуществляются последовательно, параллелизм для функции с пакетной активацией всегда работает на уровне 1, а динамический параллелизм не применяется.

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

Дополнительные сведения см. на следующих ресурсах: