Modelagem de clusters de failover com base em PostgreSQL e Pacemaker

Introdução

Há algum tempo, recebi a tarefa de desenvolver um cluster de failover para PostgreSQL, operando em vários data centers conectados por fibra dentro da mesma cidade e capaz de resistir à falha (por exemplo, apagão) de um data center. Como um software responsável pela tolerância a falhas, escolhi Marcapasso cardíaco, porque esta é a solução oficial da RedHat para a criação de clusters de failover. É bom porque o RedHat oferece suporte para isso e porque esta solução é universal (modular). Com a sua ajuda, será possível fornecer tolerância a falhas não só para PostgreSQL, mas também para outros serviços, seja através de módulos padrão ou criando-os para necessidades específicas.

Para esta decisão, surgiu uma questão razoável: quão tolerante a falhas será um cluster de failover? Para investigar isso, desenvolvi uma bancada de testes que simula diversas falhas nos nós do cluster, aguarda a recuperação, restaura o nó com falha e continua testando em loop. Inicialmente esse projeto se chamava hapgsql, mas com o tempo fiquei entediado com o nome, que possui apenas uma vogal. Portanto, comecei a nomear bancos de dados tolerantes a falhas (e IPs flutuantes apontando para eles) Krogan (um personagem de um jogo de computador, no qual todos os órgãos importantes são duplicados), e nós, clusters e o próprio projeto são tuchanka (o planeta onde vivem os krogans).

A administração já aprovou abrir um projeto para a comunidade de código aberto sob a licença do MIT. O README será traduzido em breve para o inglês (porque espera-se que os desenvolvedores do Pacemaker e do PostgreSQL sejam os principais consumidores), e decidi publicar a antiga versão russa do README (parcialmente) na forma deste artigo.

Modelagem de clusters de failover com base em PostgreSQL e Pacemaker

Clusters são implantados em máquinas virtuais VirtualBox. No total, serão implantadas 12 máquinas virtuais (36GiB no total), que formam 4 clusters de failover (diferentes opções). Os dois primeiros clusters consistem em dois servidores PostgreSQL localizados em data centers diferentes e um servidor comum testemunha c dispositivo de quórum (hospedado em uma máquina virtual barata em um terceiro data center) que resolva incertezas 50% / 50%através do voto. O terceiro cluster em três data centers: um mestre, dois escravos, não dispositivo de quórum. O quarto cluster consiste em quatro servidores PostgreSQL, dois por data center: um mestre, os demais são réplicas, e também utiliza testemunha c dispositivo de quórum. O quarto sobrevive à falha de dois servidores ou de um data center. Esta solução pode ser ampliada para mais réplicas, se necessário.

Serviço de tempo ntpd também reconfigurado para tolerância a falhas, mas usa o método de ntpd (modo órfão). Servidor compartilhado testemunha atua como um servidor NTP central, distribuindo seu tempo para todos os clusters, sincronizando assim todos os servidores entre si. Se testemunha falhar ou ficar isolado, um dos servidores do cluster (dentro do cluster) começará a distribuir seu tempo. Cache auxiliar Proxy HTTP também elevado para testemunha, com sua ajuda, outras máquinas virtuais têm acesso aos repositórios Yum. Na realidade, serviços como hora precisa e proxy provavelmente serão hospedados em servidores dedicados e no estande em que estão hospedados. testemunha apenas para economizar o número de máquinas virtuais e espaço.

Versões

v0. Funciona com CentOS 7 e PostgreSQL 11 no VirtualBox 6.1.

Estrutura de cluster

