Ajuste do desempenho para uploads e downloads com Python
Quando um aplicativo transfere dados usando a biblioteca de clientes do Armazenamento do Microsoft Azure para Python, há vários fatores que podem afetar a velocidade, o uso de memória e até mesmo o êxito ou a falha de 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 aborda várias considerações para ajustar as opções de transferência de dados. Quando ajustada corretamente, a biblioteca de clientes pode distribuir dados com eficiência 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 de uploads
Ajustar corretamente as opções de transferência de dados é fundamental para o desempenho confiável de 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 com suporte varia de acordo com a operação e a versão do serviço. Portanto, verifique a documentação para determinar os limites. Para obter mais informações sobre limites de tamanho de transferência para o Armazenamento de Blobs, confira Dimensionar destinos para armazenamento de Blobs.
Definir opções de transferência de uploads
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 blocos em partes. O padrão é 4 MiB.
max_concurrency
: o número máximo de subtransferências que podem ser usadas paralelamente.
Observação
As bibliotecas de cliente usarão padrões para cada opção de transferência de dados, se não for fornecida. Esses padrões normalmente têm um bom desempenho em um ambiente de data center, mas provavelmente não são adequados para ambientes de consumidor doméstico. As opções de transferência de dados ajustadas de forma incorreta pode 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 argumento max_single_put_size
é o tamanho máximo do blob em bytes para um upload de uma única 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 max_block_size
não limita o valor definido para max_single_put_size
. O argumento max_single_put_size
define uma limitação de tamanho separada de uma solicitação para executar toda a operação de uma só vez, sem subtransferências. Muitas vezes, você deseja que max_single_put_size
seja 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 ter um desempenho melhor, 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
como o mesmo valor usado para max_block_size
.
max_block_size
O argumento max_block_size
é o comprimento máximo de uma transferência em bytes ao carregar um blob de blocos em partes. Conforme mencionado anteriormente, esse valor não limita max_single_put_size
, que pode ser maior que max_block_size
.
Para manter os dados em movimento com eficiência, as bibliotecas de cliente nem sempre podem alcançar o valor max_block_size
de cada transferência. Dependendo da operação, o valor máximo com suporte para o tamanho da transferência pode variar. Para obter mais informações sobre limites de tamanho de transferência para o Armazenamento de Blobs, confira o gráfico em Dimensionar destinos para armazenamento de Blobs.
Exemplo de código
O exemplo de código a seguir mostra como especificar opções de transferência de dados ao criar um objeto BlobClient
e como carregar dados usando esse objeto cliente. Os valores fornecidos neste exemplo não se destinam a ser uma recomendação. Para ajustar adequadamente 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 trabalhos de transferência paralela como 2, usando o argumento max_concurrency
na chamada de método. Essa configuração abre até duas conexões simultaneamente, permitindo que o upload ocorra em paralelo. Durante a instanciação do cliente, definimos o argumento max_single_put_size
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 partes com um tamanho máximo de parte de 4 MiB, conforme definido pelo argumento max_block_size
.
Considerações de desempenho para uploads
Durante um upload, as bibliotecas do cliente de armazenamento dividem um determinado fluxo de upload em vários subuploads 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 objeto BlobClient
, essa operação é Put Block. A biblioteca de clientes de armazenamento gerencia essas operações REST paralelamente (dependendo das opções de transferência) para concluir o upload completo.
Você pode aprender como a biblioteca de clientes lida com o buffer nas seções a seguir.
Observação
Os blobs de blocos têm uma contagem máxima de blocos de 50.000 blocos. Então, o tamanho máximo do blob de blocos é 50.000 vezes max_block_size
.
Buffer durante os uploads
A camada REST de Armazenamento não dá suporte à coleta de 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 de uploads de fluxos, as bibliotecas de clientes de armazenamento colocam os dados em buffer para cada chamada REST individual antes de iniciar o upload. Além das limitações de velocidade de rede, esse comportamento de buffer é motivo para considerar um valor menor para max_block_size
, mesmo ao carregar em sequência. Diminuir o valor de max_block_size
diminui a quantidade máxima de dados armazenados em buffer em cada solicitação e em cada nova tentativa de uma solicitação com falha. Se você estiver enfrentando tempos limite frequentes durante as transferências de dados de um determinado tamanho, a redução do valor de max_block_size
reduz o tempo de armazenamento em buffer e pode resultar em um melhor desempenho.
Por padrão, o SDK armazena em buffer dados de max_block_size
bytes por solicitação de sub-carga simultânea, mas o uso de memória pode ser limitado a 4 MiB por solicitação se as seguintes condições forem atendidas:
- O argumento
max_block_size
deve ser maior quemin_large_block_upload_threshold
. O argumentomin_large_block_upload_threshold
pode ser definido durante a instanciação do cliente e é o tamanho mínimo da parte em bytes necessários para usar o algoritmo de eficiência de memória. O argumentomin_large_block_upload_threshold
define4*1024*1024 + 1
como padrão. - O fluxo fornecido deve ser buscável. Um fluxo pesquisável é um fluxo que dá suporte à consulta e à modificação da posição atual em um fluxo.
- O blob deve ser um blob de blocos.
Embora essa estratégia se aplica a maioria das situações, ainda é possível que mais buffer ocorra se o código estiver usando outros recursos da biblioteca de clientes que exigem buffer.
Ajuste de desempenho de downloads
Ajustar corretamente as opções de transferência de dados é fundamental para o desempenho confiável de 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 de downloads
Os seguintes argumentos podem ser ajustados com base nas necessidades do seu aplicativo:
max_chunk_get_size
: o tamanho máximo da parte usada para baixar um blob. O padrão é 4 MiB.max_concurrency
: o número máximo de subtransferências que podem ser usadas paralelamente.max_single_get_size
: o tamanho máximo para que um blob seja baixado em uma única chamada. Se o tamanho total do blob excedermax_single_get_size
, o restante dos dados de 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 de clientes gerenciarão essas operações REST paralelamente para concluir o download completo.
max_single_get_size for downloads
Durante um download, as bibliotecas do 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 inicial de download, as bibliotecas do cliente sabem o tamanho total do recurso. Se a solicitação inicial tiver baixado todo o conteúdo com êxito, a operação será concluída. Caso contrário, as bibliotecas do cliente continuarão fazendo solicitações de intervalo de até max_chunk_get_size
até que o download completo seja concluído.
Próximas etapas
- Este artigo faz parte do guia para desenvolvedores do Armazenamento de Blobs para Python. Consulte a lista completa de artigos do guia do desenvolvedor em Criar seu aplicativo.
- Para entender mais sobre os fatores que podem influenciar o desempenho das operações do Armazenamento do Azure, confira Latência no Armazenamento de Blobs.
- Para ver uma lista de considerações de design para otimizar o desempenho de aplicativos usando o Armazenamento de Blobs, confira Lista de verificação de desempenho e escalabilidade para Armazenamento de Blobs.