Criar serviços de nuvem com tolerância a falhas

Concluído

Grande parte do gerenciamento de datacenters e de serviços de nuvem envolve a criação e a manutenção de um serviço confiável baseado em partes não confiáveis. A figura a seguir mostra parte de um treinamento para novos funcionários e deve dar uma ideia do grande número (e dos tipos) de falhas que surgem regularmente em um datacenter grande.

Reliability issues as shown in a training presentation.

Figura 2: Problemas de confiabilidade mostrados em uma apresentação de treinamento

Uma falha em um sistema ocorre como resultado de um estado inválido introduzido no sistema em decorrência de uma falha. Normalmente, os sistemas desenvolvem falhas de um dos seguintes tipos:

  • Falhas transitórias: falhas temporárias no sistema que corrigem a si mesmas no decorrer do tempo.
  • Falhas permanentes: falhas que não podem ser recuperadas e que geralmente exigem a substituição de recursos.
  • Falhas intermitentes: falhas que ocorrem periodicamente em um sistema.

As falhas podem afetar a disponibilidade do sistema desativando seus serviços ou reduzindo o desempenho de suas funcionalidades. Um sistema com tolerância a falhas tem a capacidade de executar sua função mesmo quando há falhas nele. Na nuvem, considera-se que um sistema com tolerância a falhas é aquele que fornece serviços de maneira uniforme com tempo de inatividade menor do que o permitido pelos SLAs (contratos de nível de serviço).

Por que a tolerância a falhas é importante?

Falhas em sistemas críticos de grande porte podem levar a perdas monetárias significativas para todas as partes envolvidas. A natureza dos sistemas de computação em nuvem é que eles têm uma arquitetura em camadas. Sendo assim, uma falha em uma camada dos recursos de nuvem pode disparar uma falha em outras camadas superiores ou ocultar o acesso às camadas inferiores.

Por exemplo, uma falha em qualquer componente de hardware do sistema pode afetar a execução normal de um aplicativo de SaaS (software como serviço) em execução em uma máquina virtual que usa os recursos com falha. As falhas em um sistema, em qualquer camada, têm uma relação direta com os SLAs entre os provedores em cada nível.

Medidas proativas

Os provedores de serviços adotam várias medidas para projetar o sistema de uma forma específica a fim de evitar problemas conhecidos ou falhas previsíveis.

Criação de perfil e testes

Realizar testes de estresse e carga nos recursos de nuvem a fim de entender as possíveis causas de falha é essencial para garantir a disponibilidade dos serviços. A criação de perfis dessas métricas ajuda a projetar um sistema capaz de suportar a carga esperada sem exibir nenhum comportamento imprevisível.

Superprovisionamento

Superprovisionamento é a prática de implantar recursos em volumes maiores do que a utilização geral projetada desses recursos em qualquer determinado momento. Em situações em que as necessidades exatas do sistema não podem, necessariamente, ser previstas, o superprovisionamento de recursos pode ser uma estratégia aceitável para lidar com picos de carga inesperados.

Considere como exemplo uma plataforma de comércio eletrônico que tem uma carga média uniforme em seus servidores o ano todo, mas durante o período de Natal, a expectativa é de que o padrão de carga atinja um pico rapidamente. Nesses períodos de pico, é aconselhável provisionar recursos extras com base nos dados históricos do uso de pico. Normalmente, é difícil acomodar um aumento rápido no tráfego em um período curto. Conforme discutido em seções posteriores, há um custo de tempo associado ao dimensionamento dinâmico, que envolve as etapas demoradas de detectar uma alteração no padrão de carga e provisionar recursos extras para acomodar a nova carga. Essas duas etapas demandam tempo. Esse atraso no ajuste pode ser suficiente para sobrecarregar e, na pior das hipóteses, travar o sistema ou, na melhor, degradar a qualidade do serviço.

