Exportar (0) Imprimir
Expandir Tudo

Banco de dados SQL do Windows Azure e o SQL Server -- Desempenho e escalabilidade comparados e contrastados

Atualizado: janeiro de 2014

Autores: Conor Cunningham, Tobias Ternström, Silvano Coriani, Ewan Fairweather

Coautores: Ralph Squillace, Karthika Raman

Embora o SQL Server e os Bancos de dados SQL do Windows Azure (ou Banco de dados SQL, anteriormente SQL Azure) tenham semelhanças grandes e importantes, eles não são idênticos, e embora as diferenças sejam relativamente pequenas, elas afetam o modo como os aplicativos são executados no Banco de dados SQL comparado ao SQL Server. Como resultado, a arquitetura do aplicativo e as técnicas de avaliação de desempenho para cada plataforma também diferem.

Este documento explica essas diferenças de desempenho, bem como suas causas, e inclui a experiência de clientes na solução de problemas reais de desempenho em Bancos de dados SQL de produção de clientes. Este documento também analisa as técnicas comuns de avaliação de desempenho do SQL Server que não funcionam no Banco de dados SQL. Para obter uma discussão mais ampla sobre o design de aplicativos do Windows Azure em grande escala e de alto desempenho, consulte Práticas recomendadas para o design de serviços em grande escala em serviços de nuvem do Windows Azure.

É importante observar aqui que o SQL Server, além de ser executado no local, também pode ser executado em uma máquina virtual do Windows Azure. As comparações e a abordagem explicadas nesse documento aplicam-se ao SQL Server se estiver sendo executado em um ambiente local ou em uma máquina virtual do Windows Azure. No entanto, quando o SQL Server estiver sendo executado em uma máquina virtual do Windows Azure, há algumas considerações adicionais de desempenho. Isso é explicado em detalhes no artigo Orientação sobre desempenho para o SQL Server em Máquinas Virtuais do Windows Azure.

O Banco de dados SQL do Windows Azure oferece a capacidade de reservar recursos para seu banco de dados pela edição Premium. Para obter mais informações, consulte Diretrizes da edição Premium para Banco de dados SQL do Windows Azure.

A estrutura deste artigo é descrita a seguir.

Primeiro, são descritos vários cenários de aplicativo padrão, bem como os padrões e as abordagens de aplicativo mais comuns.

Segundo, são descritas várias expectativas comuns dos clientes para o Banco de dados SQL e também como as expectativas podem resultar em abordagens com menos êxito.

Terceiro, o tópico se concentra primeiro em padrões clássicos de bom desempenho em ambientes compartilhados e, em seguida, se aprofunda um pouco mais em alguns padrões de desempenho específicos ao Banco de dados SQL.

Quarto, o tópico descreve várias técnicas gerais de avaliação de desempenho para bancos de dados relacionais.

Quinto, o tópico aborda várias técnicas para avaliar adequadamente o desempenho de suas instâncias do Banco de dados SQL, visto que os recursos disponíveis para você diferem daqueles do SQL Server.

Sexto, o apêndice fornece vários scripts SQL que podem ajudá-lo a avaliar e solucionar problemas nas instâncias do Banco de dados SQL.

Quando se trata da análise e otimização de desempenho, padrões de aplicativo diferentes exigem abordagens que variam de acordo com o tipo de arquitetura e os requisitos técnicos. Essas diferenças podem gerar dificuldades na definição de um conjunto comum de práticas recomendadas e técnicas para medir e compreender características de desempenho. Entretanto, há alguns padrões comuns que podem ser usados para categorizar aplicativos e generalizar diretrizes. Esta seção descreve alguns padrões comuns encontrados no Banco de dados SQL do Windows Azure em aplicativos até o momento.

Este grupo contém aplicativos de negócios tradicionais (contabilidade, CRM, ERP e assim por diante) que adotam o modelo de entrega SaaS (software como um serviço). Eles costumam estar relacionados à implementação de um novo modelo de negócios ou voltados a novos segmentos de clientes. Os maiores desafios encontrados por uma empresa de desenvolvimento de software tradicional que passa a adotar um novo modelo de entrega de software são questões relativas à base de código existente e a habilidades e abordagens dos funcionários. Passar para o modelo SaaS significa, inerentemente, adotar um modelo multilocação como forma de hospedar vários clientes no mesmo conjunto de recursos físicos. Isso maximiza investimentos de hardware e reduz custos de gerenciamento, mas geralmente exige um novo design do aplicativo com foco especial no nível da camada de dados para distribuir dados em vários bancos de dados e, ao mesmo tempo, manter a consistência dos dados. Uma expectativa comum é a de que a plataforma apresente um desempenho “exatamente como o equivalente local”, embora o ambiente seja hospedado e os recursos de hardware sejam normalmente compartilhados com outros aplicativos.

Este cenário em geral envolve a migração dos aplicativos existentes de processamento em lotes de um ambiente caro para conseguir economizar em licenciamento e manutenção. Para aplicativos de mainframe, grande parte da lógica de negócios existente (normalmente COBOL) precisará ser mantida inalterada devido à complexidade ou à dificuldade em reter o conhecimento interno necessário para reescrever o código, especialmente se ele foi escrito há muito tempo. Uma avaliação cuidadosa desses ambientes permitirá compreender o nível necessário de ajuste e otimização para viabilizar sua execução com êxito no Azure. Embora isso possa ser entediante, a experiência mostra que esses tipos de aplicativos não têm requisitos estritos de latência e só precisam de taxa de transferência suficiente para concluir grandes trabalhos em lotes no período de tempo necessário.

As plataformas em nuvem como o Windows Azure costumam ser o ambiente ideal para projetos de aplicativos personalizados. Esses aplicativos costumam ser desenvolvidos de acordo com o projeto, implementando novos processos de negócios com base nas estruturas que são desenvolvidas, refinadas e reutilizadas por vários projetos. Um requisito comum para esse tipo de esforço de desenvolvimento de software é a capacidade da plataforma em nuvem de dar suporte a recursos híbridos e de conectividade, como sincronização e replicação de dados, orquestração do processo, integração e assim por diante. O tempo de colocação no mercado e a rapidez no desenvolvimento e na implantação da solução são essenciais para esses tipos de projetos. Isso também exige o uso de meios para descobrir, analisar e resolver imediatamente afunilamentos de desempenho e problemas de escalabilidade.

Esse padrão representa novos projetos de desenvolvimento de software importantes, que foram criados diretamente em um ambiente em nuvem, envolvendo um certo grau de risco para os negócios. Esses tipos de aplicativos são desenvolvidos, testados e colocados em produção na nuvem – e nunca estarão em outro lugar. Devido à complexidade inerente à execução do aplicativo e serviços em escala, é muito importante compreender o comportamento e o desempenho do aplicativo e da plataforma em nuvem que o hospeda para poder compreender melhor como eles se ajustam aos requisitos dos negócios, ao modelo de custo e às expectativas de desempenho e de escala. Executar estes tipos de aplicativos normalmente requer um certo nível de compensação entre o custo de desenvolvimento e os riscos de investimento.

Esse tipo de aplicativo costuma ser uma nova possibilidade: provavelmente ele não teria existido sem o ambiente flexível e altamente escalonável oferecido por plataformas em nuvem. Os provedores de aplicativo antes tentaram implementar o aplicativo usando uma arquitetura tradicional em um data center tradicional, mas não conseguiram devido à carga de trabalho imprevisível gerada pela base de usuários e às dificuldades e custos da design de uma infraestrutura tradicional para o pico de carga, sem falar no gerenciamento após seu design e criação. Os requisitos de alta visibilidade e de negócios críticos exigem uma abordagem inteiramente nova no design e implementação de uma solução totalmente escalonável e particionada na camada de aplicativos e na camada de dados. Com um maior grau de complexidade, a capacidade de analisar e solucionar rapidamente problemas de desempenho do aplicativo ponta a ponta é obrigatória desde as fases iniciais de implementação.

Uma crença comum dos novos usuários do Banco de dados SQL é:

O Banco de dados SQL é uma versão do SQL Server de custo baixo, flexível, altamente disponível e com baixa sobrecarga de gerenciamento, fornecido como um serviço.

Isso é basicamente verdadeiro. O Banco de dados SQL é bem semelhante ao SQL Server:

  • Ele oferece suporte a um grande subconjunto da área de superfície de programação do SQL Server (inclusive suporte ao protocolo TDS & T-SQL, com um banco de dados mestre, usando a autenticação do SQL e assim por diante).

  • Ele reutiliza uma versão do mecanismo do SQL Server para sua funcionalidade do RDBMS principal.

  • Os clientes devem saber o mínimo necessário para começar a trabalhar na nova plataforma.

No entanto, os aplicativos de produção não são criados nesse nível de abstração. Como resultado, ao criar aplicativos, é essencial ultrapassar esse nível de conhecimento e compreender as principais diferenças reais entre o SQL Server e o Banco de dados SQL, porque essas diferenças existem e o que fazer de diferente no Banco de dados SQL para garantir que o aplicativo seja executado com eficiência e êxito.

