Ajuste de desempenho para uploads e downloads com .NET
Quando um aplicativo transfere dados usando a biblioteca de cliente do Armazenamento do Azure para .NET, há vários fatores que podem afetar a velocidade, o uso de memória e até mesmo o sucesso ou falha da solicitação. Para maximizar o desempenho e a confiabilidade das transferências de dados, é importante ser proativo na configuração das opções de transferência da biblioteca do cliente com base no ambiente em que seu aplicativo é executado.
Este artigo apresenta várias considerações para ajustar as opções de transferência de dados, e as diretrizes se aplicam a qualquer API que aceite StorageTransferOptions
como parâmetro. Quando ajustada corretamente, a biblioteca do cliente pode distribuir dados de forma eficiente entre várias solicitações, o que pode resultar em maior velocidade de operação, uso de memória e estabilidade de rede.
Ajuste de desempenho com StorageTransferOptions
Ajustar corretamente os valores em StorageTransferOptions é a chave para um desempenho confiável para operações de transferência de dados. As transferências de armazenamento são particionadas em várias subtransferências com base nos valores de propriedade definidos em uma instância desta estrutura. O tamanho máximo de transferência suportado varia de acordo com a operação e a versão do serviço, portanto, certifique-se de verificar a documentação para determinar os limites. Para obter mais informações sobre limites de tamanho de transferência para armazenamento de Blob, consulte Dimensionar destinos para armazenamento de Blob.
As seguintes propriedades do StorageTransferOptions
podem ser ajustadas com base nas necessidades do seu aplicativo:
- InitialTransferSize - o tamanho da primeira solicitação em bytes
- MaximumConcurrency - o número máximo de subtransferências que podem ser usadas em paralelo
- MaximumTransferSize - o comprimento máximo de uma transferência em bytes
Nota
Embora o StorageTransferOptions
struct contenha valores anuláveis, as bibliotecas de cliente usarão padrões para cada valor individual, se não forem fornecidos. Esses padrões geralmente têm desempenho em um ambiente de data center, mas provavelmente não são adequados para ambientes de consumidores domésticos. Mal ajustado StorageTransferOptions
pode resultar em operações excessivamente longas e até mesmo tempos limite de solicitação. É melhor ser proativo ao testar os valores no e ajustá-los com base nas StorageTransferOptions
necessidades do seu aplicativo e ambiente.
InitialTransferSize
InitialTransferSize é o tamanho da primeira solicitação de intervalo em bytes. Uma solicitação de intervalo HTTP é uma solicitação parcial, com o tamanho definido por InitialTransferSize
neste caso. Blobs menores que esse tamanho são transferidos em uma única solicitação. Blobs maiores que esse tamanho continuam a ser transferidos em pedaços de tamanho MaximumTransferSize
.
É importante observar que o valor especificado para MaximumTransferSize
não limita o valor definido para InitialTransferSize
. InitialTransferSize
Define uma limitação de tamanho separada para uma solicitação inicial para executar toda a operação de uma só vez, sem subtransferências. Muitas vezes, você quer InitialTransferSize
ser pelo menos tão grande quanto o valor definido para MaximumTransferSize
, se não maior. Dependendo do tamanho da transferência de dados, essa abordagem pode ser mais eficiente, pois a transferência é concluída com uma única solicitação e evita a sobrecarga de várias solicitações.
Se você não tiver certeza de qual valor é melhor para sua situação, uma opção segura é definir InitialTransferSize
para o mesmo valor usado para MaximumTransferSize
.
Nota
Ao usar um BlobClient
objeto, o upload de um blob menor que o InitialTransferSize
será executado usando Put Blob, em vez de Put Block.
MaximumConcurrency
MaximumConcurrency é o número máximo de trabalhadores que podem ser usados em uma transferência paralela. Atualmente, apenas operações assíncronas podem paralelizar transferências. As operações síncronas ignoram esse valor e funcionam em sequência.
A eficácia desse valor está sujeita aos limites do pool de conexões no .NET, que podem restringir o desempenho por padrão em determinados cenários. Para saber mais sobre os limites do pool de conexões no .NET, consulte Limites do pool de conexões do .NET Framework e o novo SDK do Azure para .NET.
MaximumTransferSize
MaximumTransferSize é o comprimento máximo de uma transferência em bytes. Como mencionado anteriormente, este valor não limita InitialTransferSize
, que pode ser maior do que MaximumTransferSize
.
Para manter os dados em movimento de forma eficiente, as bibliotecas de cliente nem sempre atingem o valor de MaximumTransferSize
cada transferência. Dependendo da operação, o valor máximo suportado para o tamanho da transferência pode variar. Por exemplo, blobs de bloco que chamam a operação Put Block com uma versão de serviço de 2019-12-12 ou posterior têm um tamanho máximo de bloco de 4000 MiB. Para obter mais informações sobre limites de tamanho de transferência para armazenamento de Blob, consulte o gráfico em Dimensionar destinos para armazenamento de Blob.
Exemplo de código
A biblioteca de cliente inclui sobrecargas para os métodos e UploadAsync
, que aceitam uma instância StorageTransferOptions como parte de um parâmetro BlobUploadOptions.Upload
Sobrecargas semelhantes também existem para os DownloadTo
métodos e DownloadToAsync
usando um parâmetro BlobDownloadToOptions .
O exemplo de código a seguir mostra como definir valores para uma StorageTransferOptions
instância e passar essas opções de configuração como um parâmetro para UploadAsync
. Os valores fornecidos neste exemplo não pretendem ser uma recomendação. Para ajustar corretamente esses valores, você precisa considerar as necessidades específicas do seu aplicativo.
// 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);
Neste exemplo, definimos o número de trabalhadores de transferência paralela como 2, usando a MaximumConcurrency
propriedade. Esta configuração abre até duas conexões simultaneamente, permitindo que o upload aconteça em paralelo. A solicitação inicial de intervalo HTTP tenta carregar até 8 MiB de dados, conforme definido pela InitialTransferSize
propriedade. Observe que InitialTransferSize
só se aplica a uploads ao usar um fluxo pesquisável. Se o tamanho do blob for menor que 8 MiB, apenas uma única solicitação será necessária para concluir a operação. Se o tamanho do blob for maior que 8 MiB, todas as solicitações de transferência subsequentes terão um tamanho máximo de 4 MiB, que definimos com a MaximumTransferSize
propriedade.
Considerações de desempenho para uploads
Durante um upload, as bibliotecas do cliente de armazenamento dividem um determinado fluxo de upload em vários subcarregamentos com base nos valores definidos na StorageTransferOptions
instância. Cada subupload tem sua própria chamada dedicada para a operação REST. Para um BlobClient
objeto ou BlockBlobClient
objeto, esta operação é Put Block. Para um DataLakeFileClient
objeto, esta operação é Append Data. A biblioteca do cliente de armazenamento gerencia essas operações REST em paralelo (dependendo das opções de transferência) para concluir o carregamento completo.
Dependendo se o fluxo de upload é pesquisável ou não, a biblioteca do cliente lida com buffering e InitialTransferSize
de forma diferente, conforme descrito nas seções a seguir. Um fluxo pesquisável é um fluxo que suporta consultar e modificar a posição atual dentro de um fluxo. Para saber mais sobre fluxos no .NET, consulte a referência da classe Stream.
Nota
Os blobs de bloco têm uma contagem máxima de blocos de 50.000 blocos. O tamanho máximo do blob de bloco, então, é de 50.000 vezes MaximumTransferSize
.
Armazenamento em buffer durante carregamentos
A camada REST de armazenamento não suporta pegar uma operação de upload REST de onde você parou; As transferências individuais são concluídas ou perdidas. Para garantir a resiliência para uploads de fluxo não pesquisáveis, as bibliotecas do cliente de armazenamento armazenam em buffer os dados para cada chamada REST individual antes de iniciar o carregamento. Além das limitações de velocidade da rede, esse comportamento de buffer é um motivo para considerar um valor menor para MaximumTransferSize
, mesmo ao carregar em sequência. Diminuir o valor de MaximumTransferSize
diminui a quantidade máxima de dados armazenados em buffer em cada solicitação e cada nova tentativa de uma solicitação com falha. Se você estiver enfrentando tempos limite frequentes durante transferências de dados de um determinado tamanho, reduzir o valor de reduz o tempo de MaximumTransferSize
buffer e pode resultar em melhor desempenho.
Outro cenário em que o buffer ocorre é quando você está carregando dados com chamadas REST paralelas para maximizar a taxa de transferência da rede. As bibliotecas de cliente precisam de fontes das quais possam ler em paralelo e, como os fluxos são sequenciais, as bibliotecas de cliente de armazenamento armazenam em buffer os dados de cada chamada REST individual antes de iniciar o carregamento. Esse comportamento de buffer ocorre mesmo se o fluxo fornecido for pesquisável.
Para evitar buffering durante uma chamada de carregamento assíncrono, você deve fornecer um fluxo pesquisável e definir MaximumConcurrency
como 1. Embora essa estratégia deva funcionar na maioria das situações, ainda é possível que o buffer ocorra se seu código estiver usando outros recursos de biblioteca de cliente que exigem buffer.
InitialTransferSize no upload
Quando um fluxo pesquisável é fornecido para upload, o comprimento do fluxo é verificado em relação ao valor de InitialTransferSize
. Se o comprimento do fluxo for menor que esse valor, todo o fluxo será carregado como uma única chamada REST, independentemente de outros StorageTransferOptions
valores. Caso contrário, o upload é feito em várias partes, conforme descrito anteriormente. InitialTransferSize
não tem efeito sobre um fluxo não pesquisável e é ignorado.
Considerações de desempenho para downloads
Durante um download, as bibliotecas do cliente de armazenamento dividem uma determinada solicitação de download em vários subdownloads com base nos valores definidos na StorageTransferOptions
instância. Cada subdownload tem sua própria chamada dedicada para a operação REST. Dependendo das opções de transferência, as bibliotecas de cliente gerenciam essas operações REST em paralelo para concluir o download completo.
Armazenamento em buffer durante downloads
Receber várias respostas HTTP simultaneamente com o conteúdo do corpo tem implicações para o uso da memória. No entanto, as bibliotecas de cliente de armazenamento não adicionam explicitamente uma etapa de buffer para o conteúdo baixado. As respostas recebidas são processadas em ordem. As bibliotecas de cliente configuram um buffer de 16 kilobytes para copiar fluxos de um fluxo de resposta HTTP para um fluxo de destino fornecido pelo chamador ou caminho de arquivo.
InitialTransferSize em download
Durante um download, as bibliotecas de cliente de armazenamento fazem uma solicitação de intervalo de download usando InitialTransferSize
antes de fazer qualquer outra coisa. Durante essa solicitação de download inicial, as bibliotecas de cliente sabem o tamanho total do recurso. Se a solicitação inicial tiver baixado com êxito todo o conteúdo, a operação será concluída. Caso contrário, as bibliotecas de cliente continuarão a fazer solicitações de intervalo até MaximumTransferSize
que o download completo seja concluído.
Próximos passos
- Este artigo faz parte do guia do desenvolvedor do Armazenamento de Blobs para .NET. Consulte a lista completa de artigos do guia do desenvolvedor em Crie seu aplicativo.
- Para entender mais sobre os fatores que podem influenciar o desempenho das operações de Armazenamento do Azure, consulte Latência no armazenamento de Blob.
- Para ver uma lista de considerações de design para otimizar o desempenho de aplicativos que usam armazenamento de Blob, consulte Lista de verificação de desempenho e escalabilidade para armazenamento de Blob.