O superprovisionamento também é uma tática usada para se defender de ataques de DoS (negação de serviço) ou DDoS (DoS distribuída), que ocorrem quando os invasores geram solicitações com a finalidade de sobrecarregar um sistema, lançando grandes volumes de tráfego para ele na tentativa de fazê-lo falhar. Em qualquer ataque, sempre é necessário algum tempo para o sistema detectar e tomar medidas corretivas. Embora essa análise dos padrões de solicitação esteja sendo feita, o sistema já está sob ataque e precisa ser capaz de acomodar o aumento no tráfego até que uma estratégia de mitigação possa ser implementada.

Replicação

Os componentes críticos do sistema podem ser duplicados usando componentes adicionais de hardware e software para lidar silenciosamente com falhas em partes do sistema sem que o sistema inteiro falhe. A replicação tem duas estratégias básicas:

  • A replicação ativa, em que todos os recursos replicados estão ativos simultaneamente e respondem a todas as solicitações e as processam. Isso significa que, para qualquer solicitação de cliente, todos os recursos recebem e respondem à mesma solicitação. A ordem das solicitações mantém o estado em todos os recursos.
  • A replicação passiva, em que apenas a unidade primária processa as solicitações e as unidades secundárias apenas mantêm o estado e assumem o controle após uma falha da unidade primária. O cliente entra em contato somente com o recurso primário, que retransmite a alteração de estado para todos os recursos secundários. A desvantagem da replicação passiva é que pode ocorrer o descarte de solicitações ou a degradação da QoS ao alternar da instância primária para a secundária.

Também há uma estratégia híbrida, chamada de semiativa, que é muito semelhante à estratégia ativa. A diferença é que somente a saída do recurso primário é exposta ao cliente. As saídas dos recursos secundários são suprimidas e registradas em log, ficando prontas para assumir o controle assim que ocorrer uma falha do recurso primário. A figura a seguir mostra as diferenças entre as estratégias de replicação.

Replication strategies.

Figura 3: Estratégias de replicação

Um fator importante a levar em consideração com relação à replicação é o número de recursos secundários a serem usados. Embora isso varie de um aplicativo para outro com base em quanto o sistema é crítico, há três níveis formais de replicação:

  • N+1: basicamente, isso significa que, para um aplicativo que precisa de N nós funcionar corretamente, um recurso extra é provisionado como forma de proteção.
  • 2N: nesse nível, um nó extra para cada nó necessário para o funcionamento normal é provisionado como forma de proteção.
  • 2N+1: nesse nível, um nó extra para cada nó necessário para o funcionamento normal, além de um nó adicional geral, são provisionados como formas de proteção.

Medidas reativas

Além das medidas preditivas, os sistemas podem adotar medidas reativas e lidar com as falhas conforme e quando elas ocorrerem:

Verificações e monitoramento

Todos os recursos são monitorados constantemente para detectar comportamentos imprevisíveis ou perdas de recursos. Com base nas informações de monitoramento, estratégias de recuperação ou reconfiguração são criadas para reiniciar recursos existentes ou habilitar novos recursos. O monitoramento pode ajudar na identificação de falhas nos sistemas. Falhas que fazem com que o serviço fique não disponível são chamadas de falhas com pane; aquelas que induzem a um comportamento irregular/incorreto no sistema são chamadas de falhas bizantinas.

Várias táticas de monitoramento são usadas para detectar falhas com pane em um sistema. Duas delas são:

  • Ping e eco: o serviço de monitoramento solicita a cada recurso seu estado e tem uma janela de tempo para responder.
  • Pulsação: cada instância envia o status ao serviço de monitoramento em intervalos regulares, sem nenhum gatilho.

O monitoramento de falhas bizantinas geralmente depende das propriedades do serviço fornecido. Os sistemas de monitoramento podem verificar métricas básicas, como latência, utilização da CPU e utilização de memória, além de comparar com os valores esperados para ver se a qualidade do serviço está sendo degradada. Além disso, geralmente são mantidos logs de supervisão específicos do aplicativo em cada ponto de execução de serviço importante, que são analisados periodicamente para ver se o serviço está funcionando corretamente a todo momento (ou se falhas foram injetadas no sistema).

