Поделиться через


эффективное создание запросов на вывод списка ресурсов пакетной службы;

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

Примечание.

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

Определение уровня детализации

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

Этот фрагмент кода API пакетной службы .NET перечисляет все задачи, связанные с заданием, а также выводит полный набор их свойств.

// Get a collection of all of the tasks and all of their properties for job-001
IPagedEnumerable<CloudTask> allTasks =
    batchClient.JobOperations.ListTasks("job-001");

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

// Configure an ODATADetailLevel specifying a subset of tasks and
// their properties to return
ODATADetailLevel detailLevel = new ODATADetailLevel();
detailLevel.FilterClause = "state eq 'completed'";
detailLevel.SelectClause = "id,commandLine,nodeInfo";

// Supply the ODATADetailLevel to the ListTasks method
IPagedEnumerable<CloudTask> completedTasks =
    batchClient.JobOperations.ListTasks("job-001", detailLevel);

Если, как в данном примере сценария, задание состоит из тысяч задач, результаты для второго запроса обычно возвращаются быстрее, чем для первого. Дополнительные сведения об использовании ODATADetailLevel при перечислении элементов с помощью API пакетной службы .NET см. в разделе "Эффективные запросы в пакетной службе .NET".

Внимание

Мы настоятельно рекомендуем всегда передавать объект ODATADetailLevel в вызовы API .NET для получения списков. Это обеспечит максимальную эффективность и производительность приложения. Задание уровня детализации помогает снизить время ответа пакетной службы, повысить эффективность использования сети и минимизировать использование памяти клиентскими приложениями.

Использование строк запроса

Вы можете использовать API пакетной службы .NET и пакетной службы REST, чтобы уменьшить количество элементов, возвращаемых запросом, и объем сведений, возвращаемых запросом для каждого элемента. Существует три типа строк запроса, которые можно использовать для сужения запроса: $filter, $select и $expand.

Сведения об API пакетной службы .NET см. в свойствах класса ODATADetailLevel. Кроме того, ознакомьтесь с разделом "Эффективные запросы в пакетной службе .NET".

Сведения об API пакетной службы REST см. в справочнике по API пакетной службы REST. Найдите ссылку на список для ресурса, который требуется запросить. Затем просмотрите раздел "Параметры URI" для получения дополнительных сведений о $filter, $select, и $expand. Например, см. параметры URI для пула — список. Кроме того, узнайте как эффективно выполнять пакетные запросы с помощью Azure CLI.

Примечание.

При создании какого-либо из трех типов строк запроса необходимо убедиться, что имена и регистр свойств совпадают с аналогичными элементами REST API. Например, при работе с классом CloudTask в .NET необходимо указывать свойство state, а не State, несмотря на то что в .NET используется свойство CloudTask.State. Дополнительные сведения см. в сопоставлении свойств между .NET и REST API.

Фильтр

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

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

В этом примере выводятся только запущенные задачи отрисовки: (state eq 'running') and startswith(id, 'renderTask').

Выбрать

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

В этом примере показано, что для каждой задачи необходимо вернуть значения только трех свойств: id, state, stateTransitionTime.

Разверните

Строка выражения $expand сокращает количество вызовов API, необходимое для получения определенных сведений. Эту строку можно использовать для получения дополнительных сведений о каждом элементе с помощью одного вызова API. Этот метод помогает повысить производительность за счет сокращения вызовов API. Используйте строку $expand вместо получения списка сущностей и запроса сведений о каждом элементе списка.

Как и $select, $expand определяет, какие данные нужно включить в результаты запроса списка. Если требуются все свойства и строка выбора не указана, $expand необходимо использовать для получения сведений о статистике. Если для получения подмножества свойств используется строка выборки, то в ней можно указать stats и не указывать $expand.

Поддерживаемые варианты использования этой строки включают перечисление заданий, расписаний заданий, задач и пулов. В настоящее время строка поддерживает только статистические данные.

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

Правила строк фильтрации, выборки и развертывания

  • Убедитесь, что имена свойств в фильтре, строке выборки и строке развертывания отображаются так же, как и в API пакетной службы REST. Это правило применяется даже при использовании пакетной службы .NET или одного из пакетов SDK пакетной службы.
  • Имена всех свойств чувствительны к регистру, но для значений свойств регистр значения не имеет.
  • Строки даты и времени могут иметь один из двух форматов и должны начинаться с DateTime.
    • Пример формата W3C-DTF: creationTime gt DateTime'2011-05-08T08:49:37Z'
    • Пример формата RFC 1123: creationTime gt DateTime'Sun, 08 May 2011 08:49:37 GMT'
  • Строки с логическими выражениями должны иметь значение true или false.
  • Если задано недопустимое свойство или оператор, отобразится ошибка 400 (Bad Request) .

