{"id":92570,"date":"2020-08-28T19:42:21","date_gmt":"2020-08-28T17:42:21","guid":{"rendered":"https:\/\/prohoster.info\/blog\/administrirovanie\/modelirovanie-otkazoustojchivyh-klasterov-na-baze-postgresql-i-pacemaker"},"modified":"2020-08-28T19:42:21","modified_gmt":"2020-08-28T17:42:21","slug":"modelirovanie-otkazoustojchivyh-klasterov-na-baze-postgresql-i-pacemaker","status":"publish","type":"post","link":"https:\/\/prohoster.info\/pt\/blog\/administrirovanie\/modelirovanie-otkazoustojchivyh-klasterov-na-baze-postgresql-i-pacemaker","title":{"rendered":"Modelagem de clusters tolerantes a falhas com PostgreSQL e Pacemaker","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<h1 id=\"vvedenie\">Introdu\u00e7\u00e3o<\/h1>\n<p><\/p>\n<p>H\u00e1 algum tempo, fui encarregado de desenvolver um cluster de alta disponibilidade para <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\">PostgreSQL<\/a><\/noindex>, operando em v\u00e1rios centros de dados interconectados por fibra \u00f3ptica dentro de uma \u00fanica cidade, e capaz de suportar a falha (por exemplo, perda de energia) de um centro de dados. Como software respons\u00e1vel pela alta disponibilidade, escolhi <noindex><a rel=\"nofollow\" href=\"https:\/\/clusterlabs.org\">Pacemaker<\/a><\/noindex>, porque \u00e9 a solu\u00e7\u00e3o oficial da RedHat para a cria\u00e7\u00e3o de clusters de alta disponibilidade. \u00c9 favor\u00e1vel, pois a RedHat oferece suporte, e \u00e9 uma solu\u00e7\u00e3o universal (modular). Com isso, ser\u00e1 poss\u00edvel garantir a alta disponibilidade n\u00e3o apenas do PostgreSQL, mas tamb\u00e9m de outros servi\u00e7os, seja atrav\u00e9s de m\u00f3dulos padr\u00e3o ou criando-os para necessidades espec\u00edficas.<\/p>\n<p><\/p>\n<p>A essa solu\u00e7\u00e3o surgiu uma pergunta pertinente: qu\u00e3o resiliente ser\u00e1 o cluster de alta disponibilidade? Para investigar isso, desenvolvi um ambiente de teste que simula v\u00e1rias falhas nos n\u00f3s do cluster, aguarda a recupera\u00e7\u00e3o do funcionamento, restaura o n\u00f3 que falhou e continua o teste em ciclo. Inicialmente, este projeto se chamava hapgsql, mas com o tempo fiquei entediado com o nome, que tinha apenas uma vogal. Portanto, comecei a nomear as bases de dados de alta disponibilidade (e o IP flutuante que as aponta) de <strong>krogan<\/strong> (um personagem de um jogo de computador que tem todos os \u00f3rg\u00e3os importantes duplicados), e os n\u00f3s, clusters e o pr\u00f3prio projeto de <strong>tuchanka<\/strong> (o planeta onde vivem os krogan).<\/p>\n<p><\/p>\n<p>Atualmente, a ger\u00eancia autorizou <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/domclick\/tuchanka\">a abrir o projeto para a comunidade open source sob a licen\u00e7a MIT<\/a><\/noindex>. O README ser\u00e1 em breve traduzido para o ingl\u00eas (pois espera-se que os principais usu\u00e1rios sejam desenvolvedores do Pacemaker e PostgreSQL), e decidi formatar a vers\u00e3o antiga em russo do README (parcialmente) como este artigo.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Modelagem de clusters tolerantes a falhas com PostgreSQL e Pacemaker\" src=\"\/wp-content\/uploads\/2020\/08\/7ebb04b3e56337060e981da319192a28.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<p>Os clusters s\u00e3o implantados em m\u00e1quinas virtuais <noindex><a rel=\"nofollow\" href=\"https:\/\/www.virtualbox.org\">VirtualBox<\/a><\/noindex>. No total, ser\u00e3o implantadas 12 m\u00e1quinas virtuais (totalizando 36GiB), que formam 4 clusters de alta disponibilidade (diferentes variantes). Os dois primeiros clusters s\u00e3o compostos por dois servidores PostgreSQL, que est\u00e3o localizados em diferentes centros de dados, e um servidor compartilhado <em>witness<\/em> c <strong>quorum device<\/strong> (localizado em uma m\u00e1quina virtual barata em um terceiro centro de dados), que resolve a ambiguidade <strong>50%\/50%<\/strong>, dando seu voto a um dos lados. O terceiro cluster abrange tr\u00eas centros de dados: um mestre, dois escravos, sem <strong>quorum device<\/strong>. O quarto cluster \u00e9 composto por quatro servidores PostgreSQL, dois em cada data center: um mestre e os outros como r\u00e9plicas, e tamb\u00e9m utiliza <em>witness<\/em> c <strong>quorum device<\/strong>. O quarto suporta a falha de dois servidores ou de um data center. Esta solu\u00e7\u00e3o pode ser escalada para um maior n\u00famero de r\u00e9plicas, se necess\u00e1rio.<\/p>\n<p><\/p>\n<p>Servi\u00e7o de Hora Precisa <noindex><a rel=\"nofollow\" href=\"https:\/\/www.ntp.org\">ntpd<\/a><\/noindex> tamb\u00e9m est\u00e1 configurado para resist\u00eancia a falhas, mas utiliza o m\u00e9todo de <code>ntpd<\/code> (<em>modo orphan<\/em>). O servidor geral <em>witness<\/em> atua como o servidor NTP central, distribuindo sua hora para todos os clusters, sincronizando assim todos os servidores entre si. Se <em>witness<\/em> falhar ou ficar isolado, um dos servidores do cluster come\u00e7ar\u00e1 a distribuir seu tempo (dentro do cluster). Um cache de apoio <strong>proxy HTTP<\/strong> tamb\u00e9m foi levantado em <em>witness<\/em>, com isso as outras m\u00e1quinas virtuais t\u00eam acesso aos reposit\u00f3rios Yum. Na realidade, servi\u00e7os como hora precisa e proxy provavelmente ser\u00e3o hospedados em servidores dedicados, enquanto na configura\u00e7\u00e3o atual est\u00e3o alocados em <em>witness<\/em> apenas para economizar virtual machines e espa\u00e7o.<\/p>\n<p><\/p>\n<h1 id=\"versii\">Vers\u00f5es<\/h1>\n<p><\/p>\n<p>v0. Funciona com CentOS 7 e PostgreSQL 11 no VirtualBox 6.1.<\/p>\n<p><\/p>\n<h1 id=\"struktura-klasterov\">Estrutura dos Clusters<\/h1>\n<p><\/p>\n<p>Todos os clusters foram projetados para serem localizados em v\u00e1rios data centers, unidos em uma rede plana e deve suportar a falha ou o isolamento de um data center. Portanto, <strong>\u00e9 imposs\u00edvel<\/strong> usar para prote\u00e7\u00e3o contra <strong>split-brain<\/strong> a tecnologia padr\u00e3o do Pacemaker, chamada de <em>STONITH<\/em> (Shoot The Other Node In The Head) ou <em>fencing<\/em>. A ess\u00eancia: se os n\u00f3s no cluster come\u00e7am a suspeitar que um dos n\u00f3s est\u00e1 apresentando problemas, n\u00e3o responde ou se comporta de maneira errada, eles o desligam for\u00e7osamente atrav\u00e9s de dispositivos 'externos', como um cart\u00e3o controlador IPMI ou UPS. Mas isso s\u00f3 funcionar\u00e1 nos casos em que, em uma \u00fanica falha de servidor, o IPMI ou UPS continuem operando. Aqui, a prote\u00e7\u00e3o est\u00e1 prevista para uma falha muito mais catastr\u00f3fica, quando todo o data center falha (por exemplo, perde a energia). E com essa falha, todos os <em>dispositivos stonith (IPMI, UPS, etc.) tamb\u00e9m n\u00e3o funcionar\u00e3o.<\/em>Em vez disso, o sistema baseia-se na ideia de qu\u00f3rum. Todos os n\u00f3s t\u00eam voz, e s\u00f3 podem trabalhar aqueles que veem mais da metade de todos os n\u00f3s. Esta quantidade 'metade+1' \u00e9 chamada de<\/p>\n<p><\/p>\n<p>qu\u00f3rum <strong>.<\/strong>. Se o qu\u00f3rum n\u00e3o for alcan\u00e7ado, o n\u00f3 decide que est\u00e1 em isolamento de rede e deve desligar seus recursos, ou seja, \u00e9 uma <strong>prote\u00e7\u00e3o contra split-brain<\/strong>. Se o software que gerencia esse comportamento n\u00e3o funcionar, um watchdog deve entrar em a\u00e7\u00e3o, por exemplo, baseado em IPMI.<\/p>\n<p><\/p>\n<p>Se o n\u00famero de n\u00f3s for par (cluster em dois data centers), pode ocorrer o que se chama incerteza <strong>50%\/50%<\/strong> (<em>cinquenta\/cinquenta<\/em>), quando o isolamento de rede divide o cluster exatamente ao meio. Portanto, para um n\u00famero par de n\u00f3s, \u00e9 adicionado <strong>quorum device<\/strong> \u2014 um daemon que n\u00e3o exige muitos recursos, que pode ser executado na m\u00e1quina virtual mais barata de um terceiro data center. Ele d\u00e1 seu voto a um dos segmentos (que v\u00ea), assim resolvendo a incerteza 50%\/50%. O servidor onde ser\u00e1 executado o dispositivo de qu\u00f3rum eu chamei de <em>witness<\/em> (terminologia do repmgr, que achei interessante).<\/p>\n<p><\/p>\n<p>Os recursos podem ser movidos de um lugar para outro, por exemplo, de servidores defeituosos para servidores funcionando, ou por comando dos administradores. Para que os clientes saibam onde est\u00e3o os recursos que necessitam (para onde se conectar?), s\u00e3o utilizados <em>IPs flutuantes<\/em> (<strong>float IP<\/strong>). Esses IPs, que o Pacemaker pode mover entre os n\u00f3s (tudo est\u00e1 em uma rede plana), simbolizam um recurso (servi\u00e7o) e estar\u00e3o onde \u00e9 necess\u00e1rio se conectar para ter acesso a esse servi\u00e7o (no nosso caso, ao BD).<\/p>\n<p><\/p>\n<h2 id=\"tuchanka1-shema-s-uplotneniem\">Tuchanka1 (esquema com compacta\u00e7\u00e3o)<\/h2>\n<p><\/p>\n<h3 id=\"struktura\">Estrutura<\/h3>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Modelagem de clusters tolerantes a falhas com PostgreSQL e Pacemaker\" src=\"\/wp-content\/uploads\/2020\/08\/5651238e36f4af1c32f117191cf30261.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>A ideia foi que temos muitos pequenos bancos de dados com baixa carga, pelos quais n\u00e3o compensa manter um servidor slave dedicado em modo de hot standby para transa\u00e7\u00f5es de leitura (n\u00e3o h\u00e1 necessidade de tal desperd\u00edcio de recursos).<\/p>\n<p><\/p>\n<p>Em cada data center h\u00e1 um servidor. Em cada servidor, existem duas inst\u00e2ncias do PostgreSQL (na terminologia do PostgreSQL, elas s\u00e3o chamadas de clusters, mas para evitar confus\u00e3o, eu as chamarei de inst\u00e2ncias (por analogia com outros bancos de dados), e chamarei de clusters apenas os clusters do Pacemaker). Uma inst\u00e2ncia opera no modo mestre, e apenas ela presta servi\u00e7os (apenas ela recebe o IP flutuante). A segunda inst\u00e2ncia opera como escravo para o segundo data center e prestar\u00e1 servi\u00e7os apenas se seu mestre falhar. Uma vez que a maior parte do tempo a presta\u00e7\u00e3o de servi\u00e7os (execu\u00e7\u00e3o de consultas) ser\u00e1 realizada apenas por uma das duas inst\u00e2ncias (o mestre), todos os recursos do servidor s\u00e3o otimizados para o mestre (mem\u00f3ria \u00e9 alocada para o cache shared_buffers, etc.), mas de modo que haja recursos suficientes para a segunda inst\u00e2ncia (mesmo que para um funcionamento sub\u00f3timo atrav\u00e9s do cache do sistema de arquivos) em caso de falha de um dos data centers. O escravo n\u00e3o presta servi\u00e7os (n\u00e3o executa consultas read only) durante a opera\u00e7\u00e3o normal do cluster, para evitar competi\u00e7\u00e3o por recursos com o mestre na mesma m\u00e1quina.<\/p>\n<p><\/p>\n<p>No caso de dois n\u00f3s, a alta disponibilidade s\u00f3 \u00e9 poss\u00edvel com replica\u00e7\u00e3o ass\u00edncrona, pois na replica\u00e7\u00e3o s\u00edncrona, a falha do escravo levar\u00e1 \u00e0 parada do mestre.<\/p>\n<p><\/p>\n<h3 id=\"otkaz-witness\">Falha do witness<\/h3>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Modelagem de clusters tolerantes a falhas com PostgreSQL e Pacemaker\" src=\"\/wp-content\/uploads\/2020\/08\/3c046d13c0c6839de297827ca3a8928b.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Falha do witness (<em>quorum device<\/em>) eu vou considerar apenas para o cluster Tuchanka1, a hist\u00f3ria ser\u00e1 a mesma para todos os outros. Em caso de falha do witness na estrutura do cluster, nada mudar\u00e1, tudo continuar\u00e1 a funcionar como antes. Mas o qu\u00f3rum se tornar\u00e1 igual a 2 em 3, e portanto qualquer falha subsequente ser\u00e1 fatal para o cluster. Afinal, ter\u00e1 que ser urgente consertado.<\/p>\n<p><\/p>\n<h3 id=\"otkaz-tuchanka1\">Falha do Tuchanka1<\/h3>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Modelagem de clusters tolerantes a falhas com PostgreSQL e Pacemaker\" src=\"\/wp-content\/uploads\/2020\/08\/112957293bd682428115e4e93c9f1a96.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Falha de um dos data centers para o Tuchanka1. Nesse caso <em>witness<\/em> ceder\u00e1 seu voto ao segundo n\u00f3 no segundo data center. L\u00e1, o antigo escravo se transforma em mestre, resultando em que ambos os mestres operam em um servidor e ambos recebem seus IPs flutuantes.<\/p>\n<p><\/p>\n<h2 id=\"tuchanka2-klassicheskaya\">Tuchanka2 (cl\u00e1ssico)<\/h2>\n<p><\/p>\n<h3 id=\"struktura-1\">Estrutura<\/h3>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Modelagem de clusters tolerantes a falhas com PostgreSQL e Pacemaker\" src=\"\/wp-content\/uploads\/2020\/08\/c3af368f823fbd580b4ebb14cc87c750.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Esquema cl\u00e1ssico de dois n\u00f3s. Em um, opera o mestre; no outro, o escravo. Ambos podem executar consultas (escravo apenas read only), portanto ambos t\u00eam IPs flutuantes: krogan2 \u2014 para o mestre, krogan2s1 \u2014 para o escravo. A alta disponibilidade ser\u00e1 mantida tanto para o mestre quanto para o escravo.<\/p>\n<p><\/p>\n<p>No caso de dois n\u00f3s, a alta disponibilidade s\u00f3 \u00e9 poss\u00edvel com replica\u00e7\u00e3o ass\u00edncrona, pois na replica\u00e7\u00e3o s\u00edncrona, a falha do escravo levar\u00e1 \u00e0 parada do mestre.<\/p>\n<p><\/p>\n<h3 id=\"otkaz-tuchanka2\">Falha do Tuchanka2<\/h3>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Modelagem de clusters tolerantes a falhas com PostgreSQL e Pacemaker\" src=\"\/wp-content\/uploads\/2020\/08\/79bfcaf88c96d8ee16767dcef53741c1.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Na falha de um dos data centers <em>witness<\/em> vota pelo segundo. No \u00fanico data center em funcionamento, um mestre ser\u00e1 levantado, e ambos os IPs flutuantes \u2014 o do mestre e o do escravo \u2014 apontar\u00e3o para ele. Naturalmente, a inst\u00e2ncia deve ser configurada de forma a ter recursos suficientes (limites de conex\u00e3o, etc.) para lidar simultaneamente com todas as conex\u00f5es e solicita\u00e7\u00f5es dos IPs flutuantes mestre e escravo. Ou seja, durante o funcionamento normal, deve haver uma margem suficiente nos limites.<\/p>\n<p><\/p>\n<h2 id=\"tuchanka4-mnogo-rabov\">Tuchanka4 (muitos escravos)<\/h2>\n<p><\/p>\n<h3 id=\"struktura-2\">Estrutura<\/h3>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Modelagem de clusters tolerantes a falhas com PostgreSQL e Pacemaker\" src=\"\/wp-content\/uploads\/2020\/08\/17819fd97847f0573d429e422d799bc1.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>J\u00e1 \u00e9 outra extremidade. Existem bancos de dados que recebem muitas solicita\u00e7\u00f5es somente de leitura (um caso t\u00edpico de um site de alta carga). Tuchanka4 \u00e9 uma situa\u00e7\u00e3o onde pode haver tr\u00eas ou mais escravos para processar tais solicita\u00e7\u00f5es, mas ainda assim n\u00e3o muito. Com um n\u00famero muito grande de escravos, ser\u00e1 necess\u00e1rio inventar um sistema hier\u00e1rquico de replica\u00e7\u00e3o. No caso m\u00ednimo (na imagem), h\u00e1 dois servidores em cada um dos dois data centers, em cada um dos quais reside uma inst\u00e2ncia do PostgreSQL.<\/p>\n<p><\/p>\n<p>Outra caracter\u00edstica desse esquema \u00e9 que aqui j\u00e1 \u00e9 poss\u00edvel organizar uma replica\u00e7\u00e3o s\u00edncrona. Ela \u00e9 configurada para replicar, sempre que poss\u00edvel, para outro data center, e n\u00e3o para a r\u00e9plica no mesmo data center que o mestre. Tanto o mestre quanto cada escravo apontam para um IP flutuante. Idealmente, entre os escravos, deve haver balanceamento de solicita\u00e7\u00f5es por algum <em>proxy SQL<\/em>, por exemplo, do lado do cliente. Diferentes tipos de clientes podem exigir diferentes tipos de <em>proxy SQL<\/em>, e somente os desenvolvedores dos clientes sabem quem precisa de qual. Essa funcionalidade pode ser implementada tanto como um dem\u00f4nio externo quanto como uma biblioteca de cliente (pool de conex\u00f5es), etc. Tudo isso est\u00e1 al\u00e9m do escopo do tema de um cluster de banco de dados tolerante a falhas (a toler\u00e2ncia a falhas <em>proxy SQL<\/em> pode ser implementada de forma independente, juntamente com a toler\u00e2ncia a falhas do cliente).<\/p>\n<p><\/p>\n<h3 id=\"otkaz-tuchanka4\">Falha Tuchanka4<\/h3>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Modelagem de clusters tolerantes a falhas com PostgreSQL e Pacemaker\" src=\"\/wp-content\/uploads\/2020\/08\/e005ae90ffd63abdb272012b94735618.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>No caso de falha de um data center (ou seja, de dois servidores), o witness vota pelo segundo. Como resultado, funcionam dois servidores no segundo data center: em um est\u00e1 o mestre, e nele aponta o IP flutuante do mestre (para aceitar solicita\u00e7\u00f5es de leitura e grava\u00e7\u00e3o); e no segundo servidor, funciona um escravo com replica\u00e7\u00e3o s\u00edncrona, e nele aponta um dos IPs flutuantes dos escravos (para solicita\u00e7\u00f5es somente de leitura).<\/p>\n<p><\/p>\n<p>A primeira coisa a ser observada: n\u00e3o ser\u00e3o todos os IPs flutuantes dos escravos que estar\u00e3o ativos, mas apenas um. E para o funcionamento correto com ele, ser\u00e1 necess\u00e1rio que <em>proxy SQL<\/em> redirecionou todas as solicita\u00e7\u00f5es para o \u00fanico IP float restante; se n\u00e3o, <em>proxy SQL<\/em> pode listar todos os IPs float dos escravos separados por v\u00edrgula na URL de conex\u00e3o. Nesse caso, <em>libpq<\/em> a conex\u00e3o ser\u00e1 feita ao primeiro IP de trabalho, assim foi feito no sistema de testes autom\u00e1ticos. Pode ser que em outras bibliotecas, como JDBC, isso n\u00e3o funcione e seja necess\u00e1rio <em>proxy SQL<\/em>. Isso foi feito porque os IPs float dos escravos n\u00e3o podem ser levantados simultaneamente em um servidor, para que sejam distribu\u00eddos uniformemente entre os servidores escravos, caso haja v\u00e1rios em funcionamento.<\/p>\n<p><\/p>\n<p>Segunda: mesmo em caso de falha do data center, a replica\u00e7\u00e3o s\u00edncrona ser\u00e1 mantida. E mesmo que haja uma segunda falha, ou seja, um dos dois servidores no data center restante falhe, o cluster, embora deixe de prestar servi\u00e7os, ainda manter\u00e1 informa\u00e7\u00f5es sobre todas as transa\u00e7\u00f5es comprometidas, para as quais ele deu confirma\u00e7\u00e3o de commit (n\u00e3o haver\u00e1 perda de informa\u00e7\u00f5es em caso de falha secund\u00e1ria).<\/p>\n<p><\/p>\n<h2 id=\"tuchanka3-3-data-centra\">Tuchanka3 (3 data centers)<\/h2>\n<p><\/p>\n<h3 id=\"struktura-3\">Estrutura<\/h3>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Modelagem de clusters tolerantes a falhas com PostgreSQL e Pacemaker\" src=\"\/wp-content\/uploads\/2020\/08\/e11f9884b92fe20a63b5080ae8c7f82b.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Este \u00e9 um cluster para situa\u00e7\u00f5es em que existem tr\u00eas data centers plenamente operacionais, em cada um dos quais h\u00e1 um servidor de banco de dados totalmente funcional. Nesse caso, <em>quorum device<\/em> n\u00e3o \u00e9 necess\u00e1rio. Em um data center, o mestre opera, enquanto nos outros dois, os escravos. A replica\u00e7\u00e3o \u00e9 s\u00edncrona, do tipo ANY (slave1, slave2), ou seja, o cliente receber\u00e1 confirma\u00e7\u00e3o de commit quando qualquer um dos escravos responder primeiro que aceitou o commit. Um IP float \u00e9 designado para o mestre e dois para os escravos. Ao contr\u00e1rio do Tuchanka4, todos os tr\u00eas IPs float s\u00e3o tolerantes a falhas. Para balancear consultas SQL somente leitura, voc\u00ea pode usar <em>proxy SQL<\/em> (com toler\u00e2ncia a falhas separada), ou designar um IP float escravo para metade dos clientes e o outro para a outra metade.<\/p>\n<p><\/p>\n<h3 id=\"otkaz-tuchanka3\">Falha do Tuchanka3<\/h3>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Modelagem de clusters tolerantes a falhas com PostgreSQL e Pacemaker\" src=\"\/wp-content\/uploads\/2020\/08\/1e61158be3c23742384d3621e8f7896b.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Em caso de falha de um dos data centers, permanecem dois. Em um, o mestre e o IP float do mestre est\u00e3o ativos; no segundo, o escravo e ambos os IPs float dos escravos (a inst\u00e2ncia deve ter um suprimento de recursos duplicado para aceitar todas as conex\u00f5es de ambos os IPs float dos escravos). Entre o mestre e o escravo h\u00e1 replica\u00e7\u00e3o s\u00edncrona. O cluster tamb\u00e9m manter\u00e1 informa\u00e7\u00f5es sobre transa\u00e7\u00f5es comprometidas e confirmadas (n\u00e3o haver\u00e1 perda de informa\u00e7\u00f5es) em caso de destrui\u00e7\u00e3o de dois data centers (se forem destru\u00eddos n\u00e3o simultaneamente).<\/p>\n<p><\/p>\n<p><em>Decidi n\u00e3o incluir uma descri\u00e7\u00e3o detalhada da estrutura de arquivos e implanta\u00e7\u00e3o. Quem quiser experimentar, pode ler tudo isso no README. Apresento apenas a descri\u00e7\u00e3o do teste autom\u00e1tico.<\/em><\/p>\n<p><\/p>\n<h1 id=\"sistema-avtomaticheskogo-testirovaniya\">Sistema de teste autom\u00e1tico<\/h1>\n<p><\/p>\n<p>Para verificar a resist\u00eancia a falhas dos clusters simulando v\u00e1rias falhas, foi criado um sistema de teste autom\u00e1tico. \u00c9 iniciado por um script <code>test\/failure<\/code>. O script pode aceitar como par\u00e2metros os n\u00fameros dos clusters que deseja testar. Por exemplo, este comando:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">test\/failure 2 3<\/code><\/pre>\n<p><\/p>\n<p>testar\u00e1 apenas o segundo e o terceiro cluster. Se os par\u00e2metros n\u00e3o forem especificados, todos os clusters ser\u00e3o testados. Todos os clusters s\u00e3o testados em paralelo, e o resultado \u00e9 exibido no painel tmux. O tmux utiliza um servidor tmux dedicado, portanto o script pode ser executado a partir do tmux padr\u00e3o, resultando em tmux aninhado. Recomendo usar um terminal com uma janela grande e fonte pequena. Antes de iniciar o teste, todas as m\u00e1quinas virtuais s\u00e3o revertidas para um snapshot no momento do t\u00e9rmino do script. <code>setup<\/code>.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Modelagem de clusters tolerantes a falhas com PostgreSQL e Pacemaker\" src=\"\/wp-content\/uploads\/2020\/08\/b546bab1ebbbe365991e1ff3d1667237.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>O terminal \u00e9 dividido em colunas conforme o n\u00famero de clusters testados, por padr\u00e3o (na captura de tela) s\u00e3o quatro. O conte\u00fado das colunas ser\u00e1 detalhado usando Tuchanka2 como exemplo. Os pain\u00e9is na captura de tela est\u00e3o numerados:<\/p>\n<p><\/p>\n<ol>\n<li>Aqui \u00e9 exibida a estat\u00edstica dos testes. Colunas:\n<ul>\n<li><strong>failure<\/strong> \u2014 o nome do teste (fun\u00e7\u00e3o no script) que simula uma falha.<\/li>\n<li><strong>reaction<\/strong> \u2014 a m\u00e9dia aritm\u00e9tica do tempo em segundos que o cluster levou para restaurar sua funcionalidade. \u00c9 medido desde o in\u00edcio do funcionamento do script que simula a falha at\u00e9 o momento em que o cluster recupera sua funcionalidade e \u00e9 capaz de continuar prestando servi\u00e7os. Se o tempo for muito curto, por exemplo, seis segundos (o que acontece em clusters com v\u00e1rios escravos (Tuchanka3 e Tuchanka4)), isso significa que a falha ocorreu em um escravo ass\u00edncrono e n\u00e3o afetou a funcionalidade, n\u00e3o houve mudan\u00e7as no estado do cluster.<\/li>\n<li><strong>deviation<\/strong> \u2014 mostra a dispers\u00e3o (precis\u00e3o) do valor <strong>reaction<\/strong> pelo m\u00e9todo de \u2018desvio padr\u00e3o\u2019.<\/li>\n<li><strong>count<\/strong> \u2014 quantas vezes esse teste foi realizado.<\/li>\n<\/ul>\n<\/li>\n<li>Um registro breve permite avaliar o que o cluster est\u00e1 fazendo no momento atual. \u00c9 exibido o n\u00famero da itera\u00e7\u00e3o (teste), a timestamp e o nome da opera\u00e7\u00e3o. Um tempo de execu\u00e7\u00e3o muito longo (&gt; 5 minutos) indica algum problema.<\/li>\n<li><strong>heart<\/strong> (cora\u00e7\u00e3o) \u2014 tempo atual. Para avalia\u00e7\u00e3o visual da funcionalidade <em>mestre<\/em> em sua tabela, o tempo atual \u00e9 constantemente escrito usando o IP float do mestre. Em caso de sucesso, o resultado \u00e9 exibido neste painel.<\/li>\n<li><strong>batida<\/strong> (pulso) \u2014 \"tempo atual\" que foi anteriormente registrado pelo script <strong>heart<\/strong> no mestre, agora \u00e9 lido do <em>escravo<\/em> atrav\u00e9s de seu IP float. Permite avaliar visualmente a funcionalidade do escravo e da replica\u00e7\u00e3o. Em Tuchanka1, n\u00e3o h\u00e1 escravos com IP flutuante (n\u00e3o h\u00e1 escravos fornecendo servi\u00e7os), mas h\u00e1 duas inst\u00e2ncias (BD), portanto, aqui ser\u00e1 exibido n\u00e3o <strong>batida<\/strong>, e <strong>heart<\/strong> da segunda inst\u00e2ncia.<\/li>\n<li>Monitoramento do estado do cluster utilizando a ferramenta <code>pcs mon<\/code>. Mostra a estrutura, distribui\u00e7\u00e3o de recursos pelos n\u00f3s e outras informa\u00e7\u00f5es \u00fateis.<\/li>\n<li>Aqui \u00e9 exibido o monitoramento do sistema de cada virtualiza\u00e7\u00e3o do cluster. Pode haver mais pain\u00e9is \u2014 quantas virtualiza\u00e7\u00f5es houver no cluster. Dois gr\u00e1ficos <em>Carga da CPU<\/em> (nas virtualiza\u00e7\u00f5es com dois processadores), nome da virtualiza\u00e7\u00e3o, <em>Carga do Sistema<\/em> (denominado como M\u00e9dia de Carga, pois \u00e9 calculado pela m\u00e9dia de 5, 10 e 15 minutos), dados sobre os processos e distribui\u00e7\u00e3o da mem\u00f3ria.<\/li>\n<li>Rastreamento do script que realiza testes. Em caso de falha \u2014 interrup\u00e7\u00e3o repentina ou ciclo infinito de espera \u2014 aqui ser\u00e1 poss\u00edvel ver a raz\u00e3o desse comportamento.<\/li>\n<\/ol>\n<p><\/p>\n<p>Os testes s\u00e3o realizados em duas etapas. Primeiro, o script percorre todas as variedades de testes, escolhendo aleatoriamente a virtualiza\u00e7\u00e3o \u00e0 qual aplicar este teste. Em seguida, um ciclo infinito de testes \u00e9 executado, onde a virtualiza\u00e7\u00e3o e a falha s\u00e3o selecionadas aleatoriamente a cada vez. A conclus\u00e3o repentina do script de teste (painel inferior) ou um ciclo infinito de espera de algo (&gt; 5 minutos de tempo de execu\u00e7\u00e3o de uma opera\u00e7\u00e3o, isso \u00e9 vis\u00edvel no rastreamento) indica que algum dos testes neste cluster falhou.<\/p>\n<p><\/p>\n<p>Cada teste consiste nas seguintes opera\u00e7\u00f5es:<\/p>\n<p><\/p>\n<ol>\n<li>Iniciar fun\u00e7\u00e3o que emula a falha.<\/li>\n<li><strong>Pronto?<\/strong> \u2014 aguardando a recupera\u00e7\u00e3o do cluster (quando todos os servi\u00e7os s\u00e3o restabelecidos).<\/li>\n<li>Mostra o tempo de espera pela recupera\u00e7\u00e3o do cluster (<em>reaction<\/em>).<\/li>\n<li><strong>Consertar<\/strong> \u2014 o cluster est\u00e1 \"sendo consertado\". Ap\u00f3s isso, ele deve retornar ao estado totalmente funcional e preparado para a pr\u00f3xima falha.<\/li>\n<\/ol>\n<p><\/p>\n<p>Aqui est\u00e1 uma lista de testes com uma descri\u00e7\u00e3o do que eles fazem:<\/p>\n<p><\/p>\n<ul>\n<li><strong>ForkBomb<\/strong>: cria &quot;Fora de mem\u00f3ria&quot; usando uma bomba de fork.<\/li>\n<li><strong>OutOfSpace<\/strong>: enche o disco r\u00edgido. No entanto, o teste \u00e9 mais simb\u00f3lico, dado a carga insignificante que \u00e9 gerada durante o teste, em caso de sobrecarga do disco r\u00edgido, geralmente n\u00e3o ocorre falha no PostgreSQL.<\/li>\n<li><strong>Postgres-KILL<\/strong>: mata o PostgreSQL com o comando <code>killall -KILL postgres<\/code>.<\/li>\n<li><strong>Postgres-STOP<\/strong>: suspende o PostgreSQL com o comando <code>killall -STOP postgres<\/code>.<\/li>\n<li><strong>PowerOff<\/strong>: \u201cdesliga\u201d a m\u00e1quina virtual com o comando <code>VBoxManage controlvm &quot;m\u00e1quina virtual&quot; poweroff<\/code>.<\/li>\n<li><strong>Reset<\/strong>: reinicia a m\u00e1quina virtual com o comando <code>VBoxManage controlvm &quot;m\u00e1quina virtual&quot; reset<\/code>.<\/li>\n<li><strong>SBD-STOP<\/strong>: suspende o daemon SBD com o comando <code>killall -STOP sbd<\/code>.<\/li>\n<li><strong>ShutDown<\/strong>: envia para a m\u00e1quina virtual um comando via SSH <code>systemctl poweroff<\/code>, o sistema encerra corretamente.<\/li>\n<li><strong>UnLink<\/strong>: isolamento de rede, comando <code>VBoxManage controlvm &quot;m\u00e1quina virtual&quot; setlinkstate1 off<\/code>.<\/li>\n<\/ul>\n<p><\/p>\n<p>Concluir o teste ou usando o comando padr\u00e3o tmux &quot;kill-window&quot; <strong>Ctrl-b &amp;<\/strong>, ou o comando &quot;detach-client&quot; <strong>Ctrl-b d<\/strong>: nesse caso, o teste \u00e9 encerrado, o tmux \u00e9 fechado e as m\u00e1quinas virtuais s\u00e3o desligadas.<\/p>\n<p><\/p>\n<h1 id=\"vyyavlennye-pri-testirovanii-problemy\">Problemas identificados no teste<\/h1>\n<p><\/p>\n<ul>\n<li>\n<p>No momento <em>o daemon watchdog sbd<\/em> processa a parada dos daemons monitorados, mas n\u00e3o a sua suspens\u00e3o. E, como consequ\u00eancia, falhas que levam \u00e0 suspens\u00e3o de apenas <em>Corosync<\/em> e <em>Pacemaker<\/em>, mas n\u00e3o suspende <em>sbd<\/em>. Para verifica\u00e7\u00e3o <em>Corosync<\/em> j\u00e1 existe <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/ClusterLabs\/sbd\/pull\/83\"><strong>PR#83<\/strong> (no GitHub em <em>sbd<\/em>)<\/a><\/noindex>, aceito na branch <em>master<\/em>. Prometeram (em PR#83) que algo similar tamb\u00e9m ser\u00e1 feito para o Pacemaker, espero que at\u00e9 <em>RedHat 8<\/em> eles consigam. Mas tais \u201cfalhas\u201d s\u00e3o hipot\u00e9ticas, facilmente simuladas artificialmente com, por exemplo, <code>killall -STOP corosync<\/code>, mas nunca ocorrem na vida real.<\/p>\n<p>\n<\/li>\n<li>\n<p>Na <em>Pacemaker<\/em> vers\u00e3o para <em>CentOS 7<\/em> o par\u00e2metro <em>sync_timeout<\/em> u <em>quorum device<\/em>est\u00e1 incorretamente definido, como resultado <noindex><a rel=\"nofollow\" href=\"https:\/\/lists.clusterlabs.org\/pipermail\/users\/2019-August\/026145.html\">com a falha de um n\u00f3 h\u00e1 uma probabilidade de reiniciar o segundo n\u00f3<\/a><\/noindex>, para o qual o mestre deveria ter migrado. Isso foi corrigido aumentando <em>sync_timeout<\/em> u <em>quorum device<\/em> durante a implanta\u00e7\u00e3o (no script <code>setup\/setup1<\/code>). Esta corre\u00e7\u00e3o n\u00e3o foi aceita pelos desenvolvedores <em>Pacemaker<\/em>, em vez disso, prometeram reformular a infraestrutura de tal maneira (num futuro indefinido), que esse tempo limite seria calculado automaticamente.<\/p>\n<p>\n<\/li>\n<li>\n<p>Se, ao configurar o banco de dados, foi especificado que em <code>LC_MESSAGES<\/code> (mensagens de texto) pode ser usado Unicode, por exemplo, <code>ru_RU.UTF-8<\/code>, ao iniciar <em>postgres<\/em> em um ambiente onde o locale n\u00e3o \u00e9 UTF-8, digamos, em um ambiente vazio (aqui <em>pacemaker<\/em>+<em>pgsqlms<\/em>(paf) inicia <em>postgres<\/em>), ent\u00e3o <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/message-id\/13FE0F7C-5140-499C-8C2E-0BE64BC3A48B%40ya.ru\">no log, em vez de letras UTF-8, aparecer\u00e3o sinais de interroga\u00e7\u00e3o<\/a><\/noindex>. Os desenvolvedores do PostgreSQL ainda n\u00e3o conseguiram chegar a um acordo sobre o que fazer neste caso. Isso pode ser contornado, \u00e9 necess\u00e1rio instalar <code>LC_MESSAGES=pt_BR.UTF-8<\/code> ao configurar (criar) uma inst\u00e2ncia de banco de dados.<\/p>\n<p>\n<\/li>\n<li>\n<p>Se o wal_receiver_timeout estiver definido (por padr\u00e3o, \u00e9 60s), ent\u00e3o ao testar o PostgreSQL-STOP no mestre nos clusters tuchanka3 e tuchanka4 <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/message-id\/60590EC6-4062-4F25-A49C-3948ED2A7D47%40ya.ru\">n\u00e3o ocorre reconex\u00e3o da replica\u00e7\u00e3o ao novo mestre<\/a><\/noindex>. A replica\u00e7\u00e3o \u00e9 s\u00edncrona, portanto, n\u00e3o apenas o escravo, mas tamb\u00e9m o novo mestre para, sendo necess\u00e1rio definir wal_receiver_timeout=0 ao configurar o PostgreSQL.<\/p>\n<p>\n<\/li>\n<li>\n<p>Raramente observei a replica\u00e7\u00e3o do PostgreSQL travar no teste ForkBomb (sobrecarga de mem\u00f3ria). <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/message-id\/60590EC6-4062-4F25-A49C-3948ED2A7D47%40ya.ru\">Ap\u00f3s ForkBomb, \u00e0s vezes os escravos podem n\u00e3o se reconectar ao novo mestre<\/a><\/noindex>. Eu s\u00f3 encontrei isso nos clusters tuchanka3 e tuchanka4, onde, devido \u00e0 replica\u00e7\u00e3o ser s\u00edncrona, o mestre travou. O problema se resolvedeu sozinho ap\u00f3s um tempo prolongado (cerca de duas horas). \u00c9 necess\u00e1ria uma investiga\u00e7\u00e3o adicional para corrigir isso. Pelo sintomas, parece um bug anterior, causado por outra raz\u00e3o, mas com consequ\u00eancias semelhantes.<\/p>\n<p>\n<\/li>\n<\/ul>\n<p><\/p>\n<p>A imagem do krogan foi retirada de <noindex><a rel=\"nofollow\" href=\"http:\/\/fav.me\/d8fo42n\">Deviant Art<\/a><\/noindex> com a permiss\u00e3o do autor:<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Modelagem de clusters tolerantes a falhas com PostgreSQL e Pacemaker\" src=\"\/wp-content\/uploads\/2020\/08\/ded1ead387814d97d84d0fb89e025386.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p>Fonte: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/domclick\/blog\/516538\/\">habr.com<\/a> <\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u041d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u043d\u0430\u0437\u0430\u0434 \u043f\u0435\u0440\u0435\u0434\u043e \u043c\u043d\u043e\u0439 \u043f\u043e\u0441\u0442\u0430\u0432\u0438\u043b\u0438 \u0437\u0430\u0434\u0430\u0447\u0443 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043e\u0442\u043a\u0430\u0437\u043e\u0443\u0441\u0442\u043e\u0439\u0447\u0438\u0432\u044b\u0439 \u043a\u043b\u0430\u0441\u0442\u0435\u0440 \u0434\u043b\u044f PostgreSQL, \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0449\u0438\u0439 \u0432 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u0434\u0430\u0442\u0430-\u0446\u0435\u043d\u0442\u0440\u0430\u0445, \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0435\u043d\u043d\u044b\u0445 \u043e\u043f\u0442\u043e\u0432\u043e\u043b\u043e\u043a\u043d\u043e\u043c \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u043e\u0434\u043d\u043e\u0433\u043e \u0433\u043e\u0440\u043e\u0434\u0430, \u0438 \u0441\u043f\u043e\u0441\u043e\u0431\u043d\u044b\u0439 \u0432\u044b\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u043e\u0442\u043a\u0430\u0437 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043e\u0431\u0435\u0441\u0442\u043e\u0447\u0438\u0432\u0430\u043d\u0438\u0435) \u043e\u0434\u043d\u043e\u0433\u043e \u0434\u0430\u0442\u0430-\u0446\u0435\u043d\u0442\u0440\u0430. \u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0441\u043e\u0444\u0442\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u043e\u0442\u043a\u0430\u0437\u043e\u0443\u0441\u0442\u043e\u0439\u0447\u0438\u0432\u043e\u0441\u0442\u044c, \u0432\u044b\u0431\u0440\u0430\u043b Pacemaker, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u044d\u0442\u043e \u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u043e\u0442 RedHat \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043e\u0442\u043a\u0430\u0437\u043e\u0443\u0441\u0442\u043e\u0439\u0447\u0438\u0432\u044b\u0445 \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u043e\u0432. \u041e\u043d\u043e \u0445\u043e\u0440\u043e\u0448\u043e \u0442\u0435\u043c, \u0447\u0442\u043e [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":92571,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-92570","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.3 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u041d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u043d\u0430\u0437\u0430\u0434 \u043f\u0435\u0440\u0435\u0434\u043e \u043c\u043d\u043e\u0439 \u043f\u043e\u0441\u0442\u0430\u0432\u0438\u043b\u0438 \u0437\u0430\u0434\u0430\u0447\u0443 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043e\u0442\u043a\u0430\u0437\u043e\u0443\u0441\u0442\u043e\u0439\u0447\u0438\u0432\u044b\u0439 \u043a\u043b\u0430\u0441\u0442\u0435\u0440 \u0434\u043b\u044f PostgreSQL.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/pt\/blog\/administrirovanie\/modelirovanie-otkazoustojchivyh-klasterov-na-baze-postgresql-i-pacemaker\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.3\" \/>\n\t\t<meta property=\"og:locale\" content=\"pt_PT\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u041c\u043e\u0434\u0435\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043e\u0442\u043a\u0430\u0437\u043e\u0443\u0441\u0442\u043e\u0439\u0447\u0438\u0432\u044b\u0445 \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u043e\u0432 \u043d\u0430 \u0431\u0430\u0437\u0435 PostgreSQL \u0438 Pacemaker | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u041d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u043d\u0430\u0437\u0430\u0434 \u043f\u0435\u0440\u0435\u0434\u043e \u043c\u043d\u043e\u0439 \u043f\u043e\u0441\u0442\u0430\u0432\u0438\u043b\u0438 \u0437\u0430\u0434\u0430\u0447\u0443 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043e\u0442\u043a\u0430\u0437\u043e\u0443\u0441\u0442\u043e\u0439\u0447\u0438\u0432\u044b\u0439 \u043a\u043b\u0430\u0441\u0442\u0435\u0440 \u0434\u043b\u044f PostgreSQL.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/pt\/blog\/administrirovanie\/modelirovanie-otkazoustojchivyh-klasterov-na-baze-postgresql-i-pacemaker\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2020-08-28T17:42:21+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-08-28T17:42:21+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Modelagem de clusters tolerantes a falhas com PostgreSQL e Pacemaker | ProHoster","description":"Introdu\u00e7\u00e3o H\u00e1 algum tempo, foi-me incumbida a tarefa de desenvolver um cluster tolerante a falhas para PostgreSQL.","canonical_url":"https:\/\/prohoster.info\/pt\/blog\/administrirovanie\/modelirovanie-otkazoustojchivyh-klasterov-na-baze-postgresql-i-pacemaker","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"pt_PT","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u041c\u043e\u0434\u0435\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043e\u0442\u043a\u0430\u0437\u043e\u0443\u0441\u0442\u043e\u0439\u0447\u0438\u0432\u044b\u0445 \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u043e\u0432 \u043d\u0430 \u0431\u0430\u0437\u0435 PostgreSQL \u0438 Pacemaker | ProHoster","og:description":"\u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u041d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u043d\u0430\u0437\u0430\u0434 \u043f\u0435\u0440\u0435\u0434\u043e \u043c\u043d\u043e\u0439 \u043f\u043e\u0441\u0442\u0430\u0432\u0438\u043b\u0438 \u0437\u0430\u0434\u0430\u0447\u0443 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043e\u0442\u043a\u0430\u0437\u043e\u0443\u0441\u0442\u043e\u0439\u0447\u0438\u0432\u044b\u0439 \u043a\u043b\u0430\u0441\u0442\u0435\u0440 \u0434\u043b\u044f PostgreSQL.","og:url":"https:\/\/prohoster.info\/pt\/blog\/administrirovanie\/modelirovanie-otkazoustojchivyh-klasterov-na-baze-postgresql-i-pacemaker","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2020-08-28T17:42:21+00:00","article:modified_time":"2020-08-28T17:42:21+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"92570","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":null,"breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 12:06:03","updated":"2022-09-29 15:28:29","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/posts\/92570","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/comments?post=92570"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/posts\/92570\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/media\/92571"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/media?parent=92570"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/categories?post=92570"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/tags?post=92570"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}