MariaDB Galera Cluster c/ HAProxy e Pacemaker
Autor: Pedro Viana | Publicado: 2015-10-22T10:24:00-02:00






Uma vez iniciei uma pesquisa sobre MariaDB Galera cluster, ideia por trás dessa missão era substituir banco de dados MySQL que tinham seus dados replicados através de DRBD. Após reunir muito material sobre o assunto, criei um checklist com um passo a passo detalhado de como implementar. 



MariaDB Galera cluster nada mais é do que um conjunto de bancos de dados MariaDB funcionando em modo ativo-ativo, ou seja, você pode acessar e até gravar em sua base de dados de qualquer um deles, simultaneamente se for preciso. Está disponível em Linux e suporta apenas os mecanismos de armazenamento XtraDB / InnoDB (existe suporte experimental para MyISAM).



MariaDB é construído por alguns dos autores originais do MySQL, com a ajuda da grande comunidade de desenvolvedores de software livre. É mantido atualizado com a última versão do MySQL, pelo que entendi, vai funcionar exatamente como MySQL. Todos os comandos, interfaces, bibliotecas e APIs que existem no MySQL também existem no MariaDB. Li rumores de que a aquisição do MySQL pela Oracle não agradou a comunidade e por isso o MariaDB ganhou força.



Pois bem, nesse post ainda vou somar o MariaDB Galera cluster com outros dois gigantes, Pacemaker e HAProxy. Isso se fez necessário por que a aplicação final não é capaz de fazer load balance entre os bancos. Já que eles vão funcionar todos como ativo, ou seja, caso aponte a aplicação para apenas um dos ips vai funcionar. Então eu preciso é de um VIP(virtual ip) e de um balanceador de carga. ;)



Ambos são muito simples de configurar, claro que eu vou focar nas configurações necessárias apenas para o cluster funcionar, mas recomendo uma pesquisa paralela sobre HAProxy e Pacemaker, ambos são excelentes e podem fazer muito mais do que vou mostrar nesse post.



Nosso ambiente será composto por 3 maquinas, todas vão ter pacemaker e haproxy e todas também vão fazer parte do cluster de banco de dados. A ideia por trás disso é simples. Todas as maquinas podem ser titulares a qualquer momento, inicialmente vou eleger uma, mas em caso de falha qualquer outra poderá assumir esse papel. Veja o desenho abaixo, tenho certeza que vai ficar mais facil de entender o que vai ser feito.











Estou utilizando apenas 3 maquinas, mas nem de longe isso é limite do 
cluster, muito menos do loadbalancer. Eu que sou preguiçoso e não 
utilizei nada para provisionar essas maquinas então três está bom. :) de
 qualquer forma, desconheço qualquer limite para cluster ou qualquer 
outra ferramenta envolvida nesse post.

Para instalar os pacotes necessários precisamos configurar um repositório e
configurar sua chave. 

$ sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv
0xcbcb082a1bb943db&nbsp;



$ sudo add-apt-repository 'deb
http://mirror.edatel.net.co/mariadb//repo/10.0/ubuntu trusty main'




$ sudo apt-get update








Instale o MariaDB Galera Server:


$ sudo apt-get install mariadb-galera-server





Obs: Caso opte por uma senha diferente de rootroot, atenção redobrada aos comandos desse post.





Instale também o PaceMaker:


$ sudo apt-get install pacemaker



E também instale o HaProxy:


$ sudo apt-get install haproxy



Crie o arquivo cluster.cnf dentro do diretorio /etc/mysql/conf.d/. Sim vamos editar uma subpasta do mysql, diretório está correto.&nbsp; 


[mysqld]
query_cache_size=0
query_cache_type=0
binlog_format=ROW
default-storage-engine=innodb
innodb_autoinc_lock_mode=2
bind-address=0.0.0.0
wsrep_provider=/usr/lib/galera/libgalera_smm.so
wsrep_cluster_name="cluster_mpdocs"
wsrep_cluster_address="gcomm://192.168.10.61,192.168.10.43,192.168.10.44"
wsrep_sst_method=rsync
wsrep_node_address=" "
wsrep_node_name=" "


Tão importante quanto editar o arquivo cluster.cnf conforme indicado acima, é

garantir que o debian.cnf, também localizado dentro do subdiretorio mysql em

/etc/, esteja idêntico em todos os servidores.



Nosso objetivo é configurar vários servidores então escolha um e utilize como

base. Apos escolher, copie o arquivo em questão para todos os demais servidores.


$ scp /etc/mysql/conf.d/cluster.cnf &lt;ip_de_destino&gt;:/etc/mysql/conf.d/cluster.cnf

$ scp /etc/mysql/debian.cnf &lt;ip_de_destino&gt;:/etc/mysql/debian.cnf


Certifique que todos os bancos MariaDB estejam parados.


$ sudo /etc/init.d/mysql stop




