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


Настройка производительности для отправки и скачивания с помощью .NET

Когда приложение передает данные с помощью клиентской библиотеки служба хранилища Azure для .NET, существует несколько факторов, которые могут повлиять на скорость, использование памяти и даже на успех или сбой запроса. Чтобы повысить производительность и надежность передачи данных, важно упреждать настройку параметров передачи клиентской библиотеки в зависимости от среды, в которой работает ваше приложение.

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

Настройка производительности с помощью StorageTransferOptions

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

Следующие свойства StorageTransferOptions можно настроить на основе потребностей приложения:

  • InitialTransferSize — размер первого запроса в байтах
  • MaximumConcurrency — максимальное количество подтрансферов, которые могут использоваться параллельно
  • MaximumTransferSize — максимальная длина передачи в байтах

Примечание.

Хотя структура StorageTransferOptions содержит значения, допускающие значение NULL, клиентские библиотеки будут использовать значения по умолчанию для каждого отдельного значения, если оно не указано. Эти значения по умолчанию обычно выполняются в среде центра обработки данных, но, скорее всего, не подходят для домашних сред потребителей. Плохо настроенная StorageTransferOptions может привести к чрезмерно длительным операциям и даже времени ожидания запросов. Рекомендуется проактивно протестировать значения StorageTransferOptionsи настроить их в зависимости от потребностей приложения и среды.

InitialTransferSize

InitialTransferSize — это размер первого запроса диапазона в байтах. Http-запрос диапазона — это частичный запрос, размер, определенный InitialTransferSize в данном случае. Большие двоичные объекты меньше этого размера передаются в одном запросе. Большие двоичные объекты, превышающие этот размер, продолжают передаваться в блоках размера MaximumTransferSize.

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

Если вы не уверены, какое значение лучше всего подходит для вашей ситуации, безопасный параметр — задать InitialTransferSize то же значение, которое используется для MaximumTransferSize.

Примечание.

При использовании объекта отправка большого BlobClient двоичного объекта меньше, InitialTransferSize чем будет выполнена с помощью Put BLOB-объекта, а не put Block.

Максимальная параллелизмность

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

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

MaximumTransferSize

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

Для эффективного перемещения данных клиентские библиотеки могут не всегда достигать значения для каждой MaximumTransferSize передачи. В зависимости от операции максимальный поддерживаемый размер передачи может отличаться. Например, блочные BLOB-объекты, вызывающие операцию Put Block с версией службы 2019-12-12 или более поздней, имеют максимальный размер блока 4000 МиБ. Дополнительные сведения об ограничениях размера передачи для хранилища BLOB-объектов см. на диаграмме в целевых объектах масштабирования для хранилища BLOB-объектов.

Пример кода

Клиентская библиотека включает перегрузки для Upload методов и UploadAsync методов, которые принимают экземпляр StorageTransferOptions в составе параметра BlobUploadOptions . Аналогичные перегрузки также существуют для DownloadTo методов и DownloadToAsync методов с помощью параметра BlobDownloadToOptions .

В следующем примере кода показано, как определить значения для экземпляра StorageTransferOptions и передать эти параметры конфигурации в качестве параметра UploadAsync. Значения, указанные в этом примере, не предназначены для рекомендации. Чтобы правильно настроить эти значения, необходимо учитывать конкретные потребности приложения.

// Specify the StorageTransferOptions
BlobUploadOptions options = new BlobUploadOptions
{
    TransferOptions = new StorageTransferOptions
    {
        // Set the maximum number of parallel transfer workers
        MaximumConcurrency = 2,

        // Set the initial transfer length to 8 MiB
        InitialTransferSize = 8 * 1024 * 1024,

        // Set the maximum length of a transfer to 4 MiB
        MaximumTransferSize = 4 * 1024 * 1024
    }
};

// Upload data from a stream
await blobClient.UploadAsync(stream, options);

В этом примере мы задали число параллельных рабочих ролей передачи 2 с помощью MaximumConcurrency свойства. Эта конфигурация открывает до двух подключений одновременно, что позволяет выполнять отправку параллельно. Исходный запрос диапазона HTTP пытается отправить до 8 МиБ данных, как определено свойством InitialTransferSize . Обратите внимание, что InitialTransferSize применяется только к отправке при использовании искать поток. Если размер большого двоичного объекта меньше 8 МиБ, для выполнения операции требуется только один запрос. Если размер большого двоичного объекта превышает 8 МиБ, все последующие запросы на передачу имеют максимальный размер 4 МиБ, который мы устанавливаем со свойством MaximumTransferSize .

Рекомендации по производительности отправки

Во время отправки клиентские библиотеки хранилища разделяют заданный поток отправки на несколько подзагрузок на основе значений, определенных в экземпляре StorageTransferOptions . Каждая подзагрузка имеет собственный выделенный вызов операции REST. BlobClient Для объекта или BlockBlobClient объекта эта операция называется Put Block. DataLakeFileClient Для объекта эта операция — "Добавление данных". Клиентская библиотека хранилища управляет этими операциями REST параллельно (в зависимости от параметров передачи) для завершения полной отправки.

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

Примечание.

Блочные большие двоичные объекты имеют максимальное количество блоков в 50 000 блоков. Максимальный размер большого двоичного объекта блока составляет 50 000 раз MaximumTransferSize.

Буферизация во время отправки

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

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

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

InitialTransferSize при отправке

Если для отправки предоставляется доступный для отправки поток, длина потока проверяется по значению InitialTransferSize. Если длина потока меньше этого значения, весь поток передается в виде одного вызова REST независимо от других StorageTransferOptions значений. В противном случае отправка выполняется в нескольких частях, как описано ранее. InitialTransferSize не влияет на неискиваемый поток и игнорируется.

Рекомендации по повышению производительности для загрузки

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

Буферизация во время загрузки

Получение нескольких HTTP-ответов одновременно с содержимым текста имеет последствия для использования памяти. Однако клиентские библиотеки хранилища явно не добавляют шаг буфера для скачаемого содержимого. Входящие ответы обрабатываются по порядку. Клиентские библиотеки настраивают 16-килобайтовый буфер для копирования потоков из потока ответа HTTP в целевой поток или путь к файлу, предоставленному вызывающим объектом.

InitialTransferSize при скачивании

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

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