Veja a seguir três exemplos marcantes em que a experiência no SQL Server difere daquela no Banco de dados SQL. É essencial dominar as três áreas a seguir para criar seu aplicativo de forma que ele seja executado na escala apropriada, com o desempenho adequado e com o menor custo, tanto agora quanto futuramente.

  • Latência

  • Hardware

  • Capacidade de recursos

Mais detalhes sobre cada item são fornecidos abaixo:

 

Conceito SQL Server Banco de dados SQL

Latência

Os servidores são co-alocados e é possível controlar a forma como eles são conectados. A latência típica entre um servidor de aplicativos e o SQL Server é de um submilissegundo. Na maioria dos casos, um aplicativo que executa um grande número de chamadas de banco de dados para concluir uma única operação terá um desempenho aceitável.

No Banco de dados SQL, a comunicação típica entre um serviço do Azure e um Banco de dados SQL ocorre em poucos milissegundos, geralmente em uma magnitude maior do que no local.

Hardware

Empresas adquirem hardware de classe empresarial e há pessoal de TI que garante o uso do computador certo para o trabalho. Falhas no computador são muito raras e não justificam dedicar tempo à criação de resiliência para comandos ou conexões, como repetições automáticas para operações com falha no aplicativo. Atualizações e reparos são realizados em uma agenda divulgada com tempo de inatividade planejado.

O Windows Azure se destina a economizar a nuvem e usa o hardware de mercadoria e computadores semelhantes no serviço inteiro. Esses computadores são menos avançados e tolerantes a falhas do que aqueles em geral usados no local, e o reparo de um computador específico pode ocorrer a qualquer momento. Quando os dados são protegidos por meio de redundância, podem ocorrer erros relativos à conexão.

Capacidade de recursos

Os bancos de dados de um aplicativo normalmente são hospedados em seus próprios computadores sem compartilhar o hardware com outros bancos de dados de aplicativos.

Um único computador hospeda até centenas de bancos de dados, e cada um deles pode potencialmente derivar de diferentes aplicativos e compartilhará recursos do computador. A lógica do serviço move bancos de dados para computadores host diferentes para distribuir a carga de agregação do serviço e fornecer equidade de recursos.

Com a introdução do banco de dados Premium, você agora tem a possibilidade de reservar um determinado nível de capacidade para um Banco de dados SQL do Windows Azure. Ao reservar uma quantidade fixa de capacidade para seu Banco de dados SQL e suas réplicas secundárias, a edição Premium proporcionará um desempenho mais previsível para aplicativos em nuvem em relação às edições Web e Business existentes de Banco de dados SQL.

Os bancos de dados Premium também reduzem bastante os problemas de multilocação quando comparados com outras edições do Banco de dados SQL.

Considerando os exemplos anteriores, quais são as razões mais comuns para que os aplicativos sejam movidos ou criados para o Banco de dados SQL?

  • Elasticidade. Desejamos obter acesso mais rápido à capacidade e sem precisar investir capital em hardware.

  • Baixa sobrecarga de gerenciamento. A maioria da capacidade de gerenciamento é interna no Banco de dados SQL. O mais importante é que a simples execução de CREATE DATABASE fornece logo um banco de dados altamente disponível coberto por 3-4 réplicas em computadores físicos diferentes em racks diferentes.

  • Preço. Desejamos executar nosso serviço a baixo custo.

Apesar de as informações anteriores abrangerem conceitos de alto nível, em vez de diferenças fundamentais na funcionalidade do RDBMS principal, esses conceitos são essenciais para compreender como o mecanismo de banco de dados subjacente será executado. Portanto, é importante levá-los em conta ao criar seu aplicativo.

É importante compreender como fazer as opções certas de criação do aplicativo para minimizar problemas e maximizar benefícios na utilização do Banco de dados SQL.

Enquanto um aplicativo típico do SQL Server pode colocar tudo o que for associado a um aplicativo em um banco de dados (potencialmente grande), um aplicativo típico do Banco de dados SQL do Azure funciona melhor quando as funções principais de um aplicativo são divididas em bancos de dados separados. Esses bancos de dados separados aproveitam os recursos de vários computadores em vez de um, e essa abordagem simplifica a tarefa de dividir funções de trabalho de um único aplicativo em vários bancos de dados à medida que eles crescem.

Em seguida, o uso do hardware de mercadoria e do modelo de manutenção no Banco de dados SQL significa que você deve criar comandos para esperar que algumas operações falhem e precisem ser repetidas. Isso exige que encontremos novas formas de dividir operações em partes menores, evitando o conhecido estado temporário, e tornando operações facilmente reiniciáveis. Esse modelo de programação permite que aplicativos continuem a funcionar quando um servidor de banco de dados faz failover durante a execução do programa.

Aplicativos baseados no Banco de dados SQL também usam abordagens diferentes para solução de problemas e registro em log. Assim como servidores Web, o modelo para solucionar problemas nesses aplicativos é mais adequado para o registro em log do que a solução de problemas ativa (consulta direta a DMVs etc.). Esses fluxos de log se tornam parte do gerenciamento do aplicativo, alimentando painéis que mostram as partes de um aplicativo que são íntegras ou exigem atenção. Quando implementado, esse modelo permite que aplicativos em grande escala tenham menos trabalho em função da maior automação.

A latência é outro aspecto importante a ser considerado em aplicativos de Banco de dados SQL. Como algumas partes do aplicativo não são hospedadas localmente para seus usuários, isso normalmente requer padrões de execução assíncrona/enfileiramento para aumentar a capacidade de resposta do aplicativo. Em outros casos, isso exige que aplicativos considerem como tornar opções mais deliberadas quanto ao número de viagens de ida e volta necessárias para concluir uma operação, comparado a um aplicativo equivalente do SQL Server no local. Essas diferenças aparecem como padrões e áreas de foco diferentes quando um aplicativo é desenvolvido para ser exibido no Banco de dados SQL.

Finalmente, convém realizar testes de desempenho de um aplicativo hospedado no mesmo hardware de produção no qual ele será executado, mas os detalhes de testes de desempenho em hardware compartilhado e hospedado diferem daqueles executados em um conjunto de computadores dedicados. Isso será abordado em maiores detalhes na seção 5 deste documento.

Ao criar um aplicativo, há quatro opções básicas disponíveis para hospedar a parte de SQL do aplicativo:

  1. SQL Server no ferro bruto (ou seja, não virtualizado)

  2. SQL Server em VM no local/hospedado

  3. SQL Server em uma máquina virtual do Windows Azure

  4. Banco de dados SQL do Windows Azure

Ao percorrer as alternativas 1 a 4 nesta ordem, nota-se uma clara movimentação para reduzir custos em OPEX & COGS, mas há uma capacidade reduzida de resolver problemas de desempenho usando técnicas de expansão, como hardware especializado, bem como recursos específicos do SQL Server relacionados ao desempenho. Se existirem problemas de desempenho em um ambiente virtualizado, como o Banco de dados SQL, será necessário fazer alterações no aplicativo para solucioná-los, em vez de aumentar o hardware. Exemplos de alterações em aplicativos são a implementação de algum tipo de padrão de expansão ou a categorização de várias tarefas do aplicativo em segmentos, em que algumas precisam receber mais recursos e ser executadas de forma síncrona (por exemplo, uma transação bancária), enquanto outras tarefas podem ser enfileiradas ou executadas usando menos recursos (um exemplo pode ser o envio de emails com um resumo da conta aos clientes do banco).

Na década passada, buscava-se facilitar aos desenvolvedores a criação de aplicativos com a apresentação e a ampla adoção de tecnologias como mapeadores relacionais de objetos (o Entity Framework, o Hibernate, o NHibernate e assim por diante). Apesar de essas tecnologias criarem uma solução mais rápida, elas também resumem as tarefas principais que estão sendo executadas pelo banco de dados e seu impacto sobre o desempenho, distanciando-se do desenvolvedor. Na era (antes da nuvem), em que a porcentagem típica de uso do data center costuma se manter em um único dígito, até mesmo os aplicativos mais usados baseados nessas tecnologias e que executam chamadas de banco de dados altamente não otimizadas sobreviverão simplesmente pelo excesso de provisionamento de hardware.

Na década passada, o custo real da execução de um aplicativo costumava ser ocultado do desenvolvedor; a maior parte dos desenvolvedores não precisam se preocupar com isso. Quando você pede a clientes sua opinião sobre o custo da execução de seus aplicativos, nota-se um padrão. É claro que esses clientes normalmente sabem quanto gastam em sistemas de grande porte, como o ERP principal, mas os diversos outros aplicativos executados e mantidos são simplesmente “outros aplicativos”. Eles calculam o custo total desses aplicativos considerando apenas o custo total dos aplicativos e subtraindo o custo dos aplicativos principais (como o sistema ERP); os detalhes do custo de um único aplicativo raramente aparecem.

Como muitos clientes não sabem o custo de um único aplicativo, a consciência desse custos não especificado raramente aparece na equipe de desenvolvimento que mantém o aplicativo. Neste ambiente, os desenvolvedores têm pouco incentivo para reduzir o custo operacional do aplicativo. O Windows Azure muda totalmente essa noção, pois uma fatura do provedor em nuvem pode ser dividida no custo de cada VM do Azure, Web e função de trabalho, e do Banco de dados SQL que executa um aplicativo específico.