Todos os clusters são projetados para serem localizados em vários data centers, unidos em uma rede plana e devem resistir a falhas ou isolamento de rede de um data center. É por isso é impossível usar para proteger contra cérebro dividido tecnologia padrão de marca-passo chamada STONITH (Atire no outro nó na cabeça) ou esgrima. Sua essência: se os nós do cluster começarem a suspeitar que algo está errado com algum nó, ele não responde ou se comporta incorretamente, então eles o desligam à força por meio de dispositivos “externos”, por exemplo, uma placa de controle IPMI ou UPS. Mas isso só funcionará nos casos em que, com uma única falha do servidor IPMI ou UPS, eles continuem funcionando. Ela também planeja proteger contra uma falha muito mais catastrófica, quando todo o data center falhar (por exemplo, for desenergizado). E com tal recusa, tudo pedra-dispositivos (IPMI, UPS, etc.) também não funcionarão.

Em vez disso, o sistema é baseado na ideia de quórum. Todos os nós têm voz e apenas aqueles que veem mais da metade de todos os nós podem trabalhar. Este número "metade + 1" é chamado quorum. Se o quorum não for atingido, então o nó decide que está em isolamento de rede e deve desligar seus recursos, ou seja, é assim proteção contra cérebro dividido. Se o software responsável por esse comportamento não funcionar, um watchdog, por exemplo, baseado em IPMI, deverá funcionar.

Se o número de nós for par (um cluster em dois data centers), poderá surgir a chamada incerteza 50% / 50% (meio a meio) quando o isolamento da rede divide o cluster exatamente pela metade. Portanto, para um número par de nós, é adicionado dispositivo de quórum - um daemon pouco exigente que pode ser executado na máquina virtual mais barata do terceiro data center. Ele dá o seu voto a um dos segmentos (que ele vê), e assim resolve a incerteza de 50%/50%. O servidor no qual o dispositivo de quorum será executado, liguei testemunha (terminologia do repmgr, gostei).

Os recursos podem ser movidos de um lugar para outro, por exemplo, de servidores defeituosos para servidores que podem ser reparados ou sob o comando de administradores de sistema. Para que os clientes saibam onde estão localizados os recursos de que necessitam (onde se conectar?), IP flutuante (IP flutuante). Esses são os IPs que o Pacemaker pode movimentar pelos nós (tudo está em uma rede plana). Cada um deles simboliza um recurso (serviço) e estará localizado onde você precisa se conectar para ter acesso a este serviço (no nosso caso, o banco de dados).

Tuchanka1 (esquema compactado)

Estrutura

Modelagem de clusters de failover com base em PostgreSQL e Pacemaker

A ideia era que tivéssemos muitos bancos de dados pequenos e com baixa carga, para os quais não é lucrativo manter um servidor escravo dedicado em modo hot standby para transações somente leitura (não há necessidade de tal desperdício de recursos).

Cada data center possui um servidor. Cada servidor possui duas instâncias do PostgreSQL (na terminologia do PostgreSQL, elas são chamadas de clusters, mas para evitar confusão, irei chamá-las de instâncias (por analogia com outros bancos de dados) e chamarei apenas clusters de clusters do Pacemaker). Uma instância funciona no modo mestre e somente fornece serviços (apenas o IP flutuante leva a ela). A segunda instância funciona como escrava do segundo data center e só fornecerá serviços se seu mestre falhar. Como na maioria das vezes apenas uma das duas instâncias (o mestre) fornecerá serviços (realizará solicitações), todos os recursos do servidor serão otimizados para o mestre (a memória será alocada para o cache shared_buffers, etc.), mas para que a segunda instância também possui recursos suficientes (embora para trabalho não ideal através do cache do sistema de arquivos) no caso de falha de um dos data centers. O escravo não fornece serviços (não executa solicitações somente leitura) durante a operação normal do cluster, para que não haja guerra por recursos com o mestre na mesma máquina.

No caso de dois nós, a tolerância a falhas só é possível com replicação assíncrona, pois com replicação síncrona a falha do escravo levará à parada do mestre.

falha em testemunhar

Modelagem de clusters de failover com base em PostgreSQL e Pacemaker