Obs: Executar esse comando em todos os 3 servidores.





Verifique se o arquivo hosts do servidor está correto. Abaixo segue um exemplo

do utilizado no servidor em questão.


$ sudo vim /etc/hosts&nbsp; 

127.0.0.1 localhost
127.0.0.1 Galera01
127.0.1.1 Galera01
# The following lines are desirable for IPv6 capable hosts
::1&nbsp;&nbsp;&nbsp;&nbsp; localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters


Vamos criar o primeiro cluster? Execute apenas em um dos servidores o comando:


$ sudo service mysql start --wsrep-new-cluster


Nos demais servidores inicie o banco de dados:


$ sudo /etc/init.d/mysql start




Obs: Atenção com o uso do sudo antes do comando de start no mysql e também nos demais executados até aqui, caso não utilize você poderá ter respostas

diferentes das que estão descritas nesse post.



Adimitindo que todos os servidores subiram o banco de dados corretamente, então

o cluster está operacional! Execute de qualquer um os comandos:


$ mysql -u root -prootroot


Em seguida de privilegio ao usuario root para acesso externo.


&gt; GRANT ALL ON *.* TO root@'%' IDENTIFIED BY 'rootroot';
&gt; GRANT ALL ON *.* TO root@'localhost' IDENTIFIED BY 'rootroot';


Caso queira verificar se todos os servidores configurados estão fazendo parte do

cluster, logue no mysql e digite:


&gt; SHOW STATUS LIKE 'wsrep_cluster_size%';


Resultado vai ser uma tabela onde a coluna VALUE deve contar o numero

correspondente a quantidade de servidores adicionados ao cluster. 



Parar o checklist aqui, significa que você tem um cluster de banco de dados funcionando a todo vapor! O que vamos fazer a seguir é configurar um loadbalancer e um vip.




Configuração Corosync / PaceMaker:



Primerio passo para configurarmos nosso cluster é criar a authkey necessária

para funcionamento do serviço corosync.


$ sudo corosync-keygen


Processo de gerar a chave é um pouco demorado. Quando terminar copie essa chave para os demais servidores. No ambiente de testes o output do comando corosync-keygen foi:


Corosync Cluster Engine Authentication key generator.
Gathering 1024 bits for key from /dev/random.
Press keys on your keyboard to generate entropy.
Press keys on your keyboard to generate entropy (bits = 872).
Press keys on your keyboard to generate entropy (bits = 920).
Press keys on your keyboard to generate entropy (bits = 968).
Press keys on your keyboard to generate entropy (bits = 1016).


Para copiar a chave para os demais servidores, você pode utilizar o comando scp.


$ scp /etc/corosync/authkey dev@NOME_DO_OUTRO_SERVIDOR:


Apos efeutar a copia, vá até o outro servidor e copie o arquivo authkey do home

do usuario dev para o diretório /etc/corosync, conforme indicação abaixo.


$ sudo cp -a authkey /etc/corosync/authkey


Logo após a instalação, por padrão o serviço do corosync não inicia como os

demais serviços apenas com o parametro start. Necessario alterar um arquivo para

que isso aconteça.


$ sudo vim /etc/default/corosync


Assim que abrir o arquivo acima, vai reparar que o parametro START está setado

para NO. Troque para YES, salve e feche o arquivo.



Atenção, ainda não inicie o serviço do corosync, precisamos configurar o arquivo

.conf correspondente.



Indique o endereço de rede onde o cluster vai operar no campo bindnetaddr do

arquivo corosync.conf. Não alterei nenhum outro campo do arquivo .conf original.


$ vim /etc/corosync/corosync.conf 

totem {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; version: 2
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; token: 3000 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; token_retransmits_before_loss_const: 10
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; join: 60
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; consensus: 3600
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; vsftype: none
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; max_messages: 20
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; clear_node_high_bit: yes
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; secauth: off
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; threads: 0
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rrp_mode: none
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; interface {
} }
amf {
ringnumber: 0
bindnetaddr: 192.168.10.0&nbsp; #Endereço de rede
mcastaddr: 226.94.1.1
mcastport: 5405
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mode: disabled
}
quorum {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; provider: corosync_votequorum
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; expected_votes: 1
}
aisexec {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; user:&nbsp;&nbsp; root
group: root
} logging {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fileline: off
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; to_stderr: yes
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; to_logfile: no
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; to_syslog: yes
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; syslog_facility: daemon
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; debug: off
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; timestamp: on
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; logger_subsys {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; subsys: AMF
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; debug: off
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; tags: enter|leave|trace1|trace2|trace3|trace4|trace6
} } 


Inicie os serviços do Corosync e também do Pacemaker.


$ sudo /etc/init.d/corosync start

$ sudo /etc/init.d/pacemaker start 


Para verificar quantos servidores compoem o cluster utilize o parametro status

do comando crm.


$ sudo crm status




