Lista de verificação de desempenho e escalabilidade para armazenamento em fila

A Microsoft desenvolveu muitas práticas comprovadas para o desenvolvimento de aplicativos de alto desempenho com o Queue Storage. Esta lista de verificação identifica as principais práticas que os desenvolvedores podem seguir para otimizar o desempenho. Tenha essas práticas em mente ao projetar seu aplicativo e durante todo o processo.

O Armazenamento do Azure tem metas de escalabilidade e desempenho para capacidade, taxa de transação e largura de banda. Para obter mais informações sobre as metas de escalabilidade do Armazenamento do Azure, consulte Metas de escalabilidade e desempenho para contas de armazenamento padrão e Metas de escalabilidade e desempenho para o Armazenamento em Fila.

Lista de Verificação

Este artigo organiza práticas comprovadas de desempenho em uma lista de verificação que você pode seguir ao desenvolver seu aplicativo de armazenamento em fila.

Concluído Categoria Consideração do design
  Metas de escalabilidade Você pode projetar seu aplicativo para usar apenas o número máximo de contas de armazenamento?
  Metas de escalabilidade Você está evitando se aproximar dos limites de capacidade e transação?
  Rede Os dispositivos do lado do cliente têm largura de banda suficientemente alta e baixa latência para alcançar o desempenho necessário?
  Rede Os dispositivos do lado do cliente têm um link de rede de alta qualidade?
  Rede O aplicativo cliente está na mesma região que a conta de armazenamento?
  Acesso direto ao cliente Você está usando assinaturas de acesso compartilhado (SAS) e compartilhamento de recursos entre origens (CORS) para habilitar o acesso direto ao Armazenamento do Azure?
  Configuração do .NET Para aplicativos .NET Framework, você configurou seu cliente para usar um número suficiente de conexões simultâneas?
  Configuração do .NET Para aplicativos .NET Framework, você configurou o .NET para usar um número suficiente de threads?
  Paralelismo Você garantiu que o paralelismo seja limitado adequadamente para que você não sobrecarregue os recursos do seu cliente ou se aproxime das metas de escalabilidade?
  Ferramentas Você está usando as versões mais recentes das bibliotecas e ferramentas de cliente fornecidas pela Microsoft?
  Tentativas Você está usando uma política de repetição com um backoff exponencial para erros de limitação e tempos limites?
  Tentativas Seu aplicativo está evitando novas tentativas por erros não repetidos?
  Configuração Você desativou o algoritmo da Nagle para melhorar o desempenho de pequenas solicitações?
  Tamanho da mensagem Suas mensagens são compactas para melhorar o desempenho da fila?
  Recuperação em massa Você está recuperando várias mensagens em uma única operação get?
  Frequência de sondagem Você está pesquisando com frequência suficiente para reduzir a latência percebida do seu aplicativo?
  Mensagem de atualização Você está executando uma operação de mensagem de atualização para armazenar o progresso no processamento de mensagens, para que você possa evitar ter que reprocessar a mensagem inteira se ocorrer um erro?
  Arquitetura Você está usando filas para tornar todo o seu aplicativo mais escalável, mantendo cargas de trabalho de longa execução fora do caminho crítico e, em seguida, dimensionar de forma independente?

Metas de escalabilidade

Se seu aplicativo se aproximar ou exceder qualquer um dos destinos de escalabilidade, ele poderá encontrar latências de transação ou limitação aumentadas. Quando o Armazenamento do Azure limita seu aplicativo, o serviço começa a retornar códigos de erro 503 () ou 500 (Server BusyOperation Timeout). Evitar esses erros permanecendo dentro dos limites das metas de escalabilidade é uma parte importante para melhorar o desempenho do seu aplicativo.

Para obter mais informações sobre destinos de escalabilidade para o Armazenamento em Fila, consulte Metas de desempenho e escalabilidade do Armazenamento do Azure.

Número máximo de contas de armazenamento