Ponto de verificação e reinício

Vários modelos de programação na nuvem implementam estratégias de ponto de verificação, em que o estado é salvo em vários estágios de execução a fim de permitir a recuperação para um ponto de verificação salvo mais recentemente. Em aplicativos de análise de dados, muitas vezes há tarefas de longa execução distribuídas em paralelo, que são executadas em terabytes de conjuntos de dados para extrair informações. Como essas tarefas são executadas em várias partes pequenas, cada etapa da execução do programa pode salvar o estado geral da execução como um ponto de verificação. Em pontos de falha em que nós individuais não conseguem concluir seu trabalho, a execução pode ser reiniciada partindo de um ponto de verificação anterior. O maior desafio ao identificar pontos de verificação válidos aos quais reverter ocorre quando processos paralelos estão compartilhando informações. Uma falha em um dos processos pode causar uma reversão em cascata em outro processo, uma vez que os pontos de verificação feitos nesse processo podem ser resultado de uma falha nos dados compartilhados pelo processo com falha. Você aprenderá mais sobre a tolerância a falhas para modelos de programação em módulos posteriores.

Estudos de caso em testes de resiliência

Os serviços de nuvem precisam ser criados tendo a redundância e a tolerância a falhas em mente, pois nenhum componente de um sistema distribuído de grande porte é capaz de garantir 100% de disponibilidade ou tempo de atividade.

Todas as falhas (incluindo falhas de dependências no mesmo nó, rack, datacenter ou em implantações com redundância geográfica) precisam ser tratadas de maneira sutil, sem afetar todo o sistema. É importante testar a capacidade do sistema de lidar com falhas catastróficas, pois às vezes até mesmo alguns segundos de tempo de inatividade ou degradação de serviço podem levar a centenas de milhares, se não milhões, de dólares em perda de receita.

Testes para detecção de falhas com tráfego real precisam ser realizados regularmente para que o sistema fique protegido e possa suportar quando ocorrer uma interrupção não planejada. Há vários sistemas criados para testar a resiliência. Um desses pacotes de testes é o Simian Army criado pela Netflix.

O Simian Army é composto por serviços (chamados de monkeys) na nuvem que têm a finalidade de gerar vários tipos de falhas, detectar condições anormais e testar a capacidade do sistema de sobreviver a elas. A meta é manter a nuvem segura, protegida e altamente disponível. Alguns dos monkeys encontrados no Simian Army são:

  • Chaos Monkey: uma ferramenta que escolhe aleatoriamente uma instância de produção e a desabilita para garantir que a nuvem sobrevive a tipos comuns de falha sem nenhum impacto para o cliente. A Netflix descreve o Chaos Monkey como "A ideia de liberar um macaco selvagem com uma arma em seu datacenter (ou região de nuvem) para aleatoriamente derrubar instâncias e mastigar cabos enquanto continuamos atendendo aos clientes sem interrupção". Esse tipo de teste com monitoramento detalhado pode expor várias formas de pontos fracos no sistema, e é possível criar estratégias de recuperação automática com base nos resultados.
  • Latency Monkey: um serviço que gera atrasos entre a comunicação RESTful de diferentes clientes e servidores, simulando a degradação e o tempo de inatividade do serviço.
  • Doctor Monkey: um serviço que localiza instâncias que estão apresentando comportamentos não íntegros (por exemplo, carga de CPU) e as remove do serviço. Ele dá aos proprietários de serviço algum tempo para descobrir o motivo do problema e, eventualmente, termina a instância.
  • Chaos Gorilla: um serviço que pode simular a perda de uma zona de disponibilidade da AWS inteira. Ele é usado para testar se os serviços reequilibram automaticamente a funcionalidade entre as zonas restantes sem impacto visível para o usuário nem intervenção manual.

Verificar seu conhecimento

1.

Qual dos cenários de teste a seguir não ajuda a testar a resiliência e a preparação de um serviço de nuvem?