Não se trata apenas de uma conta; munidos desse conhecimento, os negócios têm as informações que podem ser usadas para tomar decisões relacionadas à escolha certa para corrigir problemas de desempenho do aplicativo. Por exemplo, um problema de desempenho pode ser resolvido desta forma:

  • aumentando os recursos disponíveis no Azure para as funções de trabalho e os bancos de dados do aplicativo

  • usando a opção da edição Premium para reservar recursos como CPU, E/S de Disco e memória.

  • refazendo o arquitetura do aplicativo para reduzir o consumo de recursos faturados

  • passando a usá-lo no local e comprando hardware personalizado

Conclusão

É essencial que desenvolvedores adotem a mentalidade em nuvem do App TCO = custo de desenvolvimento + custo de serviço. Às vezes, a opção certa é investir no desenvolvimento de aplicativos para reduzir o custo de serviços. Em outros momentos, é melhor aumentar os recursos do aplicativo. Essa opção também pode ser afetada pelos skillsets da organização e pela dimensão do problema a ser resolvido. Se houver um forte conhecimento em desenvolvimento de aplicativos, a decisão de implementar alterações no aplicativo para reduzir a demanda por recursos do aplicativo poderá ser fácil, enquanto, em outras situações, talvez seja melhor investir no uso de mais recursos disponíveis na plataforma para atingir as metas de desempenho necessárias.

Para executar aplicativos com eficiência, é importante compreender o uso pelo aplicativo de qualquer serviço de nuvem através da telemetria. No Windows Azure, convém avaliar ótimas ferramentas de terceiros como New Relic ou Opstera, mas também vale a pena considerar soluções personalizadas com base em diagnóstico do Windows Azure. Finalmente, o cuidado em afastar o excesso de complexidade, como no caso do ORM, apresentado antes, pode tornar a busca pela solução de problemas de desempenho ou de escalabilidade muito difícil ou dispendiosa.

Esta seção explicará fatores comuns que afetam o desempenho de operações de banco de dados. A primeira subseção abrange os fatores tradicionais usados no SQL Server. Observe que a maioria deles ainda se aplica ao Banco de dados SQL. A segunda seção aborda as razões que são novidades no Banco de dados SQL. Finalmente, veremos a área de superfície de ferramentas de diagnóstico e solução de problemas fornecidas pelo Banco de dados SQL Azure e usaremos um exemplo prático para mostrar como utilizá-las.

A análise de desempenho no SQL Server tem uma longa história – esta seção deve ajudar a fornecer uma compreensão básica. Para obter mais detalhes, consulte:http://msdn.microsoft.com/pt-br/library/dd672789(v=SQL.100).aspx

O otimizador de consulta do SQL Server faz opções de plano que afetam o desempenho do sistema. Por exemplo, o otimizador pode decidir executar uma pesquisa de índice ou uma verificação de tabela para atender determinada consulta. O otimizador costuma fazer as escolhas certas, mas há casos em que essa escolha é errada porque os dados de entrada (como estatísticas) estão desatualizados ou se uma consulta acessa uma limitação de modelo no otimizador (como a falta de atenção sobre o distorção de dados em junções em todos os casos ao fazer uma estimativa da cardinalidade).

O otimizador pode fazer escolhas de plano erradas individualmente (afetando uma única consulta) ou em combinação (em que o desempenho geral do sistema não é o ideal devido a um conjunto de opções de plano). O otimizador, que não seja a heurística básica de espaço de busca dentro de um plano, não considera a otimização entre planos.

Para obter mais informações sobre o otimizador, consulte o Capítulo Otimizador no SQL Server 2008 Internals (por Conor Cunningham e outros) ou a próxima versão, o SQL Server 2012.

O SQL Server é executado no hardware do usuário; portanto, é responsabilidade do administrador adquirir e configurar esse hardware. Se o cliente não configura o hardware corretamente, isso pode reduzir o desempenho geral do sistema. Exemplos comuns incluem:

  • Opção/versão de driver para vários componentes (como controladores de disco) com configuração errada

  • Configurações BIOS

  • Configuração NUMA/configurações de afinidade da CPU

  • Configurações de memória (memória máxima do servidor etc.)

  • Intervalos de ponto de verificação

  • MAXDOP

