Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Пакетная служба Azure может автоматически масштабировать пулы в зависимости от определенных вами параметров, экономии времени и денег. Автоматическое масштабирование позволяет пакетной службе динамически добавлять узлы в пул при росте потребностей задачи, а также удалять вычислительные узлы по мере уменьшения требований задачи.
Чтобы включить автоматическое масштабирование пула вычислительных узлов, вы связываете пул с определенной формулой автомасштабирования. Служба пакетной обработки использует формулу автомасштабирования, чтобы определить, сколько узлов требуется для выполнения рабочей нагрузки. Эти узлы могут быть выделенными узлами или точечными узлами Azure. Batch периодически проверяет данные метрик сервиса и использует их для настройки количества узлов в пуле на основе вашей формулы и заданного вами интервала.
Вы можете включить автоматическое масштабирование при создании пула или применить его к уже используемому пулу. Система Batch дает возможность оценить формулы перед их назначением пулам и отслеживать состояние выполнения автоматических запусков масштабирования. После настройки пула с автоматическим масштабированием можно позже внести изменения в формулу.
Внимание
При создании учетной записи пакетной службы можно указать режим распределения пула, который определяет, выделяются ли пулы в подписке на пакетную службу (по умолчанию) или в вашей пользовательской подписке. Если учетная запись пакетной службы была создана с конфигурацией пакетной службы по умолчанию, то она имеет ограничение на максимальное количество ядер, которые могут использоваться для обработки. Служба пакетной обработки масштабирует вычислительные узлы только до установленного лимита ядер. По этой причине пакетная служба может не достичь целевого количества вычислительных узлов, указанных формулой автомасштабирования. Сведения о том, как просматривать и увеличивать квоты учетной записи Azure, см. в разделе Квоты и ограничения для службы пакетной обработки Azure.
Если вы создали свою учетную запись в режиме пользовательской подписки, ваша учетная запись входит в основную квоту этой подписки. Дополнительные сведения см. в разделе Ограничения виртуальных машин в статье Подписка Azure, границы, квоты и ограничения службы.
Примеры формул автомасштабирования
Формула автомасштабирования представляет собой определяемое пользователем строковое значение, которое содержит один или несколько операторов. Формула автоматического масштабирования назначается элементу autoScaleFormula пула (Batch REST) или свойству CloudPool.AutoScaleFormula (Batch .NET). С помощью этой формулы пакетная служба определяет целевое количество вычислительных узлов в пуле для следующего интервала обработки. Строка формулы не может превышать 8 КБ, может содержать до 100 операторов, разделенных точкой с запятой, а также разрывы строк и комментарии.
Вы можете рассматривать формулы автоматического масштабирования как "язык" службы Batch для автомасштабирования. Операторы формул — это свободные выражения, которые могут содержать как определяемые службой переменные, которые определяются службой Batch, так и определяемые пользователем переменные. В формулах можно выполнять различные операции над этими переменными с помощью встроенных типов, операторов и функций. Например, инструкция может принимать следующую форму:
$myNewVariable = function($ServiceDefinedVariable, $myCustomVariable);
Обычно формулы содержат несколько инструкций, выполняющих операции со значениями, полученными в предыдущих инструкциях. Например, сначала вы получите значение для variable1
, а затем передайте его в функцию, чтобы заполнить variable2
:
$variable1 = function1($ServiceDefinedVariable);
$variable2 = function2($OtherServiceDefinedVariable, $variable1);
Добавьте эти выражения в формулу автомасштабирования, чтобы получить необходимое количество вычислительных узлов. Выделенные узлы и спотовые узлы имеют собственные целевые настройки. Формула автомасштабирования может включать в себя целевое значение для выделенных узлов, целевое значение для узлов Spot или обеих типов узлов.
Целевое число узлов может быть выше, меньше или совпадает с текущим числом узлов этого типа в пуле. Пакетный процесс оценивает формулу автомасштабирования пула в определенные интервалы автоматического масштабирования. Затем она корректирует целевое количество каждого типа узлов в пуле до числа, указанного в формуле автомасштабирования в момент оценки.
Примеры формул автомасштабирования
В следующих примерах показаны две формулы автомасштабирования, которые можно настроить для работы в большинстве сценариев. Переменные startingNumberOfVMs
и maxNumberofVMs
в этих формулах можно изменять произвольным образом.
Ожидающие выполнения задачи
Если используется эта формула автоматического масштабирования, пул создается с одной виртуальной машиной. Метрика $PendingTasks
обозначает количество задач, находящихся в очереди или в состоянии выполнения. Формула находит среднее количество ожидающих задач за последние 15 минут и задает $TargetDedicatedNodes
переменную соответствующим образом. Формула гарантирует, что целевое число выделенных узлов никогда не превысит значение 25. По мере добавления новых задач пул автоматически расширяется. При завершении задач виртуальные машины высвобождаются, и формула автомасштабирования сжимает размер пула.
Эта формула масштабирует выделенные узлы, но ее можно изменить, чтобы также применять для масштабирования узлов Spot.
startingNumberOfVMs = 1;
maxNumberofVMs = 25;
pendingTaskSamplePercent = $PendingTasks.GetSamplePercent(TimeInterval_Minute * 15);
pendingTaskSamples = pendingTaskSamplePercent < 70 ? startingNumberOfVMs : avg($PendingTasks.GetSample(TimeInterval_Minute * 15));
$TargetDedicatedNodes=min(maxNumberofVMs, pendingTaskSamples);
$NodeDeallocationOption = taskcompletion;
Внимание
В настоящее время Batch сервис имеет ограничения в решении ожидающих задач. При добавлении задачи в задание она также добавляется в внутреннюю очередь, используемую пакетной службой для планирования. Если задача удаляется до ее планирования, она может оставаться в очереди, что приведет к ее учету в $PendingTasks
. Эта удаленная задача в конечном итоге будет удалена из очереди, когда пакетная служба получает возможность извлекать задачи из очереди для планирования с неактивными узлами в пуле пакетной службы.
Замещенные узлы
В этом примере создается пул, который начинается с 25 точечных узлов. Каждый раз, когда узел Spot вытесняется, он заменяется выделенным узлом. Как и в первом примере, переменная maxNumberofVMs
не позволяет увеличивать пул, добавляя больше 25 виртуальных машин. Этот пример полезен для использования виртуальных машин типа Spot, а также для обеспечения того, чтобы в течение всего времени существования пула происходило только фиксированное число прерываний.
maxNumberofVMs = 25;
$TargetDedicatedNodes = min(maxNumberofVMs, $PreemptedNodeCount.GetSample(180 * TimeInterval_Second));
$TargetLowPriorityNodes = min(maxNumberofVMs , maxNumberofVMs - $TargetDedicatedNodes);
$NodeDeallocationOption = taskcompletion;
Узнайте больше о создании формул автомасштабирования и ознакомьтесь с примерами формул автомасштабирования далее в этой статье.
Переменные
В формуле автоматического масштабирования можно использовать как служебные, так и пользовательские переменные.
Переменные, определяемые службой, встроены в службу пакетной обработки. Некоторые переменные, определенные сервисом, доступны для чтения и записи, а некоторые — только для чтения.
Пользовательские переменные — это переменные, которые определяете вы. В предыдущем примере $TargetDedicatedNodes
и $PendingTasks
являются определяемыми службой переменными, а также startingNumberOfVMs
maxNumberofVMs
являются пользовательскими переменными.
Примечание.
Служебные переменные всегда начинаются с символа доллара ($). Для определяемых пользователем переменных знак доллара является необязательным.
В следующих таблицах показаны переменные для чтения и записи и только для чтения, определенные пакетной службой.
Определяемые службой переменные для чтения и записи
Вы можете получить и установить значения этих переменных, определяемых службой, чтобы управлять количеством вычислительных узлов в пуле.
Переменная | Описание |
---|---|
$TargetDedicatedNodes | Целевое количество выделенных вычислительных узлов для пула. Указан в качестве цели, так как пул может не всегда достигать желаемого количества узлов. Например, если целевое количество выделенных узлов изменяется в результате оценки автомасштабирования до того, как пул достигнет начального целевого количества, пул может не достичь запланированного количества. Пул в учетной записи, созданной в режиме пакетной службы, может не достичь целевого объекта, если целевой объект превышает узел учетной записи пакетной службы или квоту ядра. Пул в учетной записи, созданной в режиме подписки пользователя, может не достичь целевого объекта, если целевой объект превышает квоту общего ядра для подписки. |
$TargetLowPriorityNodes | Целевое количество спот-вычислительных узлов для пула. Указан в качестве цели, так как пул может не всегда достигать желаемого количества узлов. Например, если целевое количество узлов Spot изменяется с помощью проверки автомасштабирования до того, как пул достигнет начального целевого количества, пул может не достичь ожидаемого числа. Пул может также не достичь своей цели, если цель превышает узел учетной записи Batch или квоту ядра. Дополнительные сведения о точечных виртуальных машинах см. в статье Использование виртуальных машин Spot с Batch. |
$NodeDeallocationOption | Действие, выполняемое после удаления вычислительных узлов из пула. Возможны следующие значения: - requeue: значение по умолчанию. Немедленно завершает задачи и помещает их обратно в очередь заданий для повторного запланирования. Это действие гарантирует, что целевое количество узлов будет достигнуто максимально быстро. Однако это может быть менее эффективным, так как все выполняемые задачи прерваны, а затем должны быть перезапущены. - terminate: немедленное завершение задач с удалением из очереди заданий. - taskcompletion: ожидание завершения текущих задач и последующее удаление узла из пула. Этот параметр позволяет избежать прерывания задач и повторного помещения в очередь, что приводит к потере выполненной работы. - retaineddata: ожидание очистки всех данных локальных задач, удерживаемых в узле, до удаления узла из пула. |
Примечание.
Вместо переменной $TargetDedicatedNodes
также можно использовать ее псевдоним $TargetDedicated
, Аналогично, переменная $TargetLowPriorityNodes
может быть указана с использованием псевдонима $TargetLowPriority
. Если в формуле заданы полностью именованные переменные и их псевдонимы, то значение, присвоенное полностью именованной переменной, имеет приоритет.
Определяемые службой переменные только для чтения
Можно получить значения этих определяемых службой переменных, чтобы вносить изменения с учетом метрик из пакетной службы.
Внимание
В настоящее время задачи выхода заданий не включены в переменные, которые предоставляют количество задач, такие как $ActiveTasks
и $PendingTasks
. В зависимости от формулы автомасштабирования это может привести к удалению узлов при отсутствии доступных узлов для выполнения задач выпуска задания.
Совет
Переменные, управляемые службами, с доступом только для чтения — это объекты, предоставляющие различные методы доступа к данным, связанным с каждым объектом. Дополнительные сведения см. в разделе Получение выборки данных далее в этой статье.
Переменная | Описание |
---|---|
$CPUPercent | Средний объем использования ЦП в процентах. |
$АктивныеЗадачи | Количество задач, готовых к выполнению, но еще не выполняющихся. Это включает все задачи в активном состоянии, зависимости которых удовлетворены. Все задачи, которые находятся в активном состоянии, но зависимости которых не были удовлетворены, исключаются из $ActiveTasks подсчета. Для задачи с несколькими экземплярами $ActiveTasks включает количество экземпляров, заданных для задачи. |
$ВыполняемыеЗадачи | Количество задач в процессе выполнения. |
$НезавершенныеЗадачи | Сумма $ActiveTasks и $RunningTasks . |
$УспешныеЗадачи | Количество успешно выполненных задач. |
$НеудачныеЗадачи | Количество задач, которые не удалось выполнить. |
$TaskSlotsPerNode | Количество слотов задач, которые могут использоваться для выполнения параллельных задач на одном вычислительном узле в пуле. |
$ТекущиеВыделенныеУзлы | Текущее количество выделенных вычислительных узлов. |
$ТекущиеУзлыНизкогоПриоритета | Текущее количество точечных вычислительных узлов, включая все замещенные узлы. |
$UsableNodeCount | Количество доступных вычислительных узлов. |
$PreemptedNodeCount | Количество узлов в пуле, которые находятся в приостановленном состоянии. |
Примечание.
Используется $RunningTasks
при масштабировании на основе количества задач, выполняемых в определенный момент времени, а также $ActiveTasks
при масштабировании в зависимости от количества задач, которые были поставлены в очередь на выполнение.
Типы
Формулы автомасштабирования поддерживают следующие типы:
- двойной
- doubleVec
- doubleVecList
- строка
- метка времени — составная структура, содержащая следующие элементы:
- год
- месяц (1-12)
- день (1-31)
- день недели (в формате числа; например, 1 — понедельник)
- час (в 24-часовом формате; например, 13 соответствует 13:00 или 1:00 дня)
- минута (00–59)
- секунда (00–59)
- интервал времени
- ИнтервалВремени_Ноль
- ИнтервалВремени_100нс
- ИнтервалВремени_Микросекунда
- ВременнойИнтервал_Миллисекунда
- ИнтервалВремени_Секунда
- ИнтервалВремени_Минута
- Интервал_Времени_Час
- ИнтервалВремени_День
- ИнтервалВремени_Неделя
- ИнтервалВремени_Год
Операции
Для перечисленных в предыдущем разделе типов разрешены перечисленные ниже операции.
Операция | Поддерживаемые операторы | Тип результата |
---|---|---|
double оператор double | +, -, *, / | двойной |
double оператор интервал времени | * | временной интервал |
doubleVec оператор double | +, -, *, / | doubleVec |
doubleVec оператор doubleVec | +, -, *, / | doubleVec |
timeinterval оператор double | *, / | временной интервал |
интервал времени оператор интервал времени | +, - | временной интервал |
временной_интервал оператор метка_времени | + | метка времени |
метка времени оператор интервал времени | + | метка времени |
timestamp оператор timestamp | - | временной интервал |
оператор double | -, ! | двойной |
оператор интервал времени | - | временной интервал |
double оператор double | <, <=, ==, =, =, >>! = | двойной |
string оператор string | <, <=, ==, =, =, >>! = | двойной |
timestamp оператор timestamp | <, <=, ==, =, =, >>! = | двойной |
интервал времени оператор интервал времени | <, <=, ==, =, =, >>! = | двойной |
double оператор double | &&, || | двойной |
Тестирование двойника с помощью тернарного оператора (double ? statement1 : statement2
), приводит к ненулевому значению true и нулю как false.
Функции
Эти предопределенные функции можно использовать при определении формулы автомасштабирования.
Функция | Возвращаемый тип | Описание |
---|---|---|
avg(doubleVecList) | двойной | Возвращает среднее значение всех элементов в doubleVecList. |
ceil(double) | двойной | Возвращает наименьшее целое значение не меньше двойного. |
ceil(doubleVecList) | doubleVec | Возвращает поэлементные компоненты в списке doubleVecList. |
округление вниз (double) | двойной | Возвращает наибольшее целое значение, не превышающее двойное. |
floor(doubleVecList) | doubleVec | Возвращает поэлементные компоненты в списке doubleVecList. |
len(doubleVecList) | двойной | Возвращает длину вектора, созданного из doubleVecList. |
lg(double) | двойной | Возвращает логарифм double по основанию 2. |
lg(doubleVecList) | doubleVec | Возвращает поэлементные компоненты в списке doubleVecList. |
ln(double) | двойной | Возвращает натуральный логарифм double. |
ln(doubleVecList) | doubleVec | Возвращает поэлементные компоненты в списке doubleVecList. |
log(double) | двойной | Возвращает логарифм по основанию 10 для числа типа double. |
log(doubleVecList) | doubleVec | Возвращает поэлементные компоненты в списке doubleVecList. |
максимальное значение (doubleVecList) | двойной | Возвращает максимальное значение в doubleVecList. |
min(doubleVecList) | двойной | Возвращает минимальное значение в doubleVecList. |
norm(doubleVecList) | двойной | Возвращает 2-норму вектора, созданного из doubleVecList. |
перцентиль(doubleVec v, double p) | двойной | Возвращает элемент процентиля вектора v. |
rand() | двойной | Возвращает случайное значение от 0,0 до 1,0. |
диапазон(doubleVecList) | двойной | Возвращает разницу между минимальным и максимальным значениями в doubleVecList. |
округление (double) | двойной | Возвращает ближайшее целое значение для числа двойной точности (в формате с плавающей запятой), округляя половинные случаи в сторону от нуля. |
round(doubleVecList) | doubleVec | Возвращает поэлементные компоненты в списке doubleVecList. |
std(doubleVecList) | двойной | Возвращает среднеквадратичное отклонение выборки для значений в doubleVecList. |
остановить() | Останавливает вычисление выражения автоматического масштабирования. | |
sum(doubleVecList) | двойной | Возвращает сумму всех компонентов doubleVecList. |
время(строка dateTime="") | метка времени | Возвращает метку времени для текущего времени, если параметр не передан, и метку времени для строки dateTime, если параметр передан. Поддерживаемые форматы даты и времени: W3C-DTF и RFC 1123. |
val(doubleVec v, double i) | двойной | Возвращает значение элемента с индексом i в векторе v с начальным индексом 0. |
Некоторые функции, описанные в предыдущей таблице, могут принимать список в качестве аргумента. Список значений, разделенных запятыми, — это любая комбинация типов double и doubleVec. Например:
doubleVecList := ( (double | doubleVec)+(, (double | doubleVec) )* )?
Значение doubleVecList перед оценкой преобразуется в одно значение doubleVec. Например, если v = [1,2,3]
, то вызов avg(v)
эквивалентен вызову avg(1,2,3)
. Вызов avg(v, 7)
эквивалентен вызову avg(1,2,3,7)
.
Метрики
При определении формулы можно использовать как метрики ресурсов, так и задач. Вы регулируете целевое количество выделенных узлов в пуле на основе данных метрики, которые вы получаете и оцениваете. Дополнительные сведения о каждой метрии см. в разделе "Переменные ".
Метрика | Описание |
---|---|
Ресурс | Метрики ресурсов основаны на использовании ресурсов ЦП, памяти и пропускной способности вычислительных узлов, а также количестве узлов. Для внесения изменений с учетом количества узлов используются следующие служебные переменные: - $TargetDedicatedNodes - $TargetLowPriorityNodes - $CurrentDedicatedNodes - $CurrentLowPriorityNodes - $PreemptedNodeCount - $UsableNodeCount Эти определяемые службой переменные полезны для корректировки на основе использования ресурсов узла: - $CPUPercent |
Задача | Метрики задач основаны на состоянии задач (активные, ожидающие и завершенные). Следующие определяемые службой переменные полезны для корректировки размера пула на основе метрик задач: - $ActiveTasks - $RunningTasks - $ОжидающиеЗадачи - $ВыполненныеЗадачи - $НеудачныеЗадачи |
Получение выборки данных
Основная операция формулы автомасштабирования — получение данных метрик задач и ресурсов (примеров), а затем настройка размера пула на основе этих данных. Поэтому важно иметь четкое представление о том, как формулы автоматического масштабирования взаимодействуют с выборками.
Методы
Формулы автомасштабирования обрабатывают выборки метрической информации, предоставляемых службой Batch. Формула увеличивает или сжимает вычислительные узлы пула на основе получаемых значений. Определяемые службой переменные — это объекты, предоставляющие методы для доступа к данным, связанным с этим объектом. Например, следующее выражение иллюстрирует запрос для получения данных об использовании ЦП за последние пять минут.
$CPUPercent.GetSample(TimeInterval_Minute * 5)
Следующие методы можно использовать для получения примеров данных о определяемых службой переменных.
Метод | Описание |
---|---|
GetSample() | Метод GetSample() возвращает вектор выборок данных.Выборка представляет собой метрические данные за 30 секунд. Другими словами, выборки делаются каждые 30 секунд. Но, как отмечалось ниже, существует задержка между сбором образца и когда она доступна для формулы. Таким образом, не все примеры для заданного периода времени могут быть доступны для оценки формулой. - doubleVec GetSample(double count) : Указывает количество образцов, которые нужно выбрать из числа недавно собранных.
GetSample(1) возвращает последнюю доступную выборку. Этот метод $CPUPercent не следует использовать для таких метрик, как GetSample(1) , так как нет возможности узнать, когда была получена эта выборка. Она может оказаться свежей, но может и устареть, если в системе возникли проблемы. В таких случаях лучше использовать интервалы, как показано ниже.- doubleVec GetSample((timestamp or timeinterval) startTime [, double samplePercent]) : задает интервал времени для получения данных выборки. Также можно указать долю выборок, которые должны быть доступны в течение запрошенного интервала времени. Например, $CPUPercent.GetSample(TimeInterval_Minute * 10) вернет 20 выборок, если в журнале CPUPercent присутствуют все выборки за последние 10 минут. Если данные за последнюю минуту недоступны, этот метод вернет только 18 выборок. В этом случае $CPUPercent.GetSample(TimeInterval_Minute * 10, 95) произойдет сбой из-за того, что доступны только 90 процентов выборок, но $CPUPercent.GetSample(TimeInterval_Minute * 10, 80) будут успешными.- doubleVec GetSample((timestamp or timeinterval) startTime, (timestamp or timeinterval) endTime [, double samplePercent]) : задает интервал времени для получения данных, т. е. начало и конец получения. Как уже упоминалось выше, существует задержка между сбором образца и тем, когда он становится доступным для формулы. Эту задержку следует учитывать при использовании метода GetSample . Ознакомьтесь с GetSamplePercent ниже. |
GetSamplePeriod() | Возвращает интервал выборок, взятых из исторического набора данных. |
Count() | Возвращает общее количество образцов в истории метрик. |
HistoryBeginTime() | Возвращает метку времени самой старой доступной выборки данных метрики. |
GetSamplePercent() | Возвращает процент выборок, которые доступны для заданного интервала времени. Например, doubleVec GetSamplePercent( (timestamp or timeinterval) startTime [, (timestamp or timeinterval) endTime] ) . Так как метод GetSample завершается сбоем, то если процент возвращаемых выборок меньше указанного в параметре samplePercent , можно сначала воспользоваться методом GetSamplePercent для проверки. Затем при недостаточном количестве выборок можно выполнить другое действие без прерывания оценки автоматического масштабирования. |
Примеры
Служба Batch периодически собирает образцы метрик задач и ресурсов, чтобы сделать их доступными для формул автомасштабирования. Эти выборки записываются службой пакетной обработки каждые 30 секунд. Однако обычно существует задержка между тем моментом, когда эти выборки были записаны, и тем, когда они становятся доступными и считываются вашими формулами масштабирования. Кроме того, примеры могут не записываться для определенного интервала из-за таких факторов, как сеть или другие проблемы инфраструктуры.
Процент выборок
Когда samplePercent
передается в GetSample()
метод или вызывается GetSamplePercent()
метод, процент указывает на сравнение между общим числом выборок, записанных Batch сервисом, и количеством выборок, доступных вашей формуле автомасштабирования.
Рассмотрим 10-минутный интервал времени в качестве примера. Так как выборки записываются каждые 30 секунд в течение этого 10-минутного интервала времени, максимальное общее количество выборок, записанных пакетом, составляет 20 выборок (2 в минуту). Однако из-за внутренней задержки механизма отчетности и других проблем в Azure может быть только 15 примеров, доступных в формуле автомасштабирования для чтения. Таким образом, например, для этого 10-минутного периода вашей формуле может быть доступно только 75 процентов от общего количества записанных образцов.
Метод GetSample() и диапазоны выборок
Формулы автомасштабирования увеличивают и уменьшают размер пулов, добавляя или удаляя узлы. Так как узлы стоят вам денег, убедитесь, что формулы используют интеллектуальный метод анализа, основанный на достаточных данных. Рекомендуется использовать анализ типа трендов в формулах. Этот тип увеличивает и уменьшает ваши пулы на основе диапазона собранных выборок.
С этой целью используйте метод GetSample(interval look-back start, interval look-back end)
для возврата вектора выборок.
$runningTasksSample = $RunningTasks.GetSample(1 * TimeInterval_Minute, 6 * TimeInterval_Minute);
При вычислении приведенной выше строки пакетная служба возвращает диапазон выборок в виде вектора значений. Например:
$runningTasksSample=[1,1,1,1,1,1,1,1,1,1];
После сбора вектора примеров можно использовать такие функции, как min()
, max()
и avg()
для получения значимых значений из собранного диапазона.
Чтобы проявить дополнительную осторожность, вы можете принудительно выполнить оценку формулы так, чтобы она не удалась, если для определенного периода времени доступно менее определенного процента данных выборки. При намеренной остановке вычисления формулы вы указываете Batch прекратить её дальнейшую обработку, если указанный процент выборок недоступен. Размер пула при этом изменяться не будет. Чтобы указать необходимый процент выборок для успешного вычисления, укажите его как третий параметр в методе GetSample()
. Здесь указано, что обязательный процент выборок равен 75 %:
$runningTasksSample = $RunningTasks.GetSample(60 * TimeInterval_Second, 120 * TimeInterval_Second, 75);
Из-за возможной задержки в доступности образцов, всегда указывайте временной диапазон со временем начала, которое превышает одну минуту. Для распространения выборок через систему занимает около одной минуты, поэтому выборки в диапазоне (0 * TimeInterval_Second, 60 * TimeInterval_Second)
могут быть недоступны. Опять же, можно использовать параметр процента GetSample()
для принудительного требования определенного процента выборок.
Внимание
Настоятельно рекомендуется избегать полагаться только на GetSample(1)
в ваших формулах автомасштабирования. Это связано с тем, что, по GetSample(1)
сути, говорит пакетной службе: "Дайте мне последний пример, который вы получили, независимо от того, как давно вы получили его". Так как это только один пример, и это может быть более старый пример, он может не представлять собой более широкую картину недавней задачи или состояния ресурсов. Если метод GetSample(1)
все же используется, убедитесь, что он является частью большей инструкции, а не единственной точкой данных, от которой зависит ваша формула.
Напишите формулу авто-масштабирования
Формула автомасштабирования создается путем формирования инструкций с помощью указанных выше компонентов и объединения этих инструкций в полную формулу. В этом разделе вы создадите пример формулы автомасштабирования, которая может принимать реальные решения по масштабированию и вносить корректировки.
Сначала давайте определим требования к нашей новой формуле автомасштабирования. Формула должна выполнять следующее:
- Увеличивать целевое количество выделенных вычислительных узлов в пуле при высокой загрузке ЦП.
- Уменьшать целевое количество выделенных вычислительных узлов в пуле при низкой загрузке ЦП.
- Всегда ограничивать максимальное количество выделенных узлов на уровне 400.
- При уменьшении количества узлов не удаляйте узлы, на которых выполняются задачи. Если нужно удалить узлы, дождитесь выполнения задач на них.
Первая инструкция в формуле увеличивает количество узлов во время высокой загрузки ЦП. Вы определяете инструкцию, заполняющую определяемую пользователем переменную ($totalDedicatedNodes
) значением, равным 110 процентам текущего целевого числа выделенных узлов, но только если минимальное среднее использование ЦП за последние 10 минут превышает 70 процентов. В противном случае используйте значение текущего количества выделенных узлов.
$totalDedicatedNodes =
(min($CPUPercent.GetSample(TimeInterval_Minute * 10)) > 0.7) ?
($CurrentDedicatedNodes * 1.1) : $CurrentDedicatedNodes;
Чтобы уменьшить количество выделенных узлов при низком использовании ЦП, следующая инструкция в формуле задает ту же $totalDedicatedNodes
переменную до 90 процентов текущего целевого числа выделенных узлов, если среднее использование ЦП за последние 60 минут составило менее 20 процентов. В противном случае используется текущее значение $totalDedicatedNodes
, заполненное в инструкции, указанной выше.
$totalDedicatedNodes =
(avg($CPUPercent.GetSample(TimeInterval_Minute * 60)) < 0.2) ?
($CurrentDedicatedNodes * 0.9) : $totalDedicatedNodes;
Теперь ограничьте целевое число выделенных вычислительных узлов не более 400.
$TargetDedicatedNodes = min(400, $totalDedicatedNodes);
Наконец, убедитесь, что узлы не удаляются до завершения их задач.
$NodeDeallocationOption = taskcompletion;
Вот полная формула:
$totalDedicatedNodes =
(min($CPUPercent.GetSample(TimeInterval_Minute * 10)) > 0.7) ?
($CurrentDedicatedNodes * 1.1) : $CurrentDedicatedNodes;
$totalDedicatedNodes =
(avg($CPUPercent.GetSample(TimeInterval_Minute * 60)) < 0.2) ?
($CurrentDedicatedNodes * 0.9) : $totalDedicatedNodes;
$TargetDedicatedNodes = min(400, $totalDedicatedNodes);
$NodeDeallocationOption = taskcompletion;
Примечание.
При выборе можно включить как примечания, так и разрывы строк в строки формул. Также следует помнить, что отсутствующие точки с запятой могут привести к ошибкам оценки.
Интервал автоматического масштабирования
По умолчанию пакетная служба изменяет размер пула по указанной формуле автомасштабирования каждые 15 минут. Этот интервал можно настроить с помощью следующих свойств пула:
- CloudPool.AutoScaleEvaluationInterval (Batch .NET)
- autoScaleEvaluationInterval (REST API)
Минимальный интервал составляет пять минут, а максимальный — 168 часов. Если указан интервал за пределами этого диапазона, пакетная служба возвращает ошибку "Неправильный запрос (400)".
Примечание.
В настоящее время автоматическое масштабирование предназначено не для реагирования на изменения в течение нескольких секунд, а для постепенного изменения размера пула в ходе выполнения рабочей нагрузки.
Создать пул с поддержкой автомасштабирования с помощью SDK пакетной службы
Настройки автомасштабирования можно указать с помощью любых Batch SDK, Batch REST API, Batch PowerShell командлетов или Batch CLI. В этом разделе представлены примеры для .NET и Python.
.СЕТЬ
Чтобы создать пул с поддержкой автомасштабирования в .NET, выполните указанные ниже действия.
- Создайте пул с помощью метода BatchClient.PoolOperations.CreatePool.
- Задайте для свойства CloudPool.AutoScaleEnabled значение true.
- Задайте свойство CloudPool.AutoScaleFormula с помощью формулы автомасштабирования.
- (Необязательно.) Задайте свойство CloudPool.AutoScaleEvaluationInterval (значение по умолчанию — 15 минут).
- Зафиксируйте пул с помощью метода CloudPool.Commit или CommitAsync.
В следующем примере создается пул с поддержкой автомасштабирования в .NET. Формула автомасштабирования пула устанавливает целевое количество выделенных узлов равным 5 по понедельникам и 1 в остальные дни недели.
Интервал автомасштабирования составляет 30 минут. В этом и других фрагментах кода C#, приведенных в этой статье, myBatchClient
представляет собой правильно инициализированный экземпляр класса BatchClient.
CloudPool pool = myBatchClient.PoolOperations.CreatePool(
poolId: "mypool",
virtualMachineSize: "standard_d1_v2",
VirtualMachineConfiguration: new VirtualMachineConfiguration(
imageReference: new ImageReference(
publisher: "MicrosoftWindowsServer",
offer: "WindowsServer",
sku: "2019-datacenter-core",
version: "latest"),
nodeAgentSkuId: "batch.node.windows amd64");
pool.AutoScaleEnabled = true;
pool.AutoScaleFormula = "$TargetDedicatedNodes = (time().weekday == 1 ? 5:1);";
pool.AutoScaleEvaluationInterval = TimeSpan.FromMinutes(30);
await pool.CommitAsync();
Внимание
При создании пула с поддержкой автомасштабирования не указывайте параметр targetDedicatedNodes или параметр targetLowPriorityNodes в вызове CreatePool
. Вместо этого укажите свойства AutoScaleEnabled
и AutoScaleFormula
на пуле. Значения этих свойств определяют целевое количество каждого типа узлов.
Чтобы вручную изменить размер пула с включенным автомасштабированием (например, с помощью BatchClient.PoolOperations.ResizePoolAsync), сначала отключите автомасштабирование пула, а затем измените его размер.
Совет
Дополнительные примеры использования .NET SDK см. в репозитории Batch .NET Quickstart на GitHub.
Питон
Чтобы создать пул с поддержкой автомасштабирования с помощью пакета SDK для Python:
- Создайте пул и укажите его конфигурацию.
- Добавьте пул в клиент сервиса.
- Включите автомасштабирование для пула с использованием созданной вами формулы.
В следующем примере это показано.
# Create a pool; specify configuration
new_pool = batch.models.PoolAddParameter(
id="autoscale-enabled-pool",
virtual_machine_configuration=batchmodels.VirtualMachineConfiguration(
image_reference=batchmodels.ImageReference(
publisher="Canonical",
offer="UbuntuServer",
sku="20.04-LTS",
version="latest"
),
node_agent_sku_id="batch.node.ubuntu 20.04"),
vm_size="STANDARD_D1_v2",
target_dedicated_nodes=0,
target_low_priority_nodes=0
)
batch_service_client.pool.add(new_pool) # Add the pool to the service client
formula = """$curTime = time();
$workHours = $curTime.hour >= 8 && $curTime.hour < 18;
$isWeekday = $curTime.weekday >= 1 && $curTime.weekday <= 5;
$isWorkingWeekdayHour = $workHours && $isWeekday;
$TargetDedicated = $isWorkingWeekdayHour ? 20:10;""";
# Enable autoscale; specify the formula
response = batch_service_client.pool.enable_auto_scale(pool_id, auto_scale_formula=formula,
auto_scale_evaluation_interval=datetime.timedelta(minutes=10),
pool_enable_auto_scale_options=None,
custom_headers=None, raw=False)
Совет
Для получения дополнительных примеров использования Python SDK см. репозиторий Batch Python Quickstart на GitHub.
Включите функцию автоматического масштабирования в существующем пуле
Каждый Batch SDK предоставляет способ включения автоматического масштабирования. Например:
- BatchClient.PoolOperations.EnableAutoScaleAsync (Batch .NET)
- Включение автомасштабирования для пула (REST API)
При включении автомасштабирования в имеющемся пуле учитывайте указанные ниже условия.
- Если автомасштабирование в пуле отключено, при выполнении запроса необходимо указать допустимую формулу автомасштабирования. При необходимости можно указать интервал автомасштабирования. Если интервал не указан, используется значение по умолчанию, равное 15 минутам.
- Если в пуле включено автомасштабирование, можно указать новую формулу, новый интервал или и то, и другое. Необходимо указать по крайней мере одно из этих свойств.
- При указании нового интервала автомасштабирования существующее расписание останавливается и запускается новое расписание. Время начала нового расписания — это время подачи запроса на включение автомасштабирования.
- Если опустить формулу автомасштабирования или интервал, служба пакетной службы продолжает использовать текущее значение этого параметра.
Примечание.
Если вы указали значения параметров targetDedicatedNodes или targetLowPriorityNodes метода при создании пула в .NET или сопоставимых параметров на другом языке, то эти значения игнорируются при вычислении формулы автомасштабирования.
В этом примере на C# используется библиотека Batch .NET для включения автомасштабирования в существующем пуле.
// Define the autoscaling formula. This formula sets the target number of nodes
// to 5 on Mondays, and 1 on every other day of the week
string myAutoScaleFormula = "$TargetDedicatedNodes = (time().weekday == 1 ? 5:1);";
// Set the autoscale formula on the existing pool
await myBatchClient.PoolOperations.EnableAutoScaleAsync(
"myexistingpool",
autoscaleFormula: myAutoScaleFormula);
Обновите формулу автомасштабирования
Чтобы обновить формулу для существующего пула с поддержкой автомасштабирования, вызовите операцию для включения автомасштабирования еще раз с новой формулой. Например, если при выполнении приведенного ниже кода .NET автомасштабирование уже включено в myexistingpool
, формула автомасштабирования заменяется содержимым myNewFormula
.
await myBatchClient.PoolOperations.EnableAutoScaleAsync(
"myexistingpool",
autoscaleFormula: myNewFormula);
Обновление интервала автомасштабирования
Чтобы обновить интервал оценки автомасштабирования для существующего пула с поддержкой автомасштабирования, вызовите операцию для включения автомасштабирования еще раз с новым интервалом. Например, чтобы задать интервал оценки автомасштабирования на 60 минут для пула, в котором автомасштабирование уже включено, выполните следующие действия:
await myBatchClient.PoolOperations.EnableAutoScaleAsync(
"myexistingpool",
autoscaleEvaluationInterval: TimeSpan.FromMinutes(60));
Оцените формулу автомасштабирования
Прежде чем применить формулу к пулу, ее можно оценить. Это позволяет проверить результаты формулы, прежде чем вы введете ее в продакшен.
Прежде чем оценить формулу автомасштабирования, необходимо включить автомасштабирование в пуле с допустимой формулой, например с помощью однострочной формулы $TargetDedicatedNodes = 0
. Затем для оценки формулы, которую требуется протестировать, выполните одно из следующих действий:
Вызовите метод BatchClient.PoolOperations.EvaluateAutoScale или EvaluateAutoScaleAsync.
Этим методам Batch .NET требуется идентификатор существующего пула и строка с формулой автомасштабирования для оценки.
Оцените формулу автомасштабирования.
В этом запросе REST API укажите идентификатор пула в универсальном коде ресурса и формулу автомасштабирования в элементе autoScaleFormula текста запроса. Ответ операции содержит все сведения об ошибках, которые могут быть связаны с формулой.
В следующем примере Batch .NET оценивается формула автомасштабирования. Если пул еще не использует автомасштабирование, сначала включите его.
// First obtain a reference to an existing pool
CloudPool pool = await batchClient.PoolOperations.GetPoolAsync("myExistingPool");
// If autoscaling isn't already enabled on the pool, enable it.
// You can't evaluate an autoscale formula on a non-autoscale-enabled pool.
if (pool.AutoScaleEnabled == false)
{
// You need a valid autoscale formula to enable autoscaling on the
// pool. This formula is valid, but won't resize the pool:
await pool.EnableAutoScaleAsync(
autoscaleFormula: "$TargetDedicatedNodes = $CurrentDedicatedNodes;",
autoscaleEvaluationInterval: TimeSpan.FromMinutes(5));
// Batch limits EnableAutoScaleAsync calls to once every 30 seconds.
// Because you want to apply our new autoscale formula below if it
// evaluates successfully, and you *just* enabled autoscaling on
// this pool, pause here to ensure you pass that threshold.
Thread.Sleep(TimeSpan.FromSeconds(31));
// Refresh the properties of the pool so that we've got the
// latest value for AutoScaleEnabled
await pool.RefreshAsync();
}
// You must ensure that autoscaling is enabled on the pool prior to
// evaluating a formula
if (pool.AutoScaleEnabled == true)
{
// The formula to evaluate - adjusts target number of nodes based on
// day of week and time of day
string myFormula = @"
$curTime = time();
$workHours = $curTime.hour >= 8 && $curTime.hour < 18;
$isWeekday = $curTime.weekday >= 1 && $curTime.weekday <= 5;
$isWorkingWeekdayHour = $workHours && $isWeekday;
$TargetDedicatedNodes = $isWorkingWeekdayHour ? 20:10;
";
// Perform the autoscale formula evaluation. Note that this code does not
// actually apply the formula to the pool.
AutoScaleRun eval =
await batchClient.PoolOperations.EvaluateAutoScaleAsync(pool.Id, myFormula);
if (eval.Error == null)
{
// Evaluation success - print the results of the AutoScaleRun.
// This will display the values of each variable as evaluated by the
// autoscale formula.
Console.WriteLine("AutoScaleRun.Results: " +
eval.Results.Replace("$", "\n $"));
// Apply the formula to the pool since it evaluated successfully
await batchClient.PoolOperations.EnableAutoScaleAsync(pool.Id, myFormula);
}
else
{
// Evaluation failed, output the message associated with the error
Console.WriteLine("AutoScaleRun.Error.Message: " +
eval.Error.Message);
}
}
В случае успешного вычисления формулы, показанной в этом фрагменте, будет получен результат, подобный следующему:
AutoScaleRun.Results:
$TargetDedicatedNodes=10;
$NodeDeallocationOption=requeue;
$curTime=2016-10-13T19:18:47.805Z;
$isWeekday=1;
$isWorkingWeekdayHour=0;
$workHours=0
Получение сведений о запусках автомасштабирования
Рекомендуется периодически проверять результаты оценки службы пакетной обработки вашей формулы автомасштабирования. Чтобы сделать это, получите (или обновите) ссылку на пул, а затем проверьте свойства последнего запуска автомасштабирования.
В Batch .NET свойство CloudPool.AutoScaleRun имеет несколько свойств, которые предоставляют сведения о последнем выполнении автомасштабирования в пуле.
В REST API сведения о пуле содержат последние сведения о выполнении автоматического масштабирования в свойстве autoScaleRun .
В следующем примере C# используется библиотека Batch .NET для вывода сведений о последнем выполнении автомасштабирования в пуле myPool.
await Cloud pool = myBatchClient.PoolOperations.GetPoolAsync("myPool");
Console.WriteLine("Last execution: " + pool.AutoScaleRun.Timestamp);
Console.WriteLine("Result:" + pool.AutoScaleRun.Results.Replace("$", "\n $"));
Console.WriteLine("Error: " + pool.AutoScaleRun.Error);
Выходные данные выборки из предыдущего примера:
Last execution: 10/14/2016 18:36:43
Result:
$TargetDedicatedNodes=10;
$NodeDeallocationOption=requeue;
$curTime=2016-10-14T18:36:43.282Z;
$isWeekday=1;
$isWorkingWeekdayHour=0;
$workHours=0
Error:
Получение журнала выполнения автомасштабирования с помощью событий автомасштабирования пула
Проверьте журнал автомасштабирования, выполнив запрос к PoolAutoScaleEvent. Сервис Batch генерирует это событие для записи каждого случая оценки и выполнения формулы автомасштабирования, что может быть полезно для устранения потенциальных проблем.
Пример события для PoolAutoScaleEvent:
{
"id": "poolId",
"timestamp": "2020-09-21T23:41:36.750Z",
"formula": "...",
"results": "$TargetDedicatedNodes=10;$NodeDeallocationOption=requeue;$curTime=2016-10-14T18:36:43.282Z;$isWeekday=1;$isWorkingWeekdayHour=0;$workHours=0",
"error": {
"code": "",
"message": "",
"values": []
}
}
Примеры формул автомасштабирования
Давайте рассмотрим некоторые формулы, которые демонстрируют различные способы настройки количества вычислительных ресурсов в пуле.
Пример 1. Изменение с учетом времени
Предположим, вы хотите изменять размер пула в зависимости от дня недели и времени дня. В этом примере показано, как уменьшать и увеличивать количество узлов в пуле соответствующим образом.
Формула сначала получает значение текущего времени. Если это будний день (1–5) и в рабочие часы (с 8:00 до 18:00), целевой размер пула устанавливается на 20 узлов. В противном случае он равен 10 узлам.
$curTime = time();
$workHours = $curTime.hour >= 8 && $curTime.hour < 18;
$isWeekday = $curTime.weekday >= 1 && $curTime.weekday <= 5;
$isWorkingWeekdayHour = $workHours && $isWeekday;
$TargetDedicatedNodes = $isWorkingWeekdayHour ? 20:10;
$NodeDeallocationOption = taskcompletion;
$curTime
можно скорректировать в соответствии с вашим местным часовым поясом, добавив time()
к произведению TimeZoneInterval_Hour
и вашего смещения от UTC. Например, для летнего горного времени (MDT) используйте $curTime = time() + (-6 * TimeInterval_Hour);
. Помните, что смещение должно быть скорректировано в начале и конце летнего времени, если применимо.
Пример 2. Изменение с учетом задачи
В этом примере C# размер пула настраивается в зависимости от количества задач в очереди. Комментарии и разрывы строк включаются в строки формул.
// Get pending tasks for the past 15 minutes.
$samples = $PendingTasks.GetSamplePercent(TimeInterval_Minute * 15);
// If you have fewer than 70 percent data points, use the last sample point,
// otherwise use the maximum of last sample point and the history average.
$tasks = $samples < 70 ? max(0,$PendingTasks.GetSample(1)) : max( $PendingTasks.GetSample(1), avg($PendingTasks.GetSample(TimeInterval_Minute * 15)));
// If number of pending tasks is not 0, set targetVM to pending tasks, otherwise
// half of current dedicated.
$targetVMs = $tasks > 0? $tasks:max(0, $TargetDedicatedNodes/2);
// The pool size is capped at 20, if target VM value is more than that, set it
// to 20. This value should be adjusted according to your use case.
$TargetDedicatedNodes = max(0, min($targetVMs, 20));
// Set node deallocation mode - let running tasks finish before removing a node
$NodeDeallocationOption = taskcompletion;
Пример 3: Учет параллельных задач
В этом примере кода на C# размер пула изменяется в зависимости от количества задач. Эта формула также учитывает значение TaskSlotsPerNode , заданное для пула. Такой подход полезен, если в пуле поддерживается параллельное выполнение задач.
// Determine whether 70 percent of the samples have been recorded in the past
// 15 minutes; if not, use last sample
$samples = $ActiveTasks.GetSamplePercent(TimeInterval_Minute * 15);
$tasks = $samples < 70 ? max(0,$ActiveTasks.GetSample(1)) : max( $ActiveTasks.GetSample(1),avg($ActiveTasks.GetSample(TimeInterval_Minute * 15)));
// Set the number of nodes to add to one-fourth the number of active tasks
// (the TaskSlotsPerNode property on this pool is set to 4, adjust
// this number for your use case)
$cores = $TargetDedicatedNodes * 4;
$extraVMs = (($tasks - $cores) + 3) / 4;
$targetVMs = ($TargetDedicatedNodes + $extraVMs);
// Attempt to grow the number of compute nodes to match the number of active
// tasks, with a maximum of 3
$TargetDedicatedNodes = max(0,min($targetVMs,3));
// Keep the nodes active until the tasks finish
$NodeDeallocationOption = taskcompletion;
Пример 4. Настройка исходного размера пула
Этот пример показывает код на C# с формулой автомасштабирования, которая задает в качестве размера пула определенное число узлов на начальный период времени. После этого корректируется размер пула в зависимости от количества выполняемых и активных задач.
В частности, в данной формуле выполняются следующие действия.
- Устанавливает начальный размер пула до четырех узлов.
- Не настраивает размер пула в течение первых 10 минут жизненного цикла пула.
- Через 10 минут определяется максимальное значение количества запущенных и активных задач за последние 60 минут.
- Если оба значения равны 0, указывая, что за последние 60 минут задачи не выполнялись или активны, размер пула имеет значение 0.
- Если любое из значений больше нуля, изменений не производится.
string now = DateTime.UtcNow.ToString("r");
string formula = string.Format(@"
$TargetDedicatedNodes = {1};
lifespan = time() - time(""{0}"");
span = TimeInterval_Minute * 60;
startup = TimeInterval_Minute * 10;
ratio = 50;
$TargetDedicatedNodes = (lifespan > startup ? (max($RunningTasks.GetSample(span, ratio), $ActiveTasks.GetSample(span, ratio)) == 0 ? 0 : $TargetDedicatedNodes) : {1});
", now, 4);
Следующие шаги
- Узнайте, как одновременно выполнять несколько задач на вычисленных узлах в пуле. Наряду с автомасштабированием это может помочь сократить продолжительность задания для некоторых рабочих нагрузок и сэкономить деньги.
- Узнайте, как эффективно запрашивать службу Azure Batch.