falha em testemunhar (dispositivo de quórum) Vou considerar apenas para o cluster Tuchanka1, a mesma história acontecerá com todos os outros. Se a testemunha falhar, nada mudará na estrutura do cluster, tudo continuará funcionando da mesma forma que funcionou. Mas o quorum será de 2 em 3 e, portanto, qualquer próxima falha será fatal para o cluster. Ainda precisa ser feito com urgência.

Rejeição Tuchanka1

Modelagem de clusters de failover com base em PostgreSQL e Pacemaker

Falha de um dos data centers de Tuchanka1. Nesse caso testemunha vota no segundo nó do segundo data center. Lá, o antigo escravo se transforma em mestre, como resultado, ambos os mestres trabalham no mesmo servidor e ambos os seus IPs flutuantes apontam para eles.

Tuchanka2 (clássico)

Estrutura

Modelagem de clusters de failover com base em PostgreSQL e Pacemaker

O esquema clássico de dois nós. O mestre trabalha em um, o escravo trabalha no segundo. Ambos podem executar solicitações (o escravo é somente leitura), então ambos são apontados pelo IP flutuante: krogan2 é o mestre, krogan2s1 é o escravo. Tanto o mestre quanto o escravo terão tolerância a falhas.

No caso de dois nós, a tolerância a falhas só é possível com replicação assíncrona, pois com replicação síncrona a falha do escravo levará à parada do mestre.

Rejeição Tuchanka2

Modelagem de clusters de failover com base em PostgreSQL e Pacemaker

Se um dos data centers falhar testemunha vote no segundo. No único data center em funcionamento, o mestre será gerado e ambos os IPs flutuantes apontarão para ele: mestre e escravo. Obviamente, a instância deve ser configurada de forma que tenha recursos suficientes (limites de conexão, etc.) para aceitar simultaneamente todas as conexões e solicitações do IP flutuante mestre e escravo. Ou seja, durante a operação normal, deve ter margem suficiente para limites.

Tuchanka4 (muitos escravos)

Estrutura

Modelagem de clusters de failover com base em PostgreSQL e Pacemaker

Já é outro extremo. Existem bancos de dados que possuem muitas solicitações somente leitura (um caso típico de site altamente carregado). Tuchanka4 é uma situação onde pode haver três ou mais escravos para lidar com tais solicitações, mas ainda não muitos. Com um número muito grande de escravos, será necessário inventar um sistema de replicação hierárquica. No caso mínimo (na imagem), cada um dos dois data centers possui dois servidores, cada um dos quais possui uma instância do PostgreSQL.

Outra característica deste esquema é que já é possível organizar aqui uma replicação síncrona. Ele está configurado para replicar, se possível, para outro data center, e não para uma réplica no mesmo data center que o mestre. O mestre e cada escravo são indicados por um IP flutuante. Para sempre, entre os escravos será necessário fazer algum tipo de balanceamento de pedidos proxy SQL, por exemplo, no lado do cliente. Diferentes tipos de clientes podem exigir diferentes tipos de proxy SQL, e somente os desenvolvedores clientes sabem quem precisa de qual. Esta funcionalidade pode ser implementada por um daemon externo ou por uma biblioteca cliente (conjunto de conexões), etc. Tudo isso está além do escopo do cluster de failover de banco de dados (failover Proxy SQL pode ser implementado de forma independente, juntamente com o failover do cliente).

Rejeição Tuchanka4

Modelagem de clusters de failover com base em PostgreSQL e Pacemaker

Se um data center (ou seja, dois servidores) falhar, a testemunha vota no segundo. Como resultado, dois servidores trabalham no segundo data center: o mestre trabalha em um e o IP flutuante mestre aponta para ele (para receber solicitações de leitura e gravação); e um escravo com replicação síncrona está sendo executado no segundo servidor, e um dos IPs flutuantes do escravo aponta para ele (para solicitações somente leitura).