Se você estiver se aproximando do número máximo de contas de armazenamento permitido para uma determinada combinação de assinatura/região, está usando várias contas de armazenamento para fragmentar para aumentar a entrada, saída, operações de E/S por segundo (IOPS) ou capacidade? Nesse cenário, a Microsoft recomenda que você aproveite os limites maiores para contas de armazenamento para reduzir o número de contas de armazenamento necessárias para sua carga de trabalho, se possível. Entre em contato com o Suporte do Azure para solicitar limites maiores para sua conta de armazenamento.

Capacidade e metas de transação

Se seu aplicativo estiver se aproximando das metas de escalabilidade para uma única conta de armazenamento, considere adotar uma das seguintes abordagens:

  • Se os destinos de escalabilidade para filas forem insuficientes para seu aplicativo, use várias filas e distribua mensagens entre elas.
  • Reconsidere a carga de trabalho que faz com que seu aplicativo se aproxime ou exceda a meta de escalabilidade. Você pode projetá-lo de forma diferente para usar menos largura de banda ou capacidade, ou menos transações?
  • Se seu aplicativo precisar exceder um dos destinos de escalabilidade, crie várias contas de armazenamento e particione os dados do aplicativo entre essas várias contas de armazenamento. Se você usar esse padrão, certifique-se de projetar seu aplicativo para que possa adicionar mais contas de armazenamento no futuro para balanceamento de carga. As próprias contas de armazenamento não têm nenhum custo além do seu uso em termos de dados armazenados, transações feitas ou dados transferidos.
  • Se seu aplicativo estiver se aproximando dos destinos de largura de banda, considere compactar dados no lado do cliente para reduzir a largura de banda necessária para enviar os dados para o Armazenamento do Azure. Embora a compactação de dados possa economizar largura de banda e melhorar o desempenho da rede, também pode ter efeitos negativos no desempenho. Avalie o impacto no desempenho dos requisitos de processamento adicionais para compactação e descompactação de dados no lado do cliente. Lembre-se de que o armazenamento de dados compactados pode dificultar a solução de problemas porque pode ser mais difícil visualizar os dados usando ferramentas padrão.
  • Se seu aplicativo estiver se aproximando das metas de escalabilidade, certifique-se de que você está usando um backoff exponencial para tentativas. É melhor tentar evitar atingir as metas de escalabilidade implementando as recomendações descritas neste artigo. No entanto, usar um backoff exponencial para novas tentativas impede que seu aplicativo tente novamente rapidamente, o que pode piorar a limitação. Para obter mais informações, consulte a seção Tempo limite e erros de servidor ocupado.

Rede

As restrições de rede física do aplicativo podem ter um impacto significativo no desempenho. As seções a seguir descrevem algumas das limitações que os usuários podem encontrar.

Capacidade de rede do cliente

A largura de banda e a qualidade do link de rede desempenham papéis importantes no desempenho do aplicativo, conforme descrito nas seções a seguir.

Débito

Para a largura de banda, o problema é muitas vezes as capacidades do cliente. Instâncias maiores do Azure têm NICs com maior capacidade, portanto, você deve considerar o uso de uma instância maior ou mais VMs se precisar de limites de rede mais altos de uma única máquina. Se você estiver acessando o Armazenamento do Azure a partir de um aplicativo local, a mesma regra se aplica: entender os recursos de rede do dispositivo cliente e a conectividade de rede com o local de Armazenamento do Azure e melhorá-los conforme necessário ou projetar seu aplicativo para funcionar dentro de seus recursos.

Como em qualquer uso de rede, tenha em mente que as condições de rede que resultam em erros e perda de pacotes retardam a taxa de transferência efetiva. Usar o Wireshark ou o Monitor de Rede pode ajudar no diagnóstico desse problema.

Localização

Em qualquer ambiente distribuído, colocar o cliente perto do servidor proporciona o melhor desempenho. Para acessar o Armazenamento do Azure com a menor latência, o melhor local para seu cliente está dentro da mesma região do Azure. Por exemplo, se você tiver um aplicativo Web do Azure que usa o Armazenamento do Azure, localize ambos em uma única região, como Oeste dos EUA ou Sudeste Asiático. A colocalização de recursos reduz a latência e o custo, já que o uso da largura de banda em uma única região é gratuito.