Эффективное выполнение запросов в пакетной службе для .NET

В API пакетной службы .NET для указания строк фильтрации, выборки и развертывания операций списка используется класс ODATADetailLevel. Класс ODataDetailLevel имеет три открытых строковых свойства. Вы можете указать эти свойства в конструкторе или задать свойства непосредственно в объекте. Затем передайте объект ODataDetailLevel в качестве параметра в различные операции получения списка, такие как ListPools, ListJobs и ListTasks.

  • ODATADetailLevel.FilterClause ограничивает количество возвращаемых элементов.
  • ODATADetailLevel.SelectClause определяет, значения каких свойств необходимо вернуть для каждого элемента.
  • ODATADetailLevel.ExpandClause извлекает данные по всем элементам за один вызов API вместо того, чтобы выполнять отдельные вызовы для каждого элемента.

Ниже приведен фрагмент кода, который с помощью API пакетной службы .NET отправляет эффективный запрос пакетной службе для получения статистики по определенному набору пулов. У пользователя пакетной службы есть как тестовые, так и рабочие пулы. Идентификаторы тестовых пулов имеют префикс "test", а рабочих пулов — "prod". myBatchClient является правильно инициализированным экземпляром класса BatchClient.

// First we need an ODATADetailLevel instance on which to set the filter, select,
// and expand clause strings
ODATADetailLevel detailLevel = new ODATADetailLevel();

// We want to pull only the "test" pools, so we limit the number of items returned
// by using a FilterClause and specifying that the pool IDs must start with "test"
detailLevel.FilterClause = "startswith(id, 'test')";

// To further limit the data that crosses the wire, configure the SelectClause to
// limit the properties that are returned on each CloudPool object to only
// CloudPool.Id and CloudPool.Statistics
detailLevel.SelectClause = "id, stats";

// Specify the ExpandClause so that the .NET API pulls the statistics for the
// CloudPools in a single underlying REST API call. Note that we use the pool's
// REST API element name "stats" here as opposed to "Statistics" as it appears in
// the .NET API (CloudPool.Statistics)
detailLevel.ExpandClause = "stats";

// Now get our collection of pools, minimizing the amount of data that is returned
// by specifying the detail level that we configured above
List<CloudPool> testPools =
    await myBatchClient.PoolOperations.ListPools(detailLevel).ToListAsync();

Совет

Экземпляр ODATADetailLevel с предложениями Select и Expand также можно передать в соответствующие методы Get, чтобы ограничить объем возвращаемых данных, например в метод PoolOperations.GetPool.

Сопоставление API REST и .NET пакетной службы

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

Сопоставления для строк фильтрации

  • Методы списка .NET — каждый из методов API для .NET в этом столбце принимает объект ODATADetailLevel в качестве параметра.
  • Запросы списка REST— каждая страница REST API, связанная с этим столбцом, содержит таблицу со свойствами и операциями, разрешенными в строках фильтрации. Вы можете использовать эти имена свойств и операции при создании строки ODATADetailLevel.FilterClause.
Методы списка .NET Запросы списка REST
CertificateOperations.ListCertificates Получение списка сертификатов в учетной записи
CloudTask.ListNodeFiles Получение списка файлов, связанных с задачей
JobOperations.ListJobPreparationAndReleaseTaskStatus Получение состояния подготовки задания и задачи деблокирования задания
JobOperations.ListJobs Получение списка заданий в учетной записи
JobOperations.ListNodeFiles Получение списка файлов в узле
JobOperations.ListTasks Получение списка задач, связанных с заданием
JobScheduleOperations.ListJobSchedules Получение расписаний для заданий в учетной записи
JobScheduleOperations.ListJobs Получение списка заданий, связанных с расписанием задания
PoolOperations.ListComputeNodes Получение списка вычислительных узлов в пуле
PoolOperations.ListPools Получение списка пулов учетной записи