A primeira coisa a observar: nem todos os IPs flutuantes escravos funcionarão, mas apenas um. E para funcionar corretamente com ele será necessário que proxy SQL redirecionou todas as solicitações para o único IP flutuante restante; e se proxy SQL não, você pode listar todos os escravos IP flutuantes separados por vírgulas no URL de conexão. Nesse caso, com libpq a conexão será com o primeiro IP funcional, conforme feito no sistema de teste automático. Talvez em outras bibliotecas, por exemplo, JDBC, isso não funcione e seja necessário proxy SQL. Isso é feito porque o IP flutuante para escravos é proibido de subir simultaneamente em um servidor, de modo que eles sejam distribuídos uniformemente entre os servidores escravos se houver vários deles.

Segundo: mesmo no caso de falha do data center, a replicação síncrona será mantida. E mesmo que ocorra uma falha secundária, ou seja, um dos dois servidores falhe no data center restante, o cluster, embora pare de fornecer serviços, ainda reterá informações sobre todas as transações comprometidas para as quais confirmou o commit (haverá não há informações de perda em caso de falha secundária).

Tuchanka3 (3 data centers)

Estrutura

Modelagem de clusters de failover com base em PostgreSQL e Pacemaker

Este é um cluster para uma situação em que há três data centers em pleno funcionamento, cada um com um servidor de banco de dados em pleno funcionamento. Nesse caso dispositivo de quórum não é necessário. Um mestre trabalha em um data center e os escravos trabalham nos outros dois. A replicação é síncrona, como ANY (escravo1, escravo2), ou seja, o cliente receberá uma confirmação de commit quando algum dos escravos for o primeiro a responder que aceitou o commit. Os recursos são apontados por um IP flutuante para mestre e dois para escravos. Ao contrário do Tuchanka4, todos os três IPs flutuantes são tolerantes a falhas. Para equilibrar consultas SQL somente leitura, você pode usar proxy SQL (com tolerância a falhas separada), ou atribuir um IP float escravo para metade dos clientes e o segundo para a outra metade.

Rejeição Tuchanka3

Modelagem de clusters de failover com base em PostgreSQL e Pacemaker

Se um dos data centers falhar, restam dois. Em um, o IP mestre e flutuante do mestre são gerados, no segundo, o escravo e ambos os IPs flutuantes escravos (deve haver uma reserva dupla de recursos na instância para aceitar todas as conexões de ambos os IPs flutuantes escravos). Replicação síncrona entre mestres e escravos. Além disso, o cluster salvará informações sobre transações confirmadas e confirmadas (não haverá perda de informações) em caso de destruição de dois data centers (se não forem destruídos ao mesmo tempo).

Decidi não incluir uma descrição detalhada da estrutura e implantação do arquivo. Se quiser brincar, você pode ler tudo isso no README. Dou apenas uma descrição dos testes automáticos.

Sistema de teste automático

Para verificar a tolerância a falhas de clusters com imitação de falhas diversas, foi feito um sistema de teste automático. Lançado por um script test/failure. O script pode tomar como parâmetros o número de clusters que você deseja testar. Por exemplo, este comando:

test/failure 2 3

testará apenas o segundo e o terceiro cluster. Se os parâmetros não forem especificados, todos os clusters serão testados. Todos os clusters são testados em paralelo e o resultado é exibido no painel tmux. O Tmux usa um servidor tmux dedicado, então o script pode ser executado no tmux padrão, resultando em um tmux aninhado. Recomendo usar o terminal em uma janela grande e com fonte pequena. Antes de iniciar o teste, todas as máquinas virtuais são revertidas para um instantâneo no momento em que o script termina setup.

Modelagem de clusters de failover com base em PostgreSQL e Pacemaker