Se os aplicativos cliente acessarem o Armazenamento do Azure, mas não estiverem hospedados no Azure, como aplicativos de dispositivo móvel ou serviços empresariais locais, localizar a conta de armazenamento em uma região próxima a esses clientes pode reduzir a latência. Se seus clientes estiverem amplamente distribuídos (por exemplo, alguns na América do Norte e outros na Europa), considere usar uma conta de armazenamento por região. Essa abordagem é mais fácil de implementar se os dados que o aplicativo armazena forem específicos para usuários individuais e não exigirem a replicação de dados entre contas de armazenamento.

SAS e CORS

Suponha que você precise autorizar um código como JavaScript em execução no navegador da Web de um usuário ou em um aplicativo de celular para acessar dados no Armazenamento do Azure. Uma abordagem é criar um aplicativo de serviço que atue como um proxy. O dispositivo do usuário é autenticado com o serviço, que, por sua vez, autoriza o acesso aos recursos do Armazenamento do Azure. Desta forma, pode evitar expor as chaves da sua conta de armazenamento em dispositivos inseguros. No entanto, essa abordagem coloca uma sobrecarga significativa no aplicativo de serviço, porque todos os dados transferidos entre o dispositivo do usuário e o Armazenamento do Azure devem passar pelo aplicativo de serviço.

Você pode evitar usar um aplicativo de serviço como um proxy para o Armazenamento do Azure usando assinaturas de acesso compartilhado (SAS). Usando o SAS, você pode habilitar o dispositivo do usuário para fazer solicitações diretamente ao Armazenamento do Azure usando um token de acesso limitado. Por exemplo, se um usuário quiser carregar uma foto para seu aplicativo, seu aplicativo de serviço poderá gerar uma SAS e enviá-la para o dispositivo do usuário. O token SAS pode conceder permissão para gravar em um recurso de Armazenamento do Azure por um intervalo de tempo especificado, após o qual o token SAS expira. Para obter mais informações sobre SAS, consulte Conceder acesso limitado aos recursos do Armazenamento do Azure usando assinaturas de acesso compartilhado (SAS).

Normalmente, um navegador da Web não permite que JavaScript em uma página hospedada por um site em um domínio execute determinadas operações, como operações de gravação, em outro domínio. Conhecida como política de mesma origem, essa política impede que um script mal-intencionado em uma página obtenha acesso a dados em outra página da Web. No entanto, a política de mesma origem pode ser uma limitação ao criar uma solução na nuvem. O compartilhamento de recursos entre origens (CORS) é um recurso do navegador que permite que o domínio de destino comunique ao navegador que confia nas solicitações originadas no domínio de origem.

Por exemplo, suponha que um aplicativo Web em execução no Azure faça uma solicitação de um recurso para uma conta de Armazenamento do Azure. O aplicativo Web é o domínio de origem e a conta de armazenamento é o domínio de destino. Você pode configurar o CORS para qualquer um dos serviços de Armazenamento do Azure para comunicar ao navegador da Web que as solicitações do domínio de origem são confiáveis pelo Armazenamento do Azure. Para obter mais informações sobre CORS, consulte Suporte de compartilhamento de recursos entre origens (CORS) para o Armazenamento do Azure.

Tanto o SAS quanto o CORS podem ajudá-lo a evitar cargas desnecessárias em seu aplicativo Web.

Configuração do .NET

Para projetos que usam o .NET Framework, esta seção lista algumas definições de configuração rápida que você pode usar para fazer melhorias significativas de desempenho. Se você estiver usando um idioma diferente do .NET, verifique se conceitos semelhantes se aplicam no idioma escolhido.

Aumentar o limite de conexão padrão

Nota