Сопоставления для строк выборки

  • Типы пакетной службы для .NET— типы API пакетной службы для .NET.
  • Сущности REST API— каждая страница в этом столбце содержит одну или несколько таблиц с именами свойств API REST для соответствующих типов. Эти имена свойств используются при создании строк выборки . Они также используются при создании строки ODATADetailLevel.SelectClause.
Типы пакетной службы для .NET Сущности REST API
Certificate Получение информации о сертификате
CloudJob Получение информации о задании
CloudJobSchedule Получение информации о расписании задания
ComputeNode Получение информации об узле
CloudPool Получение информации о пуле
CloudTask Получение информации о задаче

Пример. Создание строки фильтрации

Чтобы создать строку фильтрации для ODATADetailLevel.FilterClause, найдите соответствующую страницу REST API. Доступные для выбора свойства и их поддерживаемые операторы находятся в первой многострочной таблице. Например, вы хотите получить все задачи с ненулевым кодом возврата. Проверьте "Вывод задач, связанных с заданием", чтобы найти строку с соответствующим свойством и допустимые операторы:

Свойство Разрешенные операции Тип
executionInfo/exitCode eq, ge, gt, le , lt Int

Связанная строка фильтрации:

(executionInfo/exitCode lt 0) or (executionInfo/exitCode gt 0)

Пример. Создание строки выборки

Чтобы создать ODATADetailLevel.SelectClause, найдите соответствующую страницу REST API для сущности, которую вы перечисляете. Доступные для выбора свойства и их поддерживаемые операторы находятся в первой многострочной таблице. Например, вы хотите получить только идентификатор и командную строку для каждой задачи в списке. Выберите Получение информации о задаче":

Свойство Тип Примечания.
id String The ID of the task.
commandLine String The command line of the task.

Связанная строка выборки:

id, commandLine

Примеры кода

Эффективные запросы на вывод списка

На примере проекта EfficientListQueries показано, как эффективные запросы на получение списков могут повлиять на производительность приложения. Это консольное приложение C# создает и добавляет большое количество задач в задание. Затем приложение выполняет несколько вызовов метода JobOperations.ListTasks и передает объекты ODATADetailLevel. Данные объекты настроены с различными значениями свойств в зависимости от возвращаемого объема данных. В данном примере показан результат схожий со следующим:

Adding 5000 tasks to job jobEffQuery...
5000 tasks added in 00:00:47.3467587, hit ENTER to query tasks...

4943 tasks retrieved in 00:00:04.3408081 (ExpandClause:  | FilterClause: state eq 'active' | SelectClause: id,state)
0 tasks retrieved in 00:00:00.2662920 (ExpandClause:  | FilterClause: state eq 'running' | SelectClause: id,state)
59 tasks retrieved in 00:00:00.3337760 (ExpandClause:  | FilterClause: state eq 'completed' | SelectClause: id,state)
5000 tasks retrieved in 00:00:04.1429881 (ExpandClause:  | FilterClause:  | SelectClause: id,state)
5000 tasks retrieved in 00:00:15.1016127 (ExpandClause:  | FilterClause:  | SelectClause: id,state,environmentSettings)
5000 tasks retrieved in 00:00:17.0548145 (ExpandClause: stats | FilterClause:  | SelectClause: )

Sample complete, hit ENTER to continue...

В примере показано как путем ограничения свойств и количества возвращаемых элементов можно значительно уменьшить время отклика на запрос. Этот и другие примеры проектов находятся в репозитории azure-batch-samples на сервисе GitHub.

Библиотека BatchMetrics

Пример проекта BatchMetrics демонстрирует, как эффективно отслеживать ход выполнения задания пакетной службы Azure с помощью API пакетной службы.

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

В примере приложения проекта демонстрируются следующие операции:

  • Выбор определенных атрибутов для загрузки только необходимых свойств
  • Фильтрация времени смены состояния для загрузки только изменений, отправленных с момента последнего запроса

Например, в библиотеке BatchMetrics используется приведенный ниже метод. Он возвращает объект ODATADetailLevel, указывающий, что для сущностей, к которым обращен запрос, нужно получить только свойства id и state. Он также указывает, что должны быть возвращены только те сущности, состояние которых изменилось с момента, указанного в значении параметра DateTime .

internal static ODATADetailLevel OnlyChangedAfter(DateTime time)
{
    return new ODATADetailLevel(
        selectClause: "id, state",
        filterClause: string.Format("stateTransitionTime gt DateTime'{0:o}'", time)
    );
}

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