Максимальный потенциальный параллелизм функции Azure, вызванный очередью служебной шины

#azure #concurrency #azure-functions #azureservicebus

#Azure #Параллелизм #azure-функции #azureservicebus

Вопрос:

Мы используем функцию Azure, которая запускается очередью служебной шины.

Host.json нашей функции выглядит следующим образом:

 {
  "version": "2.0",
  "extensions": {
    "serviceBus": {
      "prefetchCount": 0,
      "autoCompleteMessages": true,
      "maxAutoLockRenewalDuration": "00:05:00",
      "maxConcurrentCalls": 16,
      "maxConcurrentSessions": 2000,
      "maxMessages": 1000,
      "sessionIdleTimeout": "00:01:00",
      "enableCrossEntityTransactions": false
    }
  },
  "logging": {
    "applicationInsights": {
      "samplingExcludedTypes": "Request",
      "samplingSettings": {
        "isEnabled": true
      }
    },
    "logLevel": {
      "Function.Delegation.User": "Information",
      "Function": "Error"
    }
  }
}
 

У нас также есть экспоненциальная повторная попытка в случае сбоя сообщений с бесконечной повторной попыткой, поскольку мы не можем позволить себе потерять какие-либо данные:

 [FunctionName("Delegation")]
[ExponentialBackoffRetry(-1, "00:00:01", "00:01:00")]
public async Task Run([ServiceBusTrigger(DelegationConstants.PlotQueueName, Connection = "ServiceBusConnectionString", IsSessionsEnabled = true)] string myQueueItem, MessageReceiver messageReceiver, string lockToken, string messageId, ILogger log)
 

В нашем пространстве имен служебной шины есть одна очередь, которая запускает это. В очереди включены сеансы и разделы, и в настоящее время у нас есть размер 1 ГБ на 16 разделов (16 ГБ). Наш ключ раздела — это идентификатор физического устройства (IMEI на мобильном устройстве, если вы знакомы), поэтому он имеет очень широкий диапазон значений (всего в нашем имении около 55 тыс.).

Наше сообщение служебной шины создается с идентификатором сеанса ключа раздела (IMEI):

 var serviceBusMessage = new ServiceBusMessage(JsonConvert.SerializeObject(delegationMessage))
{
    SessionId = delegationMessage.PartitionKey
};
 

Каждый из наших вызовов функций занимает ~ 200-300 мс:

Продолжительность функции

Сообщения «для каждого устройства» должны обрабатываться FIFO, отсюда и сеансы. В любой момент времени нам может потребоваться до (а в будущем, возможно, и более) 1000 сообщений в секунду на многих устройствах, каждое со скоростью 200-300 мс.

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

Учитывая всю приведенную выше информацию, наша очередь служебной шины продолжает увеличиваться, что указывает на то, что, возможно, имеющейся у нас сейчас настройки служебной шины функции недостаточно для обеспечения нашей пропускной способности. Есть ли что-то, чего мне здесь не хватает, или я достиг предела параллелизма с этой конфигурацией? Наша функция работает на P1V3 и занимает ~ 45% процессора и ~ 25% памяти

Комментарии:

1. На каком уровне выполняется ваш план обслуживания приложений функций, если он премиум, сколько у вас экземпляров «всегда готовых» и установлен максимальный пакет? Если это не премиум , попробуйте создать его и использовать экземпляры always ready и посмотреть, улучшится ли это.

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

3. @AnandSowmithiran Привет. В настоящее время я запускаю 3 экземпляра S2 для запуска этого в данный момент. Я собирался попытаться переместить функцию в премиум (удалить и воссоздать, я думаю, поскольку вы не можете изменить ее после ее создания). Итак, я посмотрю, как это повлияет на это. Создание нескольких очередей — потенциальное решение, но также немного запутанное, и я бы предпочел избегать, если смогу, или, по крайней мере, использовать только в качестве последнего средства.

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

5. Если вы ожидаете, что приток будет постоянным в течение дня, вместо триггера, почему бы не выполнить массовый пакетный прием с предварительным количеством выборки, скажем, 100. Смотрите Это руководство MS