Настройка производительности для отправки и скачивания с помощью .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
завершения полной загрузки.
Следующие шаги
- Эта статья является частью руководства разработчика хранилища BLOB-объектов для .NET. Полный список статей руководства разработчика см. в статье о создании приложения.
- Дополнительные сведения о факторах, которые могут повлиять на производительность операций служба хранилища Azure, см. в статье "Задержка в хранилище BLOB-объектов".
- Чтобы просмотреть список рекомендаций по проектированию для оптимизации производительности приложений с помощью хранилища BLOB-объектов, см . контрольный список производительности и масштабируемости для хранилища BLOB-объектов.