Atenção: Valido compreender dois recursos do cluster antes de prosseguirmos.

Em ambos CIB(Cluster Information Base) desabilitei o stonith. Este recurso força shutdown do servidor caso julgue necessário, justificativa é garantir integridade dos dados. Durante a pesquisa achei relatos que não funciona corretamente. Adiante como pode perceber, opto por desligar o recurso.



No-quorum-policy=”ignore” esta linha indica ao cluster que ele vai funcionar mesmo que não tenha maioria de quorum. Exemplo: Imagine que você possui dois servidores e um deles apresenta uma falha. Nesta condição o cluster será automaticamente desligado por falta de quorum. Para isso não acontecer, digite esta linha na criação do CIB.



Entendido? Vamos criar o VIP e também vamos integrar o HAProxy ao Pacemaker.

Torne-se root para facilitar o processo, para isso você pode usar o comando

sudo -i. Para deslogar use ctrl +d 


$ sudo -i
# crm
# cib new conf-failover
# configure
# primitive failover-ip ocf:heartbeat:IPaddr2 params ip=192.168.10.62 cidr_netmask=24
# property no-quorum-policy="ignore"
# property stonith-enabled=false
# end
# cib commit conf-failover
# quit


Antes de iniciar esse novo passo, teste o ip virtual que você acabou de fazer.

Utilize ping, tente acessar o banco de dados. Somente depois inicie o

procedimento de integrar o HAProxy ao Pacemaker.


# crm
# cib new conf-haproxy
# configure
# property stonith-enabled=false
# property no-quorum-policy=ignore
# primitive haproxy lsb:haproxy op monitor interval="1s"
# colocation haproxy-with-failover-ip inf: haproxy failover-ip
# order haproxy-after-failover-ip mandatory: failover-ip haproxy
# end
# cib use live
# cib commit conf-haproxy
# quit




Configuração HAProxy:

Antes de iniciar as configurações do HAProxy vamos configurar o log, sempre util

para debug. Precisamos acrescentar algumas informações no /etc/rsyslog.conf


$ sudo vim /etc/rsyslog.conf


Acrescente no final do arquivo:


local0.* /var/log/haproxy.log
local1.* /var/log/haproxy.log


Edite o arquivo haproxy.cnf localizado em: /etc/haproxy/haproxy.cnf conforme

indicação abaixo:


$ vim /etc/haproxy/haproxy.cnf

global
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; log /dev/log
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; log /dev/log
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; user haproxy
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; group haproxy
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; daemon
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; local0
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; local1 notice
defaults
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; log global
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; timeout connect&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10s
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; timeout client&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1m
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; timeout server&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1m
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; listen galera-cluster VIP_Address:PORTA
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mode tcp
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; balance roundrobin
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; server Galera01 192.168.10.61:3306 check
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; server Galera02 192.168.10.42:3306 check
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; server Galera03 192.168.10.44:3306 check 


Vamos testar o HAProxy? Utilizei um FOR para conectar 60 vezes seguidas no

endereço de ip VIP e exibir o hostname cadastrado no banco de dados.



Obs: Você só vai ter sucesso ao iniciar o serviço, no servidor que for titular do cluster!!! 



Digite o comando abaixo no terminal de alguma maquina que tenha acesso ao

cluster.


$ for i in `seq 1 60`; do mysql -h X.X.X.X -u root -prootroot -PPORTA -e "select @@wsrep_node_name;"; sleep 1; done




Tão importante quanto construir um checklist é documentar as derrubadas. Nesse caso foram muitas então não pude deixar de anotar todas aqui.





Troubleshooting:



1- Por algum fator totalmente fora do esperado você parou todos os bancos que

compoem o MariaDB Galera Cluster. Pior, quando você tenta subir o serviço através

do comando: /etc/init.d/mysql start não sobe? Então execute:


$ sudo /etc/init.d/mysql start –wsrep_cluster_address="gcomm://"




2- Verificar nome do servidor que está rodando o mysql, logue no mysql(-uroot

-prootroot) e digite:


$ select @@wsrep_node_name;




3- Verifique quais servidores estão online e quais estão offline no cluster:


$ sudo crm_mon --group-by-node –inactive




4- Deletar Resource do Pacemaker. Primeiro passo é stopar o recurso que deseja

deletar, depois efetivamente deletar.


$ sudo -i
# crm
# resource
# stop XXXXX
# end
# configure
# delete XXXX
# quit


5- Migrar recurso para outro membro do cluster. Sintaxe do comando é: migrate

NOME_DO_RECURSO NOME_DO_NÓ_DESTINO


$ sudo -i
# crm
# resource
# migrate failover-ip Galera02
# quit




6- É possível usar broadcast ao inves de multicast para comunicação entre os nós

do corosync. Faça a alteração no /etc/corosync/corosync.conf:


# mcastaddr: 226.94.1.1
broadcast: yes