Esta seção se aplica a projetos que usam o .NET Framework, pois o pool de conexões é controlado pela classe ServicePointManager. O .NET Core introduziu uma mudança significativa em torno do gerenciamento do pool de conexões, onde o pool de conexões acontece no nível HttpClient e o tamanho do pool não é limitado por padrão. Isso significa que as conexões HTTP são dimensionadas automaticamente para satisfazer sua carga de trabalho. O uso da versão mais recente do .NET é recomendado, quando possível, para aproveitar os aprimoramentos de desempenho.

Para projetos que usam o .NET Framework, você pode usar o código a seguir para aumentar o limite de conexão padrão (que geralmente é 2 em um ambiente de cliente ou 10 em um ambiente de servidor) para 100. Normalmente, você deve definir o valor para aproximadamente o número de threads usados pelo seu aplicativo. Defina o limite de conexão antes de abrir qualquer conexão.

ServicePointManager.DefaultConnectionLimit = 100; //(Or More)  

Para saber mais sobre os limites do pool de conexões no .NET Framework, consulte Limites do pool de conexões do .NET Framework e o novo SDK do Azure para .NET.

Para outras linguagens de programação, consulte a documentação para determinar como definir o limite de conexão.

Aumentar o número mínimo de threads

Se você estiver usando chamadas síncronas juntamente com tarefas assíncronas, convém aumentar o número de threads no pool de threads:

ThreadPool.SetMinThreads(100,100); //(Determine the right number for your application)  

Para obter mais informações, consulte o método ThreadPool.SetMinThreads .

Paralelismo ilimitado

Embora o paralelismo possa ser ótimo para o desempenho, tenha cuidado ao usar paralelismo ilimitado, o que significa que não há limite imposto ao número de threads ou solicitações paralelas. Certifique-se de limitar as solicitações paralelas para carregar ou baixar dados, para acessar várias partições na mesma conta de armazenamento ou para acessar vários itens na mesma partição. Se o paralelismo não for limitado, seu aplicativo poderá exceder os recursos do dispositivo cliente ou os destinos de escalabilidade da conta de armazenamento, resultando em latências e limitações mais longas.

Bibliotecas e ferramentas de clientes

Para obter o melhor desempenho, use sempre as bibliotecas de cliente e as ferramentas mais recentes fornecidas pela Microsoft. As bibliotecas de cliente do Armazenamento do Azure estão disponíveis para vários idiomas. O Armazenamento do Azure também dá suporte ao PowerShell e à CLI do Azure. A Microsoft desenvolve ativamente essas bibliotecas e ferramentas de cliente com o desempenho em mente, mantém-nas atualizadas com as versões de serviço mais recentes e garante que elas lidem com muitas das práticas de desempenho comprovadas internamente. Para obter mais informações, consulte a documentação de referência do Armazenamento do Azure.

Manipular erros de serviço

O Armazenamento do Azure retorna um erro quando o serviço não pode processar uma solicitação. Compreender os erros que podem ser retornados pelo Armazenamento do Azure em um determinado cenário é útil para otimizar o desempenho.

Erros de tempo limite e servidor ocupado

O Armazenamento do Azure pode limitar seu aplicativo se ele se aproximar dos limites de escalabilidade. Em alguns casos, o Armazenamento do Azure pode não conseguir lidar com uma solicitação devido a alguma condição transitória. Em ambos os casos, o serviço pode retornar um erro 503 () ou 500 (Server BusyTimeout). Esses erros também podem ocorrer se o serviço estiver reequilibrando partições de dados para permitir uma taxa de transferência mais alta. O aplicativo cliente normalmente deve tentar novamente a operação que causa um desses erros. No entanto, se o Armazenamento do Azure estiver limitando seu aplicativo porque está excedendo as metas de escalabilidade, ou mesmo se o serviço não pôde atender à solicitação por algum outro motivo, novas tentativas agressivas podem piorar o problema. Recomenda-se o uso de uma política de repetição de recuo exponencial, e as bibliotecas de cliente usam esse comportamento como padrão. Por exemplo, seu aplicativo pode tentar novamente após 2 segundos, depois 4 segundos, depois 10 segundos, depois 30 segundos e, em seguida, desistir completamente. Dessa forma, seu aplicativo reduz significativamente sua carga no serviço, em vez de exacerbar o comportamento que poderia levar à limitação.

