Partilhar via


Ajuste de desempenho para uploads e downloads com Python

Quando um aplicativo transfere dados usando a biblioteca de cliente do Armazenamento do Azure para Python, 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. 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 para uploads

Ajustar corretamente as opções de transferência de dados é a chave para um desempenho confiável para uploads. As transferências de armazenamento são particionadas em várias subtransferências com base nos valores desses argumentos. 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.

Definir opções de transferência para carregamentos

Os seguintes argumentos podem ser ajustados com base nas necessidades do seu aplicativo:

  • max_single_put_size: O tamanho máximo de um blob a ser carregado com uma única solicitação. O padrão é 64 MiB.
  • max_block_size: O comprimento máximo de uma transferência em bytes ao carregar um blob de bloco em partes. O padrão é 4 MiB.
  • max_concurrency: O número máximo de subtransferências que podem ser utilizadas em paralelo.

Nota

As bibliotecas de cliente usarão padrões para cada opção de transferência de dados, se não forem fornecidas. Esses padrões geralmente têm desempenho em um ambiente de data center, mas provavelmente não serão adequados para ambientes de consumidores domésticos. Opções de transferência de dados mal ajustadas podem resultar em operações excessivamente longas e até mesmo tempos limite de solicitação. É melhor ser proativo ao testar esses valores e ajustá-los com base nas necessidades do seu aplicativo e ambiente.

max_single_put_size

O max_single_put_size argumento é o tamanho máximo de blob em bytes para um único carregamento de solicitação. Se o tamanho do blob for menor ou igual a max_single_put_size, o blob será carregado com uma única solicitação Put Blob . Se o tamanho do blob for maior que max_single_put_size, ou se o tamanho do blob for desconhecido, o blob será carregado em partes usando uma série de chamadas Put Block seguidas por Put Block List.

É importante observar que o valor especificado para não limita o valor definido para max_block_sizemax_single_put_size. O max_single_put_size argumento define uma limitação de tamanho separada para uma solicitação para executar toda a operação de uma só vez, sem subtransferências. Muitas vezes, você quer max_single_put_size ser pelo menos tão grande quanto o valor definido para max_block_size, 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 max_single_put_size para o mesmo valor usado para max_block_size.

max_block_size

O max_block_size argumento é o comprimento máximo de uma transferência em bytes ao carregar um blob de bloco em partes. Como mencionado anteriormente, este valor não limita max_single_put_size, que pode ser maior do que max_block_size.

Para manter os dados em movimento de forma eficiente, as bibliotecas de cliente nem sempre atingem o valor de max_block_size cada transferência. Dependendo da operação, o valor máximo suportado para o tamanho da transferência pode variar. 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

O exemplo de código a seguir mostra como especificar opções de transferência de dados ao criar um BlobClient objeto e como carregar dados usando esse objeto cliente. 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.

def upload_blob_transfer_options(self, account_url: str, container_name: str, blob_name: str):
    # Create a BlobClient object with data transfer options for upload
    blob_client = BlobClient(
        account_url=account_url, 
        container_name=container_name, 
        blob_name=blob_name,
        credential=DefaultAzureCredential(),
        max_block_size=1024*1024*4, # 4 MiB
        max_single_put_size=1024*1024*8 # 8 MiB
    )
    
    with open(file=os.path.join(r'file_path', blob_name), mode="rb") as data:
        blob_client = blob_client.upload_blob(data=data, overwrite=True, max_concurrency=2)

Neste exemplo, definimos o número de trabalhadores de transferência paralela como 2, usando o max_concurrency argumento na chamada do método. Esta configuração abre até duas conexões simultaneamente, permitindo que o upload aconteça em paralelo. Durante a instanciação do cliente, definimos o max_single_put_size argumento como 8 MiB. Se o tamanho do blob for menor que 8 MiB, apenas uma única solicitação será necessária para concluir a operação de upload. Se o tamanho do blob for maior que 8 MiB, o blob será carregado em blocos com um tamanho máximo de bloco de 4 MiB, conforme definido pelo max_block_size argumento.

Considerações de desempenho para uploads

Durante um carregamento, as bibliotecas do cliente de armazenamento dividem um determinado fluxo de carregamento em vários subcarregamentos com base nas opções de configuração definidas durante a construção do cliente. Cada subupload tem sua própria chamada dedicada para a operação REST. Para um BlobClient objeto, esta operação é Put Block. 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.

Você pode aprender como a biblioteca de cliente lida com o buffer nas seções a seguir.

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 max_block_size.

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, as bibliotecas do cliente de armazenamento armazenam em buffer 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 max_block_size, mesmo ao carregar em sequência. Diminuir o valor de diminui a quantidade máxima de dados que são armazenados em buffer em cada solicitação e cada nova tentativa de max_block_size 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 max_block_size buffer e pode resultar em melhor desempenho.

Por padrão, o SDK armazena em buffer dados de bytes por solicitação de subupload simultânea, mas o uso de max_block_size memória pode ser limitado a 4 MiB por solicitação se as seguintes condições forem atendidas:

  • O max_block_size argumento deve ser maior que min_large_block_upload_threshold. O min_large_block_upload_threshold argumento pode ser definido durante a instanciação do cliente e é o tamanho mínimo do bloco em bytes necessário para usar o algoritmo eficiente de memória. O min_large_block_upload_threshold argumento assume como 4*1024*1024 + 1padrão .
  • O fluxo fornecido deve ser pesquisável. Um fluxo pesquisável é um fluxo que suporta consultar e modificar a posição atual dentro de um fluxo.
  • O blob deve ser um blob de bloco.

Embora essa estratégia se aplique à maioria das situações, ainda é possível que ocorra mais buffering se o código estiver usando outros recursos de biblioteca de cliente que exigem buffer.

Ajuste de desempenho para downloads

Ajustar corretamente as opções de transferência de dados é a chave para um desempenho confiável para downloads. As transferências de armazenamento são particionadas em várias subtransferências com base nos valores desses argumentos.

Definir opções de transferência para downloads

Os seguintes argumentos podem ser ajustados com base nas necessidades do seu aplicativo:

  • max_chunk_get_size: O tamanho máximo de bloco usado para baixar um blob. O padrão é 4 MiB.
  • max_concurrency: O número máximo de subtransferências que podem ser utilizadas em paralelo.
  • max_single_get_size: O tamanho máximo para um blob a ser baixado em uma única chamada. Se o tamanho total do blob exceder max_single_get_size, o restante dos dados do blob será baixado em partes. O padrão é 32 MiB.

Exemplo de código

def download_blob_transfer_options(self, account_url: str, container_name: str, blob_name: str):
    # Create a BlobClient object with data transfer options for download
    blob_client = BlobClient(
        account_url=account_url, 
        container_name=container_name, 
        blob_name=blob_name,
        credential=DefaultAzureCredential(),
        max_single_get_size=1024*1024*32, # 32 MiB
        max_chunk_get_size=1024*1024*4 # 4 MiB
    )

    with open(file=os.path.join(r'file_path', 'file_name'), mode="wb") as sample_blob:
        download_stream = blob_client.download_blob(max_concurrency=2)
        sample_blob.write(download_stream.readall())

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 nas opções de configuração definidas durante a construção do cliente. Cada subdownload tem sua própria chamada dedicada para a operação REST. Dependendo das opções de transferência, as bibliotecas do cliente gerenciam essas operações REST em paralelo para concluir o download completo.

max_single_get_size para downloads

Durante um download, as bibliotecas de cliente de armazenamento fazem uma solicitação de intervalo de download usando max_single_get_size 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é max_chunk_get_size que o download completo seja concluído.

Próximos passos