Como criar um aplicativo de alta disponibilidade

9

Atualmente, temos um aplicativo clássico de n camadas: DB / serviço da web / front-end. Tem outros componentes, mas é o layout básico.

Queremos melhorar a disponibilidade do aplicativo por três razões principais:

  1. Às vezes, nosso host sofre interrupções (como todos acontecem) e queremos minimizar o impacto em nossos clientes; por exemplo, eles ativariam o datacenter B se o datacenter A estivesse inativo.
  2. Quando atualizamos a versão, encerramos o site para manutenção, e geralmente leva algumas horas (scripts de migração, etc.). Gostaríamos que os usuários tivessem uma transição mais uniforme, com o mínimo de tempo de inatividade possível (eles usam o servidor B enquanto o servidor A está sendo atualizado).
  3. Opcionalmente, nossos clientes estão localizados em todo o mundo e queremos que eles tenham a melhor experiência possível, apesar de suas possíveis conexões ruins (qualquer pessoa que trabalhe com desenvolvedores indianos deve saber o que quero dizer). Idealmente, gostaríamos de poder conectar um servidor ao escritório (ou usar um datacenter perto da cidade) e ele seria integrado perfeitamente à nossa arquitetura.

Não precisamos remotamente de 99% de disponibilidade, nem mesmo de 95%. É um aplicativo de gerenciamento de documentos. Ninguém se importa. Mas como as migrações podem demorar um pouco, e há clientes em todo o mundo, às vezes impedimos que um cliente trabalhe a maior parte do dia.

Para a parte SQL, mesmo que não haja DBAs "adequados", conhecemos as possibilidades de SQL : replicação, espelhamento etc. No lado do banco de dados, é muito fácil encontrar recursos para isso. O que é mais difícil é tudo o resto: armazenamento de sessões, código, etc. Se meu servidor de serviço da web ficar inativo, como minha interface do usuário sabe que deve mudar? Como minhas sessões persistem nos servidores?

Infelizmente, nenhum de nós tem experiência nessa área e nem sabemos por onde começar a procurar. Existem práticas recomendadas para isso? Padrões de design? Bibliotecas (que devem ser gratuitas porque não temos dinheiro)?

Estamos usando o ASP.Net e o SQL Server, com um serviço da Web WCF no meio. Temos vários serviços do Windows por aí, mas eles não são de missão crítica, e presumo que os métodos para lidar com o site sejam aplicáveis ​​aos serviços.

Eu entendo que a maioria das plataformas em nuvem fornece um sistema interno para isso, mas a hospedagem em nuvem é proibida por causa do administrador de sistemas, que deseja gerenciar tudo sozinho e não confiar em ninguém.

thomasb
fonte
11
"e se eles decidirem repentinamente vender nossos dados para nossos concorrentes?" Realmente? Esse é o melhor argumento que eles têm? 1) Certeza de que isso seria ilegal. 2) Nenhum provedor de hospedagem respeitável faria isso (isso estaria comprometendo todo o negócio). 3) Se você estiver realmente preocupado, verifique se os acordos assinados proíbem essas coisas e processem se eles violarem o contrato. 4) Criptografe seus dados. 5) O que impede seu host atual de fazer a mesma coisa?
Becuzz
11
Com toda a seriedade, porém, evitar o uso de algo pré-construído para a coisa exata que você deseja apenas levará a problemas. Você terá que aprender todas as lições sobre como hospedar adequadamente um sistema de alta disponibilidade que esses provedores já aprenderam. E você provavelmente não terá os recursos e os conhecimentos necessários para responder aos problemas, assim como eles terão. Se você (ou os administradores de sistema) ainda insistir em fazer isso, verifique o balanceamento de carga, o armazenamento da sessão que não está na memória (como o armazenamento de sessões SQL), as implantações automatizadas etc.
Becuzz
Custo de bibliotecas será a menor das despesas
Dan Pichelman
@ Beecuzz: Estou exagerando um pouco lá, mas eles têm (na minha opinião) argumentos geralmente não fundamentados e ilógicos contra a hospedagem na nuvem. Eles acham que são melhores que a maioria dos hosters. O que posso dizer? Quanto ao segundo ponto, não somos contra o uso de uma biblioteca, mas ela deve ser gratuita ou barata, porque não temos um orçamento para isso.
Thomasb
11
Custos de alta disponibilidade, tanto capex como opex, porque você precisa de hardware redundante e uma boa quantidade de dev & devops trabalha para fazer o HA funcionar - se você não tiver orçamento para comprar algumas ferramentas, duvido que você possa evoluir e operar uma configuração de HA.
Frederik

Respostas:

5