Os erros de conectividade podem ser repetidos imediatamente, porque não são o resultado da limitação e espera-se que sejam transitórios.

Erros não repetitivos

As bibliotecas de cliente lidam com novas tentativas com um conhecimento de quais erros podem ser repetidos e quais não podem. No entanto, se você estiver chamando a API REST do Armazenamento do Azure diretamente, há alguns erros que você não deve tentar novamente. Por exemplo, um erro 400 (Bad Request) indica que o aplicativo cliente enviou uma solicitação que não pôde ser processada porque não estava na forma esperada. Reenviar essa solicitação resulta sempre na mesma resposta, portanto, não adianta tentar novamente. Se você estiver chamando a API REST do Armazenamento do Azure diretamente, esteja ciente de possíveis erros e se eles devem ser repetidos.

Para obter mais informações sobre códigos de erro do Armazenamento do Azure, consulte Status e códigos de erro.

Desativar o algoritmo de Nagle

O algoritmo de Nagle é amplamente implementado em redes TCP/IP como um meio de melhorar o desempenho da rede. No entanto, não é ideal em todas as circunstâncias (como ambientes altamente interativos). O algoritmo de Nagle tem um impacto negativo no desempenho de solicitações ao Armazenamento de Tabela do Azure e você deve desativá-lo se possível.

Tamanho da mensagem

O desempenho e a escalabilidade da fila diminuem à medida que o tamanho da mensagem aumenta. Coloque apenas as informações que o recetor precisa em uma mensagem.

Recuperação de lotes

Você pode recuperar até 32 mensagens de uma fila em uma única operação. A recuperação em lote pode reduzir o número de viagens de ida e volta do aplicativo cliente, o que é especialmente útil para ambientes, como dispositivos móveis, com alta latência.

Intervalo de sondagem da fila

A maioria dos aplicativos pesquisa mensagens de uma fila, que pode ser uma das maiores fontes de transações para esse aplicativo. Selecione seu intervalo de sondagem com sabedoria: sondagem com muita frequência pode fazer com que seu aplicativo se aproxime das metas de escalabilidade para a fila. No entanto, em 200.000 transações por US$ 0,01 (no momento da redação), uma sondagem de processador único uma vez a cada segundo durante um mês custaria menos de 15 centavos, portanto, o custo normalmente não é um fator que afeta sua escolha de intervalo de sondagem.

Para obter informações de custo atualizadas, consulte Preços do Armazenamento do Azure.

Executar uma operação de mensagem de atualização

Você pode executar uma operação de mensagem de atualização para aumentar o tempo limite de invisibilidade ou atualizar as informações de estado de uma mensagem. Essa abordagem pode ser mais eficiente do que ter um fluxo de trabalho que passa um trabalho de uma fila para outra, à medida que cada etapa do trabalho é concluída. Seu aplicativo pode salvar o estado do trabalho na mensagem e, em seguida, continuar trabalhando, em vez de enfileirar novamente a mensagem para a próxima etapa do trabalho toda vez que uma etapa for concluída. Lembre-se de que cada operação de mensagem de atualização conta para o destino de escalabilidade.

Arquitetura da aplicação

Use filas para tornar a arquitetura do aplicativo escalável. A seguir estão listadas algumas maneiras de usar filas para tornar seu aplicativo mais escalável:

  • Você pode usar filas para criar listas de pendências de trabalho para processamento e suavizar cargas de trabalho em seu aplicativo. Por exemplo, você pode enfileirar solicitações de usuários para executar um trabalho intensivo do processador, como redimensionar imagens carregadas.
  • Você pode usar filas para separar partes do seu aplicativo para que possa dimensioná-las independentemente. Por exemplo, um front-end da Web pode colocar os resultados da pesquisa dos usuários em uma fila para análise e armazenamento posteriores. Você pode adicionar mais instâncias de função de trabalho para processar os dados da fila conforme necessário.

Próximos passos