O terminal é dividido em colunas de acordo com o número de clusters testados, por padrão (na captura de tela) são quatro. Descreverei o conteúdo das colunas usando Tuchanka2 como exemplo. Os painéis na captura de tela são numerados:

  1. É aqui que as estatísticas do teste são exibidas. Caixas de som:
    • falha — o nome do teste (função no script) que emula a falha.
    • reação — a média aritmética do tempo em segundos durante o qual o cluster restaurou o seu desempenho. É medido desde o início do script que emula a falha, e até o momento em que o cluster restaura sua saúde e consegue continuar prestando serviços. Se o tempo for muito curto, por exemplo, seis segundos (isso acontece em clusters com vários escravos (Tuchanka3 e Tuchanka4)), isso significa que o mau funcionamento acabou em um escravo assíncrono e não afetou de forma alguma o desempenho, não houve interruptores de estado do cluster.
    • desvio - mostra o spread (precisão) do valor reação pelo método do desvio padrão.
    • contar Quantas vezes este teste foi realizado.
  2. Um pequeno log permite avaliar o que o cluster está fazendo atualmente. O número da iteração (teste), o carimbo de data/hora e o nome da operação são exibidos. A execução muito longa (> 5 minutos) indica algum tipo de problema.
  3. coração (coração) é a hora atual. Para avaliação de desempenho visual mestres a hora atual é constantemente gravada em sua tabela usando o IP flutuante do mestre. Se for bem-sucedido, o resultado será exibido neste painel.
  4. bater (pulso) - “hora atual”, que foi previamente registrada pelo script coração para dominar, agora leia de escravo através de seu IP flutuante. Permite avaliar visualmente o desempenho de um escravo e de replicação. Não há escravos com IP flutuante em Tuchanka1 (não há escravos prestando serviços), mas há duas instâncias (DB), portanto não será mostrado aqui baterE coração segunda instância.
  5. Monitorando o estado do cluster usando o utilitário pcs mon. Mostra a estrutura, distribuição de recursos por nós e outras informações úteis.
  6. Ele exibe o monitoramento do sistema de cada máquina virtual do cluster. Pode haver mais painéis desse tipo - quantas máquinas virtuais o cluster possui. Dois gráficos Carga da CPU (dois processadores em máquinas virtuais), nome da máquina virtual, Carga do sistema (denominado Load Average porque teve uma média de 5, 10 e 15 minutos), dados de processo e alocação de memória.
  7. Rastreando o script que realiza os testes. Em caso de avaria - uma interrupção repentina do trabalho ou um ciclo de espera interminável - aqui poderá ver o motivo deste comportamento.

O teste é realizado em duas etapas. Primeiramente, o script passa por todos os tipos de testes, escolhendo aleatoriamente uma máquina virtual na qual esse teste deverá ser aplicado. Em seguida, um ciclo interminável de testes é executado, máquinas virtuais e um mau funcionamento são selecionados aleatoriamente a cada vez. O encerramento repentino do script de teste (painel inferior) ou um loop de espera interminável por algo (> 5 minutos para concluir uma operação, isso pode ser visto no rastreamento) indica que alguns dos testes neste cluster falharam.

Cada teste consiste nas seguintes operações:

  1. Iniciando uma função que emula uma falha.
  2. Pronto? - aguardar a restauração da saúde do cluster (quando todos os serviços forem prestados).
  3. O tempo limite de recuperação do cluster é mostrado (reação).
  4. Fixar - o cluster está "reparado". Depois disso, ele deverá retornar a um estado totalmente operacional e pronto para o próximo mau funcionamento.