Você precisa esclarecer que tipo de alta disponibilidade está procurando. Existem aplicativos altamente disponíveis que eu executo que precisam estar atualizados 95% do tempo. Existem outros que precisam rodar em 99%. Posso pensar em cenários de vida ou morte que exigem 100% de tempo de atividade. Apenas esses três têm abordagens e custos drasticamente diferentes.

Basta adivinhar com base em suas necessidades e um SLA de 95 a 99% de tempo de atividade:

  • As migrações de banco de dados devem poder ocorrer em tempo real para a maioria das alterações. Pratique o design de banco de dados evolutivo . Para alterações que exigem comportamento mais invasivo, você tem algumas opções. Um é tirar o tempo de inatividade. Se possível, a execução do serviço no modo somente leitura pode funcionar. Para funcionalidade completa, estou querendo experimentar o ScaleArc há algum tempo. Parece uma ferramenta realmente eficiente para dimensionamento e resiliência no mundo do SQL Server.
  • Colocar servidores nos sites dos clientes é uma receita para um desastre incontrolável, a menos que você tenha estratégias de implantação de classe mundial (que, com base na descrição de suas migrações, você ainda não tem). Não envie serviços de nuvem no local porque você tem problemas de desempenho. Resolva os problemas de desempenho de vez em quando e não precisará lidar com os mais caros do caminho.
  • Seu servidor de estado deve ser algum tipo de banco de dados. Siga as diretrizes de HA. Você pode usar o SQL Server para isso, pois você já o tem disponível.
  • Falando em bancos de dados, a replicação não habilita o HA. De fato, a Replicação SQL causará dores de cabeça a cada passo (falando da experiência com vários cenários de replicação de nós). O espelhamento pode funcionar, mas, por último, lembre-se de que o cluster SQL leva de 1 a 5 minutos para executar o failover no novo servidor. Ouvi coisas boas sobre o AlwaysOn, mas continuo desconfiado, considerando o histórico da Microsoft. Algo como o ScaleArc pode ser mais útil aqui.
  • Seu servidor da web deve ser sem estado. Gire três ou quatro e coloque-os atrás de um balanceador de carga. Isso resolve suas preocupações de tempo de atividade lá. Como Frederik mencionou anteriormente, você também pode fazer implantações contínuas dessa maneira.
  • Seu serviço da web provavelmente deve ser sem estado. Caso contrário, veja se você pode separá-lo em bits sem estado e sem estado. Colocar várias instâncias dele atrás do mesmo balanceador de carga novamente resolve as preocupações de tempo de atividade e permite cenários de implantação mais interessados ​​(por exemplo, implantações em azul / verde).

Ao contrário de Frederik, não chamarei sua paranoia de nuvem injustificada. Depende dos seus requisitos de tempo de atividade. É concebível que um serviço tenha que ser executado em vários data centers operados por diferentes provedores em diferentes países por causa da redundância. No entanto, devido ao seu estado atual, eu concordo que a AWS, o Azure ou similares provavelmente são apostas seguras para sua empresa.