Essa situação costuma ser tratada por documentação precisa e testes de pré-aceitação para que o novo hardware possa validar todos os recursos principais do sistema (usando ferramentas como SQLIOSim http://www.microsoft.com/pt-br/download/details.aspx?id=20163)

O bloqueio é usado para permitir que vários usuários façam alterações consistentes nos mesmos dados de forma controlada. Apesar desse bloqueio ser uma parte necessária de um sistema de banco de dados, os bloqueios não são criados da mesma forma. Por exemplo, o otimizador pode criar planos para várias consultas conflitantes, retardando a taxa de transferência total do sistema em comparação com outras opções de plano possíveis. Ocasionalmente, o otimizador pode criar combinações de planos que podem causar deadlocks (por exemplo, quando bloqueios diferentes são adquiridos em ordem oposta em dois ou mais planos). Opções de plano diferentes (ou padrões de chamada de carga de trabalho) costumam ser necessárias para resolver este tipo de situação.

A trava é semelhante ao bloqueio no sentido de que ela adjudica o acesso de vários usuários às estruturas dentro do SQL Server. No entanto, a trava lida com as estruturas de página físicas internas. De certa forma, a trava é ortogonal ao bloqueio, mas os dois problemas podem se aplicar e a solução principal costuma ser semelhante: se houver uma trava ativa, a resposta típica será alterar o padrão de chamada (forçando formas diferentes de plano ou reorganizando o código de chamada) para reduzir o impacto da trava de bloqueio na produção geral.

Mesmo quando o bloqueio não é um problema em operações multiusuário em um banco de dados, ainda é possível que o desempenho ou a produção seja reduzida porque algumas operações não recebem recursos suficientes, enquanto outras têm mais do que o suficiente. Quando a primeira manifestação dessa condição é uma operação mais demorada do que o habitual, a causa interna é que um ou mais recursos estão sob pressão. Os fatores comuns incluem o tipo de espera SOS_SCHEDULER_YIELD (indica que a operação está aguardando na CPU para ser liberada), longas esperas de E/S (indica que o SQL Server está gerando solicitações de E/S acima da capacidade de processamento do sistema de E/S) e RESOURCE_SEMAPHORE (memória). Uma técnica comum para tratar o problema de bloqueio é simplesmente comprar um computador maior ou componentes mais rápidos.

Ponto de verificação é o processo pelo qual o DBMS libera páginas sujas da memória para o disco visando minimizar o tempo que a recuperação levaria se o servidor de banco de dados falhasse. Esse processo pode causar um ponto em operações de E/S que pode prejudicar o desempenho das consultas, bem como afetar a latência e a taxa de transferência. Os aplicativos normalmente precisariam de um teste de carga por um período maior do que a frequência de pontos de verificação, de forma que o impacto do ponto de verificação pudesse ser medido e incluído no planejamento de capacidade e na certificação.

noteObservação
Observe que o SQL Server 2012 contém um recurso chamado “ponto de verificação indireto” (para obter mais informações, consulte http://msdn.microsoft.com/pt-br/library/ms189573.aspx#IndirectChkpt) que pode reduzir a sobrecarga de E/S pontual dos pontos de verificação, distribuindo a carga de E/S do ponto de verificação mais uniformemente em um período de tempo mais longo. Isso pode reduzir o impacto de E/S sobre a solução de problemas de desempenho e de capacidade.

Apenas para declarar novamente: deve ficar claro que o Banco de dados SQL do Windows Azure não é idêntico ao SQL Server. O Banco de dados SQL é um serviço hospedado executado em um data center diferente. Ele é multilocatário, o que significa que vários clientes compartilham o mesmo computador físico. Ele contém recursos automáticos como a alta disponibilidade (HA) automática e backups automáticos. Ele é executado em hardware de mercadoria, e não em grandes servidores. Como um serviço, ele é vendido a clientes como um serviço, e não como uma licença. Todos esses fatores afetam o modelo comercial geral do Banco de dados SQL, bem como a maneira de lidar com considerações de desempenho e de escala.

Além disso, o Banco de dados SQL no momento não apresenta diversos recursos que costumam ser usados em consultas de data warehouse (isso significa que o foco inicial do Banco de dados SQL está em sistemas OLTP). Esses recursos incluem a compactação do banco de dados, consultas paralelas, índices ColumnStore e o particionamento de tabela, além do total suporte ao tamanho do banco de dados e do subsistema de E/S orientado a uma carga de trabalho do data warehouse. Quando não for possível criar soluções de data warehouse usando o Banco de dados SQL hoje, lembre-se de que essas diferenças de recursos afetarão comparações com o SQL Server.

Esta seção explica como cada um desses fatores importantes interfere na solução de problemas de desempenho no Banco de dados SQL, levando a supor que os clientes estão focando soluções OLTP.

Uma das maiores diferenças em relação ao SQL Server é que o Banco de dados SQL expõe um serviço multilocação. Cada computador físico pode ter centenas (ou mais) de bancos de dados de usuário armazenados em um computador. Isso permite que o Banco de dados SQL ofereça um ponto de preço bem baixo (começando por alguns dólares por mês nos EUA). Essa diferença é significativa: por padrão, o Banco de dados SQL tem usuários diferentes que compartilham os recursos de um único computador em um cluster, tentando equilibrar a carga total no cluster movendo clientes para outros computadores em um cluster para tentar maximizar a equidade e equilibrar a carga.

Consequentemente, um cliente que esteja executando um teste de desempenho em seu banco de dados hospedado talvez esteja executando em um sistema que contém vários outros bancos de dados ativos de outros usuários. Assim como no SQL Server, a presença de outros clientes que executam testes no mesmo hardware afeta os resultados do teste de desempenho. Portanto, evite tirar conclusões finais sobre o desempenho do Banco de dados SQL com base em um único teste de desempenho pois outros usuários podem invalidar essas conclusões.

No entanto, você tem a capacidade de reservar recursos para seu banco de dados e as réplicas usando a opção da edição Premium. Com isso, você tem garantia de CPU, E/S de Disco e memória reservadas para seu banco de dados. Você também pode usar essa opção quando precisar dela atualizando para uma edição Premium e fazendo downgrade para uma edição Business ou Web quando a capacidade não for mais necessária.

Usar o banco de dados Premium remove os casos em que a variação de desempenho pode fazer as consultas pequenas demorarem mais do que o esperado em operações sensíveis à latência. Isso também pode permitir a migração de alguns aplicativos locais sem alterações significativas, pois essa é uma experiência mais próxima da experiência tradicional isolada presumida nesses aplicativos. Para obter mais informações, consulte Orientação para banco de dados Premium para Banco de dados SQL do Windows Azure.

O Banco de dados SQL é criado usando grandes clusters de computadores. Individualmente, esses computadores não são em massa; eles são computadores padrão de servidor, baseados em rack, que maximizam um equilíbrio de preço e desempenho, em vez de focar apenas o desempenho geral. Essa diferença é importante, pois muitos aplicativos do SQL Server são criados com base na suposição de que são executados em um computador que é "rápido o suficiente" ou “grande o suficiente “ (isso significa que os clientes comprariam um computador se ficassem sem recursos ao executar o aplicativo). O Banco de dados SQL não inclui hardware avançado em sua oferta hospedada. Em vez disso, é um modelo de “expansão” em vez de um modelo de escala “-” acima. Quando um aplicativo cliente excede os limites de um único computador, a expectativa é de que o cliente reescreva seu banco de dados para usar vários bancos de dados (espalhados por vários computadores), e não um único computador.

O nível de falha do hardware de mercadoria também é superior ao de soluções tradicionais locais. O hardware não tem fontes de alimentação redundantes, memória ECC ou outros recursos para maximizar o tempo de atividade em todos os casos. Além disso, há vários computadores que compõem o cluster que precisam trabalhar juntos para oferecer uma solução completa, na camada de dados e na camada de aplicativos. O SLA atual do Banco de dados SQL é que um banco de dados estará disponível 99,9% do tempo. Ou seja, a instância média do Banco de dados SQL pode estar indisponível por aproximadamente 42 minutos todo mês e, ainda assim, atingir essa meta. Apesar de nem todos os bancos de dados de fato atingirem essa meta, a disponibilidade geral aponta que isso ocorre na maioria dos bancos de dados. Esse valor costuma ser mais baixo do que um sistema tradicional do SQL Server (muitos usuários do SQL Server não medem formalmente o tempo de inatividade, mas os eventos de tempo de inatividade costumam ser planejados e as notificações são enviadas -- As falhas de Banco de dados SQL são mais aleatórias pois geralmente não são planejadas sob a perspectiva do aplicativo). Esse tempo de inatividade indica que o design do aplicativo deve considerar o tempo de inatividade de cada banco de dados em uma solução, usando técnicas que impedem pontos únicos de falha (destacando a remoção dos caminhos críticos que dependem sempre de um único banco de dados estar “ativo"), inclusive o cache em outras camadas quando apropriado, e o uso da lógica de repetição na conexão e de comandos resilientes a falhas no aplicativo e serviço.

Os serviços ou as soluções maiores devem formalmente separar cada função em um ou mais bancos de dados separados. Por exemplo, se um serviço tem um recurso que envia email aos clientes para executar o registro do serviço, talvez seja necessário isolar os dados para esse recurso de outros dados no serviço e até mesmo espalhar os dados de email em vários bancos de dados para tratar a carga alta (se ela exceder a capacidade de um único computador). Não é implausível ter vários conjuntos diferentes de bancos de dados, cada um desempenhando uma função principal diferente, para gerenciar os limites de capacidade de computadores em termos de porte e disponibilidade.

Como há diferenças fundamentais em como grandes soluções são projetadas no Windows Azure, a definição de “desempenho” usada para avaliar soluções do SQL Server provavelmente requer ajustes. Se a execução de uma solução do SQL Server foi melhor antes por causa da aquisição de uma rede SAN, o desempenho para a latência de E/S poderá não ser tão bom quando você não tiver um no Banco de dados SQL. Apesar de a maioria dos mesmos requisitos de negócio principal poderem ser atendidos sem problemas, você não deve avaliar o desempenho bruto do hardware como um método para determinar se o Banco de dados SQL pode resolver um problema de negócios específico. O hardware é mais lento, mas muitas vezes você pode usar vários computadores para obter o mesmo resultado comercial com as metas de desempenho desejadas.

O Banco de dados SQL não contém exatamente o mesmo conjunto de recursos que o SQL Server. As instâncias do Banco de dados SQL são conceitos programáticos – elas representam um banco de dados lógico, e não uma instância específica em um servidor, por exemplo. Além disso, alguns recursos do SQL Server foram bloqueados da superfície de programação do Banco de dados SQL. O Banco de dados SQL hoje não expõe grupos de arquivos ou o particionamento dentro do banco de dados, por exemplo, pois isso não é necessário para paradigmas de programação do Banco de dados SQL padrão. Além disso, alguns casos de uso relacionados ao Data Warehousing avançado (índices ColumnStore) também não são expostos neste momento. Essas diferenças permitem inovações do Banco de dados SQL relacionadas ao modelo de hospedagem, e a maioria desses mesmos benefícios do cliente serão tratados por outras abordagens ao longo do tempo no Banco de dados SQL.

O Banco de dados SQL também busca reduzir custos de trabalho associados à execução, gerenciamento e ajuste de bancos de dados. Como parte desse objetivo, ele inclui os mecanismos automáticos que tratam algumas das tarefas mais comuns-porém-difíceis-de-serem-executadas-perfeitamente tais como:

  • Backups de banco de dados (feitos com intervalos curtos para cada banco de dados ativo)

  • Alta disponibilidade (o Banco de dados SQL oferece isso com pelo menos três réplicas para cada banco de dados sem ação do usuário)

  • Verificações de consistência do banco de dados

  • Atualizações automáticas – o Banco de dados SQL apresentará automaticamente novas versões do serviço de forma bem transparente.

Essas diferenças significam que uma parte da capacidade de cada computador é reservada para executar essas operações. Isso afeta os métodos que podem ser usados para determinar os limites de desempenho máximo para um sistema, assunto abordado mais adiante. A definição formal de metas de desempenho para cada operação comercial ajuda a isolar avaliações de desempenho do impacto desses mecanismos automáticos.

O Windows Azure viabiliza a criação de serviços muito grandes na Internet. Apesar de não ser algo exclusivo do Windows Azure, a experiência necessária para criar essa solução com o SQL Server costuma restringir esse tipo de aplicativo àqueles com boa situação financeira e um forte desejo de realizar isso. Essas soluções avançadas em geral também exigiriam etapas para eliminar ou reduzir o tempo de inatividade de sua solução ou serviço, criando seu código para evitar deixar bancos de dados ou outros componentes inativos. Por exemplo, uma solução sem tempo de inatividade envolveria qualquer solução de alta disponibilidade (HA), como o espelhamento de banco de dados ou bancos de dados sempre ativos, para evitar falhas de hardware ou para orquestrar atualizações de modo que os servidores ficassem inativos apenas por um tempo mínimo. Esta abordagem é essencial para soluções baseadas no Banco de dados SQL, pois grande parte dos aplicativos são serviços e um novo grupo de clientes está tentando criar essas soluções totalmente online nesta nova plataforma.

O Banco de dados SQL já oferece alta disponibilidade interna para a solução principal. O tempo de inatividade causado por atualizações internas para o serviço de Banco de dados SQL é tratado pela mesma lógica de repetição usada para controlar falhas relacionadas ao hardware de mercadoria. O atendimento ao cliente, no entanto, também deve considerar como orquestrar o processo de atualização em várias camadas de um aplicativo. Por exemplo, se um serviço inclui uma camada da Web ou de aplicativo acima de uma camada de dados, uma técnica comum usada em atualizações é:

  • Implantar novos procedimentos armazenados lado a lado com procedimentos armazenados existentes (sp_createaccount_v1, sp_createaccount_v2)

  • Atualizar os computadores da camada de aplicativo (usando a técnica “troca VIP” no Windows Azure) para alternar para a nova versão do aplicativo. A atualização no local é outra opção caso a troca VIP tenha um impacto nos serviços correlacionadas (por exemplo, o cache).

  • Esgote o trabalho existente na versão “v1” dos procedimentos armazenados

  • Quando todo o trabalho anterior for concluído, faça outra alteração que remova as versões “v1” dos procedimentos armazenados

Efetivamente, as atualizações de aplicativo podem ser feitas online, decompondo uma atualização de aplicativo em etapas pequenas que podem ser executadas sem tempo de inatividade. Se algumas etapas exigem tempo de inatividade, então deve haver um empenho para minimizar esse tempo, agendando isso para um número reduzido de clientes internos de cada vez (fora do seu expediente) ou copiando os dados de usuário em um novo banco de dados no plano de fundo de modo que nunca vejam o serviço geral como “inativo”.

Essa mudança de mentalidade requer algumas alterações nas práticas de engenharia, mas a decomposição também permite que você considere soluções como deixar parte de um serviço inativo para atualizações, e não o serviço inteiro. Por exemplo, talvez você possa desabilitar a lógica que mostra a clientes suas contas mensais anteriores, mantendo o serviço principal ativo durante uma operação de atualização. A decomposição necessária para tratar o hardware de mercadoria também oferece a oportunidade de redefinir com mais precisão e minimizar o impacto, visível ao cliente, do tempo de inatividade.

Os clientes precisam determinar se as metas de desempenho devem ser atingidas durante os ciclos de atualização. Em caso afirmativo, o serviço/aplicativo deve ser provisionado para controlar a carga adicional ou a interrupção causada pela própria implantação do serviço.

Muitos clientes implantam o SQL Server e todos os outros componentes de uma solução em uma sub-rede local, o que significa que a latência de rede entre camadas geralmente é insignificante. Quando você move uma solução para a infraestrutura hospedada, pode haver latência adicionada entre o cliente e alguma parte de sua solução. Além disso, as várias camadas no Windows Azure não estarão na mesma sub-rede da rede; portanto, haverá uma pequena diferença de latência entre duas camadas específicas. As soluções do SQL Server que são muito “tagarelas” (elas fazem muitas consultas ou atualizações pequenas) podem perceber que são executadas mais devagar no Banco de dados SQL devido a essas diferenças de rede física. Para aqueles já familiarizados com a computação cliente/servidor, as mesmas soluções se aplicam aqui: reflita sobre viagens de ida e volta entre camadas em uma solução para tratar quaisquer diferenças visíveis de latência.

Aqui estão dois métodos práticos para medir o impacto dessa latência:

  • Implementar um aplicativo simples da Web ou de função de trabalho que executa continuamente uma consulta simples “SELECT 1” em uma instância do Banco de dados SQL do Windows Azure, e rastreamentos iniciam e terminam tempos de resposta.

  • A área de trabalho remota nessa instância Web/função de trabalho e executa o applet do monitor de recursos. Na guia Rede, você encontrará uma grade “Conexão TCP” com uma coluna “Latência (ms)” que oferece uma ideia da latência em suas conexões no Banco de dados SQL (encontre o Endereço IP do servidor virtual de Banco de dados SQL do Windows Azure executando ping ou tracert em seu nome totalmente qualificado, e verifique as conexões com a porta 1433).

Para obter uma discussão completa sobre as práticas recomendadas e otimizações relacionadas à latência, consulte o seguinte artigo de diretrizes do Windows Azure: Considerações sobre desempenho com o Banco de dados SQL do Windows Azure.

Finalmente, às vezes há problemas no próprio serviço de Banco de dados SQL que podem afetar a maneira de realizar a análise de desempenho. Um desses problemas é que o Banco de dados SQL não exibe todos os recursos existentes no SQL Server. Alguns recursos ausentes no Banco de dados SQL do Windows Azure – por exemplo, SQL Profiler -- geralmente são usados para executar a solução de problemas de desempenho para o SQL Server no local. Esse intervalo de recursos resulta da alteração na área da superfície de programação para expor bancos de dados em vez de servidores como o conceito principal no serviço de Banco de dados SQL. Na maioria dos casos, a equipe do SQL pretende oferecer funcionalidade igual ou equivalente em etapas para resolver essas restrições.

Outro problema que pode existir é que o próprio Banco de dados SQL pode conter bugs. Quando os clientes no SQL Server têm sua própria cópia do software, ela é compartilhada no Banco de dados SQL. Ocasionalmente, haverá um bug em nosso software e a equipe do SQL pode precisar solucionar um problema ou bloquear um recurso até que o problema seja resolvido. A equipe do SQL pretende incluir recursos para ajudar a tornar esse processo mais visível e gerenciável para clientes em nosso serviço. Devido às possíveis diferenças de comportamento em diversos clusters do Banco de dados SQL na operação em qualquer momento, a avaliação de desempenho é melhor quando é executada em horários diferentes e em data center diferentes para ajudar a isolar clientes de limitações temporárias no serviço. Esses ajustes removerão a maioria desses fatores que afetam as conclusões tiradas de qualquer teste no serviço.

Esta seção explica algumas técnicas recomendadas para validar e otimizar uma solução do Banco de dados SQL e aborda algumas técnicas específicas a serem evitadas.

Em função das diferenças de plataforma existentes, não faz sentido executar comparações de “maçãs-com-maçãs” com o Banco de dados SQL -- o hardware é diferente e a plataforma tem diferenças que sugerem uma abordagem diferente. Ao migrar soluções existentes, os clientes estão fazendo um grande progresso na plataforma, usando técnicas que determinam o desempenho necessário para operações principais e, depois, determinam como ajustar o código para atender a esses requisitos.

Considere o seguinte exemplo:

Um cliente tem um aplicativo ASP.NET existente no local que faz 10 chamadas para um Banco de dados do SQL Server e renderiza uma página em 2 segundos. Este aplicativo Web está sendo considerado para portabilidade para o Windows Azure, que executa uma função de trabalho de camada Web ou de aplicativo e usando o Banco de dados SQL como o banco de dados. Inicialmente, o cliente decide apenas mover o aplicativo e compilá-lo. Depois de resolver vários problemas para conseguir implantá-lo no Windows Azure, notaram que a página da Web tem agora leva 4 segundos para ser renderizada (2 segundos a menos do que antes). O cliente conclui que a nuvem deve ser “lenta”.

Há vários fatores prováveis que podem explicar essa diferença de latência (todos os exemplos específicos foram extraídos de apontamentos anteriores neste tópico):

  • Pode haver latência entre o chamador e o servidor Web (o chamador está longe do data center e a solicitação demora para ser chegar via Internet)

  • Pode haver um pouco de latência adicional em cada chamada de SQL do aplicativo ASP.NET porque as duas camadas não estão na mesma sub-rede

  • Os computadores que estão sendo usados localmente podem ser diferentes daqueles usados pelo Banco de dados SQL

  • Os planos de consulta podem ser diferentes

O aspecto mais importante é que você não deve tentar comparar o desempenho do SQL Server e do Banco de dados SQL para soluções existentes – há muitas razões para a existência de diferenças. Concentre-se diretamente na pergunta importante: o nível de desempenho é necessário para resolver o problema de negócios? Nesse caso, se o requisito é que a página da Web é renderizada para o cliente em dois segundos, portanto há várias maneiras diferentes de conseguir isso na plataforma do Windows Azure (embora a solução exata possa diferir entre uma solução do SQL Server no local, uma solução das máquinas virtuais do Windows Azure (IaaS) e o Banco de dados SQL). Possíveis alterações a serem consideradas para que este exemplo melhore o desempenho para cumprir a segunda meta:

  • Determinar a latência entre o cliente e o servidor Web (criar uma página de teste da Web e medir o tempo de resposta para uma página da Web que não precise contatar um banco de dados). Se esse é um fator importante, então procure localizar um data center mais próximo para reduzir a latência e/ou use uma rede de distribuição de conteúdo (CDN) para reduzir a latência percebida pelo cliente, armazenando em cache o conteúdo mais próximo de cada usuário.

  • Considere se é possível combinar viagens de ida e volta do aplicativo ASP.NET para reduzir qualquer sobrecarga de rede física associada entre camadas. Isso pode aumentar um pouco a latência também.

  • Examine o tempo de execução de cada consulta, e procure os planos de consulta lentos que podem ser melhorados, bloqueios que podem ser eliminados ou recursos de banco de dados que podem ser incluídos. Se necessário, defina metas de desempenho para cada operação e repita a técnica em cada sub-problema.

  • Determine quanto teste de estresse pode ser realizado no banco de dados antes de ser limitado (observe os novos DMVs sys.event_log e sys.database_connection_stats no banco de dados mestre) para compreender se é necessário considerar:

    • Reduzindo o número de conexões em nível de aplicativo

    • Expandindo o modelo de dados através da adição de mais bancos de dados para obter o nível de produção que você precisa atingir

A consideração importante é iniciar com o problema comercial e definir metas, em vez de tentar determinar se o Banco de dados SQL tem o mesmo desempenho que o SQL Server; provavelmente ele será diferente.

Quando você encontra um problema de desempenho, geralmente convém tentar afastar o problema de todas as outras fontes de uso e variação de recursos. Ainda em relação ao exemplo anterior, digamos que uma consulta específica terminou consumindo 3 segundos do tempo total. Retire essa consulta e execute-a diretamente no banco de dados (talvez dentro de um procedimento armazenado chamado do SQL Server Management Studio) para isolar a consulta de solução original. Talvez o aplicativo Web esteja malconfigurado ou talvez a consulta tenha um plano errado. A execução de testes isolados remove as causas em potencial e ajuda a isolar rapidamente problemas centrais a serem resolvidos. Às vezes, talvez faça sentido desmembrar a operação de baixo desempenho (por exemplo: removendo partes-chave de um texto da consulta) para identificar o ponto em que esse problema de desempenho não ocorra mais e a operação volte “a ser rápida”. Essa técnica é frequentemente usada pela equipe do produto SQL para ajudar clientes a isolar problemas. A adição de configurações SET STATISTICS IO ON e SET STATISTICS TIME ON no nível de conexão pode ajudar a fornecer detalhes adicionais sobre o desempenho da execução.

A infraestrutura hospedada pode ser de mais difícil solução. Não é possível observar diretamente os contadores de desempenho ou outros dados que estão disponíveis em implantações no local. A capacidade de repetir um teste com log (talvez armazenado em um banco de dados diferente para não afetar os resultados) é muito útil porque esse teste pode ser implantado em data centers diferentes. Apesar de o hardware usado em cada data center hoje ser em grande parte semelhante, há algumas diferenças e elas podem aparecer em testes específicos, especialmente em um cenário de cliente com requisitos rígidos de latência em uma operação específica. Após determinar que uma operação específica é essencial, você deve validar esse exemplo isolado em cada data center onde é planejada a implantação do aplicativo. Nem todos os clientes têm um pacote de testes formal de desempenho, e esta etapa também pode ajudar em validações no local.

Em ambientes isolados, nem sempre é necessário considerar o desempenho de uma operação em diversas execuções. Os ambientes compartilhados variar muito devido às operações do sistema em segundo plano, bem como ao impacto de outros locatários no sistema. Consequentemente, é útil fazer o teste repetível e executá-lo várias vezes. A coleta dos resultados de diversas execuções frequentemente mostrará uma variação do desempenho em chamadas e você pode avaliar isso representando graficamente a distribuição percentual para determinada operação repetida.

Considere o seguinte exemplo:

Uma consulta de cliente tem um requisito desejado de latência para uma operação de 20 ms e, ao executar a consulta 1000 vezes, o cliente nota que a média é de 26,95 ms. Ao examinarmos a distribuição percentual da latência em todas as chamadas, observamos que os dados têm esta aparência:

(O eixo x é o percentual para determinado teste de execução da mesma consulta N vezes. O eixo y é a latência em milissegundos).

O interessante é que a distribuição de dados não é uniforme -- há um pico na extremidade superior do conjunto de dados. Deve ficar claro que não basta verificar a média pois isso pode ser decepcionante. Muitas curvas de resposta de latência são exponenciais; é possível descrevê-las escolhendo alguns pontos essenciais ao longo da curva e descrevendo a latência em percentuais chaves:

 

Média

26.95 ms

50%

15 ms

95%

21 ms

99%

80 ms

99,9%

1044 ms

Para este exemplo, o problema principal aparece na parte final da distribuição de dados. Há um ponto de dados ocasional que é bem pior do que os outros. Esta forma de capturar e descrever o problema ajudará a explicar que o problema não reside no caso comum -- trata-se de um problema em algumas situações raras mas importantes.

Esse exemplo pode ocorrer em ambientes compartilhados e em geral se relaciona a um pacote TCP removido em um dos roteadores ao longo do caminho usado na solução. Se o pacote for removido, o TCP acabará repetindo após cerca de um segundo. Nesse caso, a causa provável desse problema é o congestionamento da rede. Se esse problema ocorre com relativa alta frequência, isso pode indicar que há um problema no hardware da rede (o que significa que você deve contatar o atendimento ao cliente da Microsoft) ou talvez haja algum outro problema que afete os resultados.

Você deve usar o log e as estatísticas de dados que caracterizam a distribuição para isolar problemas e, depois, decidir se eles são essenciais para o negócio. Essa área de análise é um problema real (embora o exemplo anterior tenha sido criado para ilustrar o problema). Quando ocorrem problemas como esse com clientes reais, alguns clientes ignoram as situações anômalas (o que significa que são irrelevantes para seus negócios e eles mudam seus requisitos para se concentrar em 50% das vezes, e não na média); já em outros casos (ao trabalhar em instalações locais), eles substituem o hardware para corrigir problemas reais encontrados em roteadores de rede usando essa técnica após o isolamento do problema.

Da mesma forma que a abordagem de arquitetura e desenvolvimento precisa se ajustar a esse ambiente em nuvem, a mentalidade operacional também precisa mudar. Implementar um sistema efetivo no Banco de dados SQL Azure exige processos operacionais que são adaptados para o ambiente em nuvem. A abordagem e as técnicas tradicionais usadas para ter uma noção sobre o uso de recursos e a eficiência, além de detectar erros, precisam ser alteradas e reavaliadas para garantir sua eficácia na tomada de decisões operacionais em um ambiente multilocatário.

Essa seção apresenta exemplos práticos de técnicas que podem ser usadas em um Banco de dados SQL do Windows Azure para obter ideias acionáveis. Ela usa exemplos práticos para solucionar, isolar e resolver problemas reais de clientes, além de destacar as ferramentas que estão disponíveis e como utilizá-las.

O Banco de dados SQL expõe várias exibições de gerenciamento dinâmico (DMVs) que podem ser usadas para compreender o consumo de recursos e identificar condições de falha.

A abordagem recomendada atual é:

  • Identificar consumidores de recursos: Use DMVs em nível de banco de dados para identificar os principais consumidores de recursos, e monitore a execução e a eficiência de consultas (por exemplo, usando sys.dm_exec_query_stats e sys.dm_db_missing_index_details)

  • Usar uma abordagem Delta: regularmente, tire instantâneos das solicitações executadas no momento no Banco de dados SQL para verificar casos de bloqueio, trava e outros problemas de contenção (por exemplo, usando sys.dm_exec_requests)

  • Monitorar para detectar erros: monitore DMVs do banco de dados mestre para verificar se há problemas relacionados a conexão, como limitação (por exemplo, usando sys.event_log e sys.database_connection_stats)

  • Monitorar consumo de recursos do banco de dados: monitore o DMV sys.resource_stats para observar o consumo de recursos do banco de dados ao longo do tempo.

Alguns dos DMVs contêm informações cumulativas da última vez em que o Banco de dados SQL do Windows Azure foi movido (um exemplo é sys.dm_exec_query_stats). Outros contêm um instantâneo de algum momento (sys.dm_exec_requests). O desempenho de uma consulta é afetado pela disponibilidade de recursos, simultaneidade nos nós primários e secundários em que a instância do Banco de dados SQL reside naquele momento, bem como problemas de aplicativo como o bloqueio. No ambiente local, sys.dm_os_wait_stats costuma ser usado em conjunto com sys.dm_exec_query_stats para compreender o desempenho da consulta e restrições de recursos, que podem ser inferidos de informações de espera do sistema. O sys.dm_db_wait_stats fornece uma exibição agregada de todas as esperas encontradas por threads executados durante as operações. Por exemplo, as esperas de bloqueio indicam a contenção de dados por consultas e as esperas de trava de ES de página indicam tempos de resposta de ES lentos.

Outra técnica também é possível:

  • Crie um instantâneo inicial de estatísticas de consulta no início do período de monitoramento. Registre isso em uma tabela temporária ou em uma tabela física.

  • Crie regularmente instantâneos de solicitações de execução durante o período de monitoramento.

  • Crie um segundo instantâneo de estatísticas de consulta.

  • Compare o delta entre os instantâneos e use as informações de solicitações de execução para compreender se os bloqueios ou as esperas de recursos afetam o desempenho da consulta.

Um cliente teve um problema no qual as solicitações de usuários eram lentas de um aplicativo Web chamado Banco de dados SQL do Windows Azure.

O script a seguir identifica os lotes principais executados em sua instância do Banco de dados SQL. Este exemplo exibe os pedidos pelo tempo total de CPU para identificar a consulta que mais usa a CPU. O mesmo padrão da consulta, a ordenação em atributos diferentes, pode encontrar outros grandes consumidores de cada tipo de recurso (E/S lógica, tempo decorrido e assim por diante). Em muitos sistemas transacionais, o principais resultados são consistentes (por exemplo, os principais consumidores agregados de CPU também consomem a maioria dos recursos de E/S).

/* Top batches by total CPU time No execution plan
**************************************/
SELECT TOP(25)
SUBSTRING (st.text,1, 512),
SUM(qs.total_worker_time) AS total_cpu_time, 
SUM(qs.total_elapsed_time) AS total_elapsed_time,
CAST((CAST(SUM(qs.total_worker_time) AS decimal) / cast(SUM(qs.total_elapsed_time) AS decimal) * 100) AS int)  AS cpu_vs_elapsed_percentage,
SUM(qs.execution_count) AS total_execution_count,
SUM(qs.total_worker_time)/SUM(qs.execution_count) AS average_cpu_time,
SUM(qs.total_elapsed_time)/SUM(qs.execution_count) AS average_elapsed_time,
SUM(qs.total_logical_reads) AStotal_logical_reads,
SUM(qs.total_logical_reads)/SUM(qs.execution_count) AS average_logical_reads,
SUM(qs.total_logical_writes) AS total_logical_writes,
COUNT(*) AS number_of_statements,
qs.plan_handle,
db_name(st.dbid) AS  [database name],
st.objectid
FROM sys.dm_exec_query_stats AS qs
CROSS APPLY sys.dm_exec_sql_text(sql_handle) AS st
GROUP BY st.text, qs.plan_handle, db_name(st.dbid), st.objectid
ORDER BY SUM(qs.total_worker_time) DESC
   

Neste exemplo, o procedimento armazenado dbo.spGetTranslationTable está consumindo a CPU 42 vezes mais do que o próximo lote.

Para determinar a utilização de recursos e a eficiência de determinada consulta, uma técnica comum é executá-la isoladamente usando o SQL Server Management Studio (SSMS). As opções SET STATISTICS IO e TIME podem ser usadas para fornecer informações úteis, e o plano de execução real também pode ser obtido. Isto é ilustrado abaixo:

SET STATISTICS IO ON;
SET STATISTICS TIME ON;
exe [dbo].[spGetTranslationTable] @lang='en'

Neste exemplo, a consulta consumiu 900 leituras lógicas da tabela de conversão. Observe que o plano de consulta é resultado de uma verificação do índice clusterizado de conversões para retornar um subconjunto relativamente pequeno de linhas. A criação de um novo índice na tabela reduziu a E/S lógica e solucionou o problema.

sys.dm_exec_requests fornece dados sobre o desempenho da consulta como tipos de bloqueio e de espera. (Para obter um exemplo de consulta, consulte o instantâneo de sys.dm_exec_requests com WAIT TYPE e WAIT TIME na seção de apêndice a seguir). Alguns novos tipos de espera adicionais foram implementados no Banco de dados SQL para representar a funcionalidade específica do Banco de dados SQL. Os tipos de espera SE_REPL_SLOW_SECONDARY_THROTTLE e SE_REPLY_COMMIT_ACK estão relacionados ao mecanismo de replicação de log usado pelo Banco de dados SQL para atender à sua meta de disponibilidade e fornecer elasticidade. Se essas esperas estão presentes nos resultados de DMV, isso em geral indica a pressão de E/S no canal de replicação. Atenuantes incluem:

  • Minimizar operações DML

  • Gerenciar o tamanho de inserções de lotes de aplicativos e tamanhos de transações

  • Reduzir o número total de inserções de aplicativos

  • Gerenciar cuidadosamente operações de banco de dados como a manutenção de índice

TipDica
Se períodos contínuos de bloqueio de SE_REPL afetarem significativamente um aplicativo, contate o atendimento ao cliente da Microsoft para obter assistência.

Se a carga em um banco de dados causa esperas de SE_REPL ou se o banco de dados está limitado pelo Windows Azure, há várias opções. Para cargas de trabalho com gravação intensa, considere fragmentar os dados para particioná-los em vários bancos de dados. Ambos os casos reduzem a carga em um nó no sistema e reduzem o risco de que um único computador de banco de dados passe por uma situação em que a limitação ou o bloqueio possam afetar o aplicativo inteiro. Para cargas de trabalho com leitura intensa, procure usar uma tecnologia de cache distribuído (como o Windows Azure Caching) para armazenar em cache as informações do banco de dados e, assim, consultá-las com menos frequência.

Instantâneo mostrando SE_REPL_SLOW_SECONDARY_THROTTLE:

Instantâneo mostrando SE_REPL_COMMIT_ACK:

A área da superfície do Banco de dados SQL do Windows Azure está sendo estendida continuamente para fornecer DMVs adicionais e outras informações de solução de problemas. Estes DMVs relacionados a índice foram habilitados no Banco de dados SQL:

  • sys.dm_db_index_usage_stats

  • sys.dm_db_missing_index_details

  • sys.dm_db_missing_index_group_stats

  • sys.dm_db_missing_index_groups

A consulta mostrada na seção Análise de Índices Ausentes (no apêndice, a seguir) identifica recomendações de índices ausentes praticamente da mesma forma que você interagiria com o SQL Server. Essas informações também estão disponíveis no plano de execução obtido do cache do plano ou através do SSMS. As capturas de tela a seguir ilustram isso.

Cada Banco de dados SQL é membro de um servidor virtual (isto é, um servidor lógico). Esse servidor lógico tem um banco de dados mestre, que agora foi estendido para fornecer os DMVs sys.event_log e sys.database_connection_stats. A exibição sys.database_connection_stats fornece um rollup de quantas conexões TDS são concluídas com êxito, encerradas ou limitadas em uma janela de agregação de cinco minutos. A exibição sys.event_log fornece mais informações sobre conexões de Banco de dados SQL com êxito, bem como falhas de conexão, deadlock e eventos de limitação. Esses DMVs permitem que você solucione rapidamente problemas de conectividade do aplicativo.

Para obter mais informações, consulte:

http://blogs.msdn.com/b/wayneb/archive/2012/11/02/introducing-sys-database-connection-stats-for-troubleshooting-windows-azure-sql-database.aspx

http://blogs.msdn.com/b/windowsazure/archive/2012/11/05/announcing-new-dynamic-management-views-for-windows-azure-sql-database.aspx

O DMV sys.resource_stats fornece uma exibição do consumo de recursos ao longo do tempo. Esse DMV pode ser usado para investigar o uso de recursos e para o planejamento de capacidade para seu aplicativo.

Consulte para retornar todas as informações no DMV sys.resource_stats nos últimos 7 dias:

SELECT * FROM sys.resource_stats
WHERE  database_name = 'MyTestDB' AND start_time > DATEADD(day, -7, GETDATE())

Capturas de tela dos resultados retornados:

Consulte para retornar o uso médio e máximo de recursos para um banco de dados nos últimos 7 dias:

SELECT 
    avg(avg_cpu_cores_used) AS 'Average CPU Cores Used',
    max(avg_cpu_cores_used) AS 'Maximum CPU Cores Used',
    avg(avg_physical_read_iops + avg_physical_write_iops) AS 'Average Physical IOPS',
    max(avg_physical_read_iops + avg_physical_write_iops) AS 'Maximum Physical IOPS',
    avg(active_memory_used_kb / (1024.0 * 1024.0)) AS 'Average Memory Used in GB',
    max(active_memory_used_kb / (1024.0 * 1024.0)) AS 'Maximum Memory Used in GB',
    avg(active_session_count) AS 'Average # of Sessions',
    max(active_session_count) AS 'Maximum # of Sessions',
    avg(active_worker_count) AS 'Average # of Workers',
    max(active_worker_count) AS 'Maximum # of Workers'
FROM sys.resource_stats 
WHERE  database_name = 'MyTestDB' AND start_time > DATEADD(day, -7, GETDATE())

Captura de tela dos resultados retornados:

Consulta para determinar o uso de mais de um único núcleo:

SELECT
(SELECT
    SUM(DATEDIFF(minute, start_time, end_time))
    FROM sys.resource_stats
    WHERE database_name = 'MyTestDB' AND 
          start_time > DATEADD(day, -7, GETDATE()) AND
          avg_cpu_cores_used > 1.0) * 1.0 / SUM(DATEDIFF(minute, start_time, end_time)
) AS percenage_more_than_1_core
FROM sys.resource_stats
WHERE database_name = 'MyTestDB' AND start_time > DATEADD(day, -7, GETDATE())

Captura de tela dos resultados retornados:

As consultas abordadas nesta seção podem ser usadas para solucionar problemas e localizar os limites de um único banco de dados.

/* Top statements by total CPU time w/ query plan on the statement level 
note - can be expensive to run this 
**requires** statement_level_query_plan.sql
************************************************************************/
SELECT TOP(25)
SUBSTRING(qt.text,qs.statement_start_offset/2, 
(CASE WHEN qs.statement_end_offset = -1 
THEN len(convert(nvarchar(max), qt.text)) * 2 
ELSE qs.statement_end_offset END -qs.statement_start_offset)/2) 
AS statement_text,
SUBSTRING (qt.text , 1, 512) AS batch_text,
qs.total_worker_time,
qs.total_elapsed_time,
CAST((CAST(qs.total_worker_time AS decimal) / cast(qs.total_elapsed_time AS decimal) * 100) AS int)  AS cpu_vs_elapsed_percentage,
qs.total_worker_time/qs.execution_count AS average_cpu_time,
qs.total_elapsed_time/qs.execution_count AS average_elapsed_time,
qs.total_logical_reads,
qs.execution_count, 
qs.total_logical_reads/qs.execution_count AS average_logical_reads,
db_name(qt.dbid) AS [database name],
qt.objectid,
pln.statement_plan
FROM sys.dm_exec_query_stats qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) AS qt
CROSS APPLY master.dbo.statement_level_query_plan(plan_handle) AS pln
WHERE statement_text LIKE
'%' + REPLACE(LEFT(SUBSTRING((select text from master.sys.dm_exec_sql_text(sql_handle)), 
statement_start_offset/2, 1 + CASE WHEN statement_end_offset = -1 
THEN LEN((SELECT text FROM master.sys.dm_exec_sql_text(sql_handle))) - statement_start_offset/2
ELSE statement_end_offset/2 - statement_start_offset/2 
END) 
,3000), '[','[[]') + '%'
ORDER BY qs.total_worker_time DESC  

-- TOP 50 Query Plans in SQL Azure Database
SELECT TOP(50)
            CONVERT(bigint, DATEPART(yyyy,getdate())*10000000000)+(DATEPART(mm,getdate())*100000000)+(DATEPART(dd,GETDATE())*1000000)+(DATEPART(hh,GETDATE())*10000)+(DATEPART(mi,GETDATE())*100)+(DATEPART(ss,GETDATE())) AS timestampKey ,
                GETDATE() AS eventdateUTC,
            CONVERT(decimal(8,2),(CAST(qs.execution_count AS FLOAT)/(DATEDIFF(mi,qs.creation_time,qs.last_execution_time)+1))*(((CAST(qs.total_worker_time AS FLOAT) / qs.execution_count) / 100000.00)+((CAST(qs.total_elapsed_time AS float) / qs.execution_count) / 1000000.00))) AS Weighting,
            query_plan.value('declare default element namespace "http://schemas.microsoft.com/sqlserver/2004/07/showplan"; 
                            (/ShowPlanXML//Object/@Index)[1]', 'varchar(255)') AS IndexName, 
            qp.query_plan,
                    CASE WHEN query_plan.exist('
                        declare default element namespace "http://schemas.microsoft.com/sqlserver/2004/07/showplan"; 
                        /ShowPlanXML/BatchSequence/Batch/Statements//RelOp/@PhysicalOp[. = "Hash Match"]'
                               )=1 THEN 1 ELSE 0 END AS hash_match
                    , CASE WHEN query_plan.exist('
                        declare default element namespace "http://schemas.microsoft.com/sqlserver/2004/07/showplan"; 
                        /ShowPlanXML/BatchSequence/Batch/Statements//RelOp/@PhysicalOp[. = "Table Scan"]'
                               )=1 THEN 1 ELSE 0 END AS table_scan
                    , CASE WHEN query_plan.exist('
                        declare default element namespace "http://schemas.microsoft.com/sqlserver/2004/07/showplan"; 
                        /ShowPlanXML/BatchSequence/Batch/Statements//RelOp/@PhysicalOp[. = "Clustered Index Scan"]'
                               )=1 THEN 1 ELSE 0 END AS clustered_index_scan
            ,SUBSTRING(qt.text,qs.statement_start_offset/2+1, 
            (CASE WHEN qs.statement_end_offset = -1 
            THEN LEN(CONVERT(nvarchar(max), qt.text)) * 2 
            ELSE qs.statement_end_offset END -qs.statement_start_offset)/2) 
            AS statement_text,
            qs.total_worker_time/qs.execution_count AS average_cpu_time,
            qs.total_elapsed_time/qs.execution_count AS average_elapsed_time,
            qs.total_logical_reads/qs.execution_count AS average_logical_reads,
            qs.total_logical_writes/qs.execution_count AS average_logical_writes,
            qs.execution_count,
            qs.plan_generation_num,
            qs.total_worker_time,
            qs.total_elapsed_time,
            qs.total_logical_reads,
            qs.total_logical_writes,
            db_name() AS [db_name],
            qt.objectid,
            qs.query_hash, 
            qs.creation_time,
            qs.last_execution_time
            FROM sys.dm_exec_query_stats qs
            CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) AS qt
            CROSS APPLY sys.dm_exec_query_plan(qs.plan_handle) AS qp
            WHERE qt.text NOT LIKE '%sys.%'
            ORDER BY qs.total_elapsed_time DESC

-- Snapshot of current sys.dm_exec_requests with WAIT TYPE and WAIT TIME
declare @i int = 0
                    DECLARE @Requests TABLE (
                    [timestampKey] [bigint] NULL,
                    [eventdateUTC] [datetime] NOT NULL,
                    [statement_text] [nvarchar](max) NULL,
                    [command] [nvarchar](32) NOT NULL,
                    [cpu_time] [int] NOT NULL,
                    [total_elapsed_time] [int] NOT NULL,
                    [wait_type] [nvarchar](60) NULL,
                    [wait_time] [int] NOT NULL,
                    [last_wait_type] [nvarchar](60) NULL,
                    [wait_resource] [nvarchar](60) NOT NULL,
                    [reads] [bigint] NOT NULL,
                    [writes] [bigint] NOT NULL,
                    [logical_reads] [bigint] NOT NULL,
                    [row_count] [bigint] NOT NULL,
                    [granted_query_memory] [int] NOT NULL,
                    [query_hash] [binary](8) NULL,
                    [query_plan] [xml] NULL,
                    [hash_match] [bit] NULL,
                    [table_scan] [bit] NULL,
                    [clustered_index_scan] [bit] NULL,
                    [session_id] [smallint] NOT NULL,
                    [blocking_session_id] [smallint] NULL,
                    [start_time] [datetime] NOT NULL,
                    [status] [nvarchar](30) NOT NULL,
                    [db_name] [nvarchar](128) NULL
                    )

                    WHILE(@i < 20)
                    BEGIN
                    INSERT INTO @Requests
                    SELECT 
                    CONVERT(bigint, datepart(yyyy,getdate())*10000000000)+(datepart(mm,getdate())*100000000)+(datepart(dd,getdate())*1000000)+(datepart(hh,getdate())*10000)+(datepart(mi,getdate())*100)+(datepart(ss,getdate())) as timestampKey ,
                    getdate() as eventdateUTC,
                    SUBSTRING(t.text,r.statement_start_offset/2+1,(case when r.statement_end_offset = -1 then len(convert(nvarchar(max), t.text)) * 2 else r.statement_end_offset end -r.statement_start_offset)/2) as statement_text, 
                    command,
                    cpu_time,
                    total_elapsed_time,
                    wait_type,
                    wait_time,
                    last_wait_type,
                    wait_resource,
                    reads,
                    writes,
                    logical_reads,
                    row_count,
                    granted_query_memory,
                    query_hash,
                    query_plan,
                    case when query_plan.exist('
                        declare default element namespace "http://schemas.microsoft.com/sqlserver/2004/07/showplan"; 
                        /ShowPlanXML/BatchSequence/Batch/Statements//RelOp/@PhysicalOp[. = "Hash Match"]'
                               )=1 then 1 else 0 end as hash_match
                    , case when query_plan.exist('
                        declare default element namespace "http://schemas.microsoft.com/sqlserver/2004/07/showplan"; 
                        /ShowPlanXML/BatchSequence/Batch/Statements//RelOp/@PhysicalOp[. = "Table Scan"]'
                               )=1 then 1 else 0 end as table_scan
                    , case when query_plan.exist('
                        declare default element namespace "http://schemas.microsoft.com/sqlserver/2004/07/showplan"; 
                        /ShowPlanXML/BatchSequence/Batch/Statements//RelOp/@PhysicalOp[. = "Clustered Index Scan"]'
                               )=1 then 1 else 0 end as clustered_index_scan
                    ,session_id,
                    blocking_session_id,
                    start_time,
                    status,
                    db_name() as [db_name] 
                    FROM 
                    sys.dm_exec_requests r
                    cross apply sys.dm_exec_sql_text(r.sql_handle) t
                    cross apply sys.dm_exec_query_plan(r.plan_handle) p
                    WHERE @@spid<>r.session_id
                       waitfor delay '00:00:00:100'
                       set @i = @i+1
                    end
                    select * from @Requests;

-- Missing indexes stats
SELECT  CONVERT(bigint,datepart(yyyy,getdate())*10000000000)+(datepart(mm,getdate())*100000000)+(datepart(dd,getdate())*1000000)+(datepart(hh,getdate())*10000)+(datepart(mi,getdate())*100)+(datepart(ss,getdate())) [timestampKey] 
 ,getdate() [eventdateUTC], 
 db_name() as [db_name], 
 mig.index_group_handle, 
 mid.index_handle,  
 'CREATE INDEX missing_index_' + 
 CONVERT (varchar, mig.index_group_handle) + '_' + 
 CONVERT (varchar, mid.index_handle) + ' ON ' + 
 mid.statement   + ' (' + ISNULL (mid.equality_columns,'') + 
 CASE WHEN mid.equality_columns IS NOT NULL AND mid.inequality_columns IS NOT NULL 
THEN ',' 
ELSE '' 
 END + ISNULL (mid.inequality_columns, '') + ')' + 
 ISNULL (' INCLUDE (' + mid.included_columns + ')', '') 
 AS create_index_statement,  
 migs.*, 
 mid.database_id, 
 mid.[object_id] 
FROM sys.dm_db_missing_index_groups mig 
INNER JOIN sys.dm_db_missing_index_group_stats migs ON migs.group_handle = mig.index_group_handle 
INNER JOIN sys.dm_db_missing_index_details mid ON mig.index_handle = mid.index_handle 
WHERE 
 CONVERT(decimal (28,1), migs.avg_total_user_cost * migs.avg_user_impact * (migs.user_seeks + migs.user_scans)) > 10 
ORDER BY 
 migs.avg_total_user_cost * migs.avg_user_impact * (migs.user_seeks + migs.user_scans) DESC

Consulte também

Mostrar:
© 2014 Microsoft