Aqui está uma lista de testes com uma descrição do que eles fazem:

  • Bomba Garfo: Cria "Sem memória" com uma bomba fork.
  • Fora do espaço: o disco rígido está cheio. Mas o teste é bastante simbólico, com a carga insignificante que é criada durante o teste, quando o disco rígido transborda, o PostgreSQL geralmente não falha.
  • Postgres-KILL: mata o PostgreSQL com o comando killall -KILL postgres.
  • postgres-STOP: trava o PostgreSQL com o comando killall -STOP postgres.
  • Desligar: "desenergiza" a máquina virtual com o comando VBoxManage controlvm "виртуалка" poweroff.
  • Limpar: recarrega a máquina virtual com o comando VBoxManage controlvm "виртуалка" reset.
  • PARADA SBD: suspende o daemon SBD com o comando killall -STOP sbd.
  • Shutdown: via SSH envia um comando para a máquina virtual systemctl poweroff, o sistema será encerrado normalmente.
  • desligar: isolamento de rede, comando VBoxManage controlvm "виртуалка" setlinkstate1 off.

Finalize o teste com o comando tmux padrão "kill-window" ctrl-b&, ou pelo comando "detach-client" ctrl-bd: ao mesmo tempo, o teste é concluído, o tmux é fechado e as máquinas virtuais são desligadas.

Problemas identificados durante o teste

  • Neste momento daemon watchdog sbd lida com a parada de daemons observados, mas não com o congelamento deles. E, como resultado, o mau funcionamento é resolvido incorretamente, levando apenas ao congelamento Corosync и Marcapasso cardíaco, mas não pendurado sbd... Para verificar Corosync ja tem PR # 83 (no GitHub em sbd), aceito no ramo dominar. Eles prometeram (no PR#83) que haveria algo semelhante para o Pacemaker, espero que até Redhat 8 vai fazer. Mas tais “maus funcionamentos” são especulativos, facilmente imitados artificialmente usando, por exemplo, killall -STOP corosyncmas nunca se encontram na vida real.

  • У Marcapasso cardíaco na versão para 7 CentOS definido incorretamente sincronização_timeout у dispositivo de quórum, como um resultado se um nó falhar, o segundo nó será reinicializado com alguma probabilidade, para o qual o mestre deveria se mudar. Curado por ampliação sincronização_timeout у dispositivo de quórum durante a implantação (no script setup/setup1). Esta alteração não foi aceita pelos desenvolvedores Marcapasso cardíaco, em vez disso, prometeram retrabalhar a infra-estrutura de tal forma (num futuro indefinido) que este tempo limite seja calculado automaticamente.

  • Se você especificou durante a configuração do banco de dados que LC_MESSAGES (mensagens de texto) Unicode pode ser usado, por exemplo, ru_RU.UTF-8, então na inicialização postgres em um ambiente onde a localidade não é UTF-8, digamos, em um ambiente vazio (aqui pacemaker+pgsqlms(paf) começa postgres), então no log em vez de letras UTF-8 haverá pontos de interrogação. Os desenvolvedores do PostgreSQL nunca concordaram sobre o que fazer neste caso. Custa, você precisa colocar LC_MESSAGES=en_US.UTF-8 ao configurar (criar) uma instância de banco de dados.

  • Se wal_receiver_timeout estiver definido (por padrão é 60s), ao testar o PostgreSQL-STOP no mestre nos clusters tuchanka3 e tuchanka4 A replicação não se reconecta a um novo mestre. A replicação lá é síncrona, então não só o escravo para, mas também o novo mestre. Obtém definindo wal_receiver_timeout=0 ao configurar o PostgreSQL.

  • Ocasionalmente, observei a replicação do PostgreSQL travada no teste ForkBomb (estouro de memória). Após o ForkBomb, às vezes os escravos podem não se reconectar ao novo mestre. Eu vi isso apenas nos clusters tuchanka3 e tuchanka4, onde devido ao fato da replicação ser síncrona, o mestre travou. O problema desapareceu sozinho, depois de muito tempo (cerca de duas horas). Mais pesquisas são necessárias para corrigir isso. Os sintomas são semelhantes aos do bug anterior, que é causado por uma causa diferente, mas com as mesmas consequências.

Foto de Krogan tirada de Deviant Art com a permissão do autor:

Modelagem de clusters de failover com base em PostgreSQL e Pacemaker

Fonte: habr.com

Adicionar um comentário