mgw854
fonte
11
Sobre a instalação no local: não é um problema de desempenho, é um problema de largura de banda do cliente. Eles podem estar em locais com conexões instáveis ​​ou lentas. Mas não é uma característica importante. Obrigado pelo resto, vou dar uma olhada neles (
thomasb
5

Obtendo algum nível de alta disponibilidade na camada da web e do aplicativo:

  1. Idealmente, fatore qualquer estado, incluindo o estado da sessão em sistemas de estado compartilhado, como um banco de dados ou um servidor de estado da sessão na memória. Dependendo do design do seu aplicativo, isso pode causar problemas de desempenho devido à latência adicionada, obtendo uma grande quantidade de estado.

  2. Cada site e camada de aplicativo devem ter um balanceador de carga independente à sua frente. O NGINX fará o truque, mas o IIS também pode fazer isso (ARR).

  3. Se um único banco de dados não puder lidar com a carga, utilize o particionamento do estado da sessão (ou fragmentação ou hash consistente) para rotear uma solicitação específica para uma caixa de banco de dados específica.

Se fatorar o estado de fatoração for muito difícil, você poderá usar a afinidade do servidor para o balanceamento de carga (ou seja, os usuários serão roteados consistentemente para a mesma caixa, geralmente baseados em cookies). Não é tão disponível como uma abordagem de rodízio sem estado, porque uma interrupção de caixa afetará todos os usuários e indicará nessa caixa, mas supera uma interrupção completa (dependendo do caso de uso).

No lado da atualização:

  1. Projete seus scripts de banco de dados de forma que as atualizações do banco de dados possam ser feitas enquanto o sistema estiver em execução, ou seja, mantenha a compatibilidade com versões anteriores. Um padrão que funciona bem para isso é "expandir e depois contratar" -> fazer apenas alterações aditivas e compatíveis com versões anteriores, mas remover dependências nos campos (etc) dos quais você deseja se livrar; então atualize todos os clientes do banco de dados para v-latest; então faça outro db-upgrade para se livrar dos campos antigos (etc) no banco de dados. Isso pode ser um processo lento se você tiver um banco de dados grande e tiver que ter cuidado para não prejudicar o desempenho do seu sistema.

  2. Atualizando a camada do aplicativo: como você não está usando um ambiente em nuvem, recomendo que você siga o padrão de implantação canário: faça uma atualização sem interrupção das caixas da Web e da camada intermediária. Se a implantação der errado, retire a caixa do balanceador de carga, como faria como se tivesse falhado.

Aviso: evoluir um sistema que não foi projetado para HA em um que seja, pode ser um processo longo e caro. Você precisará fazer trocas ao longo do caminho (custo x esforço para atingir um nível específico de disponibilidade)

Sua paranóia da nuvem é injustificada - provedores como a AWS, em conjunto com as boas práticas de sua parte, podem controlar / mitigar a maioria dos riscos - consulte a página de conformidade deles para ter uma idéia de quais regulamentos eles são compatíveis: https: // aws .amazon.com / conformidade /

Frederik
fonte
1

TL; DR: criar redundante, modular; teste de disponibilidade; monitorar de perto.

Depois de perceber que a tentativa de extrair qualquer explicação pode demorar muito, escreverei todas as observações que fiz.

Questionando a premissa

Sistema de nuvem é panacéia

Mesmo que você opte totalmente pela nuvem, com um dos principais provedores de nuvem, ainda será necessário projetar seu aplicativo para resiliência. A AWS pode substituir sua VM, mas seu aplicativo deve ser capaz de reiniciar se for deixado no meio da computação.

Não queremos usar o sistema em nuvem, por causa de x / y / z

A menos que você seja uma organização muito grande, é melhor usar sistemas de nuvem. Os três principais sistemas em nuvem (AWS, MSFT, Google) empregam milhares de engenheiros para fornecer SLAs prometidos e o painel fácil de gerenciar. Na verdade, é uma boa pechincha usá-los, em vez de gastar um centavo com isso em casa.

Problemas no escopo e no design

Definir, quantificar e, em seguida, medir continuamente a disponibilidade de um serviço é um desafio maior do que escrever soluções para problemas de disponibilidade.

Definir e medir a 'disponibilidade' é mais difícil do que o esperado

Múltiplas partes interessadas têm uma visão diferente da disponibilidade, e o que pode acontecer é a definição preferida por uma pessoa com salário mais alto que outra definição. Às vezes, essa é a definição correta, mas geralmente o ecossistema não é construído para medir a mesma coisa, porque essa definição ideal é muito difícil de medir, e muito menos monitorar em tempo real. Se você tem uma definição de disponibilidade que não pode ser monitorada em tempo real, você encontrará seu projeto semelhante auto-realizado repetidas vezes com semelhanças assustadoras. Atenha-se a algo que faça sentido e que possa ser facilmente monitorado.

As pessoas subestimam as complexidades do sistema sempre disponível.

Para abordar o elefante na sala, deixe-me dizer o seguinte: "Nenhum sistema multi-computador está 100% disponível, poderá no futuro, mas não com a tecnologia atual". Aqui, pela tecnologia atual, estou me referindo à nossa incapacidade de enviar sinais mais rapidamente do que a velocidade da luz e coisas assim. Todos os engenheiros da comp-sci valem a pena conhecer as limitações da computação distribuída , e a maioria deles não menciona isso nas reuniões, com medo de parecer noobs. Para compensar todos aqueles que não mencionam as limitações da computação distribuída , direi que é complicado, mas nem sempre confia nos computadores .

As pessoas superestimam as capacidades de seus engenheiros

Infelizmente, a disponibilidade cai na categoria em que você não sabe o que deseja, mas sabe o que não quer. É um pouco mais complicado que a categoria 'conheça os desejos', como a interface do usuário. Requer um pouco de experiência e muita leitura para aprender com a experiência dos outros e um pouco mais.

Construindo um sistema disponível desde o início

Certifique-se de evangelizar para todas as equipes de arquitetura e design a prioridade correta da disponibilidade como um requisito do sistema.

Atributos do sistema que ajudam a disponibilidade

As seguintes características do sistema demonstraram ter contribuído para a disponibilidade do sistema:

Redundância

Alguns exemplos disso são: nunca ter apenas uma única VM atrás de um VIP ou nunca armazenar apenas uma única cópia dos seus dados. Essas são as perguntas que um bom IAAS facilitará para você resolver, mas você ainda precisará tomar essas decisões.

Modularidade

Um REST modular é melhor que o SOA monolítico. Na verdade, um microsserviço modular está realmente mais disponível do que o habitual HATEOS REST . O raciocínio pode ser encontrado na discussão relacionada ao rendimento na próxima seção. Se você estiver processando em lote, é melhor processá-lo em lotes razoáveis ​​de 10s em comparação a lidar com um lote de 1.000.000.

Resiliência

"I am always angry"
                    - Hulk

Um sistema resiliente está sempre pronto para se recuperar. Essa resiliência se aplica a instâncias como reconhecer o ACK para gravação somente após a gravação no disco RAID e, possivelmente, em pelo menos dois data centers. Outra tendência mais recente é usar estruturas de dados sem conflito , onde a estrutura de dados assume a responsabilidade de resolver conflitos quando apresentada com duas versões diferentes. Um sistema não pode ser resiliente como uma reflexão tardia, ele deve ser previsto e incorporado. Uma falha é garantida a longo prazo, por isso devemos estar sempre preparados com um plano de recuperação.

Trilha de registro

Tecnicamente, esse é um subtipo de resiliência, mas muito especial por causa de sua capacidade de capturar todos os recursos. Apesar do melhor esforço, podemos não ser capazes de prever o padrão de indisponibilidade. Se possível, mantenha trilha de log suficiente das atividades do sistema para poder reproduzir eventos do sistema. Isso, a um grande custo manual, permitirá que você se recupere de situações imprevistas.

Atributos de disponibilidade

A lista não exaustiva de atributos de 'disponibilidade': Para discussão, vamos supor que a pergunta do usuário seja: "Quantos itens eu tenho no meu carrinho de compras?"

Correção

Você deve produzir a resposta mais precisa possível ou pode cometer erros? Apenas para uma referência, quando você retira dinheiro do caixa eletrônico, não é garantido que ele esteja correto. Se o banco descobrir que cometeu um erro, você poderá reverter as transações. Se o seu sistema está produzindo números primos, então eu acho que você pode querer respostas corretas o tempo todo.

Produção

Pule este ponto, se você respondeu sempre correto para a pergunta do tópico anterior. Às vezes, a resposta às perguntas não precisa ser precisa, por exemplo, quantos amigos eu tenho no Facebook agora? Mas a resposta deve estar no estádio +/- 1 o tempo todo. Quando você está produzindo o resultado esperado, seu rendimento é 100.

Consistência

Sua resposta pode estar correta em um ponto no tempo, mas quando a luz sair da tela e entrar na retina do observador, as coisas poderão ter mudado. Faz sua resposta errada? Não, apenas torna inconsistente. A maioria dos aplicativos é eventualmente consistente, mas o truque é definir que tipo de modelo de consistência seu aplicativo fornecerá. Por acaso seu aplicativo pode ser executado em um único computador, você pode pular essa adorável leitura no teorema do CAP .

Custo

Depende muito do impacto total dos efeitos de curto prazo (perda de receita) e efeitos de longo prazo (má reputação, retenção de clientes). Dependendo do tipo de cliente (pago / gratuito, repetido / exclusivo, cativo) e da disponibilidade de recursos, diferentes níveis de garantias de disponibilidade devem ser incorporados.

Para melhorar a disponibilidade de um sistema existente

O gerenciamento operacional de máquinas individuais e uma rede é tão complexo que suponho que você o tenha deixado para o provedor de nuvem ou você já é especialista o suficiente para saber o que está fazendo. Vou tocar em outros tópicos sob disponibilidade. Para a estratégia de longo prazo, Definir-Medir-Analisar-Controle é uma combinação divina, algo que eu já me vi.

  1. Defina o que é 'disponibilidade' para seus stakeholders
  2. Como você medirá o que você definiu
  3. Análise de causa raiz para identificar gargalos
  4. Tarefas para melhorias
  5. Monitoramento contínuo ( controle ) do sistema

Causas de indisponibilidade

Como concordamos que o gerenciamento operacional que abrangeria qualquer gerenciamento de infraestrutura física deveria ser feito por profissionais, abordarei outras causas de indisponibilidade por questões de integridade. A disponibilidade da IMO também deve incluir a falta de comportamento esperado, ou seja, se o usuário não receber a experiência esperada, algo estará indisponível. Com essa definição ampla em mente, o seguinte pode causar indisponibilidade: - Bugs de código - Incidências de segurança - Problemas de desempenho

Ajeet Ganga
fonte
Interessante, mas não muito útil, e um pouco fora de tópico. Obrigado mesmo assim.
Thomasb