O failover rápido é um dos muitos aprimoramentos que vêm com o lançamento do Servidor Couchbase 5.0 (já disponível para download).
O failover é um dos conceitos mais importantes a serem compreendidos quando se trata de bancos de dados distribuídos. O teorema CAP afirma que um banco de dados distribuído não pode estar disponível ao mesmo tempo e consistente todos do tempo. A arquitetura do Couchbase Server foi projetada para ser sempre consistente e tolerante a partições. Com o failover rápido, o Couchbase Server está fechando a lacuna em relação a alta disponibilidade.
Nesta postagem do blog, vou demonstrar o failover em ação. Usarei o Docker para criar um cluster de 3 nós do Couchbase em minha máquina local.
Você pode acompanhar o exemplo de código nesta postagem do blog: ele é disponível no GitHub.
Visão geral do failover rápido
Você precisará de um pouco de configuração e preparação.
Primeiro, crie um cluster do Couchbase Server com três nós (pelo menos). Há várias maneiras de fazer isso, incluindo VagabundosMáquinas virtuais, máquinas reais, Azuree muito mais.
Optei por usar o Docker. Eu escrevi em um blog sobre como criar um cluster do Couchbase no Docker e acessá-lo com um aplicativo .NET Core (não se esqueça da rede bridge!). Então, simplesmente segui as mesmas instruções novamente. A única diferença é que usei um aplicativo de console em vez de um aplicativo ASP.NET (sobre o qual você poderá ler mais adiante nesta publicação).
Eu usei o Imagem do Couchbase Server 5.0.0-beta2 do Docker Hubmas, quando você estiver lendo isso, uma versão oficial do Couchbase Server 5.0 deverá ser lançada. disponível no repositório oficial do docker Couchbase.
Em seguida, criei um bucket chamado "mybucket". Certifique-se de ativar as réplicas para criar cópias adicionais de dados no mesmo cluster.
Depois disso, crie um usuário (chamei o meu de "myuser") com pelo menos permissão de Data Writer e Data Reader para "mybucket"). Se você ainda não estiver familiarizado com o Couchbase Server Controle de acesso baseado em função (RBAC)Comece com esta postagem do blog sobre Autenticação com RBAC e .NET.
Por fim, ative o failover rápido automático. No Console do Couchbase, acesse Configurações e, em seguida, Auto-Failover. Marque a caixa "Enable auto-failover" (Ativar failover automático). A partir da versão 5.0, você pode definir o valor de Timeout como 5 (segundos). Anteriormente, o valor tinha de ser de pelo menos 30 segundos.
Há um motivo pelo qual o failover automático está desativado por padrão. Consulte a seção completa documentação sobre failover automático para ter certeza de que é a opção certa para você.
Exemplo de .NET
Agora que você tem um cluster de três nós em execução dentro do seu host do Docker, é hora de escrever um aplicativo de demonstração. Decidi escrever um aplicativo de console que executaria continuamente leituras no Couchbase. Em algum momento, vou "desligar" um dos nós para mostrar o failover rápido automático em ação.
Conexão com o cluster
Depois de criar um novo aplicativo de console do .NET Core no Visual Studio, adicionei o componente Couchbase .NET SDK (atualmente na versão 2.5.1) usando o NuGet.
Em seguida, criei uma configuração para me conectar ao cluster de três nós, autenticar como "myuser" e abrir o "mybucket".
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
var clientConfig = novo Configuração de cliente { Servidores = novo Lista<Uri> { novo Uri("http://172.17.0.2"), novo Uri("http://172.17.0.3"), novo Uri("http://172.17.0.4") } }; var agrupamento = novo Aglomerado(clientConfig); var credenciais = novo PasswordAuthenticator("myuser", "senha"); agrupamento.Autenticar(credenciais); _bucket = agrupamento.OpenBucket("mybucket"); |
Esses endereços IP são os endereços que são interno para o host do Docker. Esse aplicativo .NET Core também será executado dentro do host do Docker, onde esses endereços IP serão resolvidos. De externo o host da estação, apenas "localhost:8091" será resolvido (supondo que você esteja seguindo o tutorial que eu vinculei anteriormente). Se não estiver usando o Docker, insira os endereços IP das máquinas do Azure, das VMs etc.
Próximo, PasswordAuthentication (autenticação por senha)
é usado para garantir o acesso ao balde.
Por fim, obtenha um objeto bucket usando OpenBucket
.
Configuração de documentos
Para esta demonstração, quero configurar vários documentos dos quais lerei repetidamente mais tarde. Primeiro, escrevi um loop para criar um número arbitrário de documentos, cada um com uma chave do tipo "documentKey[num]" (por exemplo, "documentKey1", "documentKey2" etc.).
1 2 3 4 5 6 7 |
var docKeys = novo Lista<string>(); para (var i = 0; i < numDocuments; i++) { var chave = "documentKey" + i; docKeys.Adicionar(chave); _bucket.Upsert(chave, novo { nome = "Documento" + i }); } |
Em meu código, numDocuments
está definido como 50. Mas se estiver acompanhando o processo, fique à vontade para definir outro número e ver o que acontece.
Leitura de documentos
Portanto, há 50 documentos com chaves conhecidas. O restante do programa estará em looping contínuo. Cada iteração do loop tentará recuperar todos os 50 documentos.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
var iteração = 0; enquanto (verdadeiro) { Console.WriteLine($"Obtendo {numDocuments} documentos [{iteração++}]"); antes de(var docKey em docKeys) { var resultado = _bucket.Obter<dinâmico>(docKey); se(conciso) ShowResultTerse(resultado, docKey); mais ShowResult(resultado, docKey); } Console.WriteLine(); Tópico.Dormir(2000); } |
Primeiro, observe que há um loop dentro do loop. O loop interno será executado 50 vezes para realizar um Obter
em cada documento. ShowResult
emitirá o que está acontecendo no console (ShowResultTerse
faz a mesma coisa, mas de uma forma muito mais compacta. ShowResult
está abaixo, mas as capturas de tela posteriores usarão ShowResultTerse
).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
privado estático vazio ShowResult(IOperationResult<dinâmico> resultado, string id) { // caminho feliz, o documento foi encontrado se (resultado.Sucesso) { Console.WriteLine("Result: success" (Resultado: sucesso)); retorno; } // erro, possivelmente o nó está inoperante // mostrar o erro, tentar obter a réplica Console.WriteLine($"Result: unsuccessful {result.Message}"); Console.WriteLine("\tTentando obter réplica."); var réplica = _bucket.GetFromReplica<dinâmico>(id); // caminho feliz para a réplica, ela foi encontrada se (réplica.Sucesso) { Console.WriteLine("\tReplica result: success"); retorno; } // erro! a replicação pode não estar configurada // ou é possível que algo catastrófico tenha acontecido // isso deve ser raro, mas definitivamente queremos registrá-lo // talvez tentar novamente e/ou escalar // neste exemplo, ele é apenas registrado no console Console.WriteLine("\tReplica result unsuccessful: {result.Message}"); } |
Os comentários o ajudarão a acompanhar o processo, mas ShowResult
faz três verificações:
- A leitura foi bem-sucedida? Em caso afirmativo, dê o resultado. Pronto! Caso contrário...
- Tente obter uma réplica (de outro nó). Isso foi bem-sucedido? Em caso afirmativo, envie o resultado. Pronto! Caso contrário...
- O aplicativo não conseguiu ler o documento ou uma de suas réplicas. Neste exemplo, isso será muito raro. Na realidade, isso pode significar que o documento não existe, ou que a replicação não está configurada corretamente, ou que alguma outra coisa deu errado.
Então, você está pronto para executar o aplicativo. Se estiver usando o Docker, não se esqueça de executar esse aplicativo no Docker (que é fácil de fazer no Visual Studio). (Certifique-se também de conectar o contêiner do aplicativo .NET Core à rede de ponte do Docker).
Desligue o plugue!
Antes de desligar um dos nós, vamos dar uma olhada na saída "normal" ao executar o aplicativo .NET Core acima.
No GIF abaixo, você verá:
- Um cluster de três nós do Couchbase Server
- Mudar para o Visual Studio
- Crie e inicie o contêiner do Docker com CTRL+F5
- A saída (concisa) do console do contêiner do Docker
(Aumentei um pouco a velocidade da animação). Observe que "S" está sendo mostrado 50 vezes. Isso significa que cada documento foi recuperado com sucesso.
A seguir, vamos mostrar o failover rápido em ação. Vou "desligar a tomada" em um dos nós. Com o Docker, posso executar docker stop db2
Por exemplo.
Há muita coisa para acompanhar de uma só vez, por isso criei um vídeo curto que demonstra o que está acontecendo.
[youtube https://www.youtube.com/watch?v=KbU5eG2R9XU&w=700&h=394]
O que você está vendo nesse vídeo é:
- Operação normal (todos os "S" de sucesso)
- Um nó sendo interrompido (com o Docker)
- Couchbase detectando um nó inoperante.
- Couchbase iniciando failover rápido para ativar réplicas.
- Durante esse período de failover, nem tudo é mais "S". Também há alguns "R" para réplicas (que são somente leitura).
- Quando o failover é concluído, os resultados voltam a ser todos "S" novamente.
O objetivo do failover rápido é reduzir o período de tempo em que nem todos os documentos estão totalmente disponíveis.
Resumo
O Couchbase Server 5.0 aprimorou o failover com uma opção de "failover rápido" que pode ser útil para ambientes com uma rede sólida.
Esta postagem do blog mostra um aplicativo de console que tem o objetivo de demonstrar o failover rápido. Não é um aplicativo muito útil fora disso, mas você pode usar os princípios e aplicá-los a um site ASP.NET ou ASP.NET Core.
Confira Servidor Couchbase 5.0 hoje para obter esse e outros excelentes recursos novos.
Agradecimentos especiais a Jeff Morris e a equipe do SDK por ajudar com esta postagem no blog!
Aqui estão alguns links para obter mais informações sobre failover rápido:
- O RFC DO SDK para failover rápido. Este documento abrange o .NET, mas também Java, libcouchbase e Go.
- Documentação de failover automático para o Couchbase Server.
- Código-fonte do aplicativo de console do .NET Core usado nesta postagem do blog (GitHub)
- Dois tíquetes do JIRA para failover rápido do .NET: NCBC-1366 e NCBC-1388.
Se você tiver dúvidas ou comentários sobre failover, não deixe de conferir o Fóruns do Couchbase.
Deixe suas perguntas e comentários sobre todos os assuntos relacionados a .NET e Couchbase ou encontre-me em Twitter @mgroves.