MariaDB
 sql >> Base de Dados >  >> RDS >> MariaDB

Balanceamento de carga MariaDB MaxScale no Docker:implantação:parte um


MariaDB MaxScale é um proxy de banco de dados plug-in avançado para servidores de banco de dados MariaDB. Ele fica entre os aplicativos cliente e os servidores de banco de dados, roteando as consultas do cliente e as respostas do servidor. O MaxScale também monitora os servidores, de modo que notará rapidamente quaisquer alterações no status do servidor ou na topologia de replicação. Isso torna o MaxScale uma escolha natural para controlar o failover e recursos semelhantes.

Nesta série de blog de duas partes, vamos dar um passo a passo completo sobre como executar o MariaDB MaxScale no Docker. Esta parte abrange a implantação como um contêiner Docker autônomo e o clustering MaxScale por meio do Docker Swarm para alta disponibilidade.

MariaDB MaxScale no Docker


Há várias imagens MariaDB Docker disponíveis no Docker Hub. Neste blog, usaremos a imagem oficial mantida e publicada pelo MariaDB chamada "mariadb/maxscale" (tag:mais recente). A imagem tem cerca de 71 MB de tamanho. No momento em que escrevo, a imagem está pré-instalada com o MaxScale 2.3.4 como parte de seus pacotes necessários.

Geralmente, as etapas a seguir são necessárias para executar um MaxScale com esta imagem no ambiente do contêiner:
  1. Uma replicação MariaDB (master-slave ou master-master) em execução/Galera Cluster ou NDB Cluster
  2. Crie e conceda um usuário de banco de dados dedicado ao monitoramento MaxScale
  3. Prepare o arquivo de configuração MaxScale
  4. Mapeie o arquivo de configuração no contêiner ou carregue no Kubernetes ConfigMap ou Docker Swarm Configs
  5. Inicie o contêiner/pod/service/replicaset

Observe que o MaxScale é um produto do MariaDB, o que significa que é adaptado para o servidor MariaDB. A maioria dos recursos ainda são compatíveis com o MySQL, exceto algumas partes, como por exemplo, manuseio de GTID, configuração do Galera Cluster e arquivos de dados internos. A versão que vamos usar é a 2.3.4, que é lançada sob Business Source License (BSL). Ele permite que todo o código seja aberto e o uso em TRÊS servidores seja gratuito. Quando o uso ultrapassa três servidores de back-end, a empresa que o utiliza deve pagar por uma assinatura comercial. Após um período de tempo específico (2 anos no caso do MaxScale), a versão passa para GPL e todo o uso é gratuito.

Só para ficar claro, como este é um ambiente de teste, podemos ter mais de 2 nós. Conforme declarado na página de perguntas frequentes do MariaDB BSL:

P:Posso usar produtos MariaDB licenciados sob BSL em ambiente de teste e desenvolvimento?
R:Sim, em ambiente de teste e desenvolvimento de não produção, você pode usar produtos licenciados sob BSL sem precisar de uma assinatura do MariaDB


Neste passo a passo, já temos uma Replicação MariaDB de três nós implantada usando o ClusterControl. O diagrama a seguir ilustra a configuração que vamos implantar:

Nossa arquitetura de sistema consiste em:
  • mariadb1 - 192.168.0.91 (mestre)
  • mariadb2 - 192.168.0.92 (escravo)
  • mariadb3 - 192.168.0.93 (escravo)
  • docker1 - 192.168.0.200 (host do Docker para contêineres - maxscale, aplicativo)

Preparando o usuário MaxScale


Primeiramente, crie um usuário de banco de dados MySQL para MaxScale e permita todos os hosts na rede 192.168.0.0/24:
MariaDB> CREATE USER 'maxscale'@'192.168.0.%' IDENTIFIED BY 'my_s3cret';

Em seguida, conceda os privilégios necessários. Se você deseja apenas monitorar os servidores de back-end com balanceamento de carga, as seguintes concessões seriam suficientes:
MariaDB> GRANT SHOW DATABASES ON *.* TO 'maxscale'@'192.168.0.%';
MariaDB> GRANT SELECT ON `mysql`.* TO 'maxscale'@'192.168.0.%';

No entanto, o MaxScale pode fazer muito mais do que encaminhar consultas. Ele tem a capacidade de realizar failover e switchover, por exemplo, promovendo um escravo para um novo mestre. Isso requer privilégios SUPER e REPLICATION CLIENT. Se você quiser usar esse recurso, atribua TODOS OS PRIVILÉGIOS ao usuário:
mysql> GRANT ALL PRIVILEGES ON *.* TO [email protected]'192.168.0.%';

Isso é tudo para a parte do usuário.

Preparando o arquivo de configuração MaxScale


A imagem requer que um arquivo de configuração de trabalho seja mapeado no contêiner antes de ser iniciado. O arquivo de configuração mínimo fornecido no contêiner não nos ajudará a construir o proxy reverso que queremos. Portanto, o arquivo de configuração deve ser preparado com antecedência.

A lista a seguir pode nos ajudar a coletar as informações básicas necessárias para construir nosso arquivo de configuração:
  • Tipo de cluster - MaxScale oferece suporte à replicação MariaDB (master-slave, master-master), Galera Cluster, Amazon Aurora, MariaDB ColumnStore e NDB Cluster (também conhecido como MySQL Cluster).
  • Endereço IP de back-end e/ou nome de host - Endereço IP ou nome de host acessível para todos os servidores de back-end.
  • Algoritmo de roteamento - MaxScale oferece suporte a dois tipos de roteamento de consulta:divisão de leitura e gravação e balanceamento de carga em round-robin.
  • Porta para escutar por MaxScale - Por padrão, MaxScale usa a porta 4006 para conexões round-robin e 4008 para conexões divididas de leitura/gravação. Você pode usar o soquete UNIX se quiser.

No diretório atual, crie um arquivo de texto chamado maxscale.cnf para que possamos mapeá-lo no contêiner ao iniciar. Cole as seguintes linhas no arquivo:
########################
## Server list
########################

[mariadb1]
type            = server
address         = 192.168.0.91
port            = 3306
protocol        = MariaDBBackend
serv_weight     = 1

[mariadb2]
type            = server
address         = 192.168.0.92
port            = 3306
protocol        = MariaDBBackend
serv_weight     = 1

[mariadb3]
type            = server
address         = 192.168.0.93
port            = 3306
protocol        = MariaDBBackend
serv_weight     = 1

#########################
## MaxScale configuration
#########################

[maxscale]
threads                 = auto
log_augmentation        = 1
ms_timestamp            = 1
syslog                  = 1

#########################
# Monitor for the servers
#########################

[monitor]
type                    = monitor
module                  = mariadbmon
servers                 = mariadb1,mariadb2,mariadb3
user                    = maxscale
password                = my_s3cret
auto_failover           = true
auto_rejoin             = true
enforce_read_only_slaves = 1

#########################
## Service definitions for read/write splitting and read-only services.
#########################

[rw-service]
type            = service
router          = readwritesplit
servers         = mariadb1,mariadb2,mariadb3
user            = maxscale
password        = my_s3cret
max_slave_connections           = 100%
max_sescmd_history              = 1500
causal_reads                    = true
causal_reads_timeout            = 10
transaction_replay              = true
transaction_replay_max_size     = 1Mi
delayed_retry                   = true
master_reconnection             = true
master_failure_mode             = fail_on_write
max_slave_replication_lag       = 3

[rr-service]
type            = service
router          = readconnroute
servers         = mariadb1,mariadb2,mariadb3
router_options  = slave
user            = maxscale
password        = my_s3cret

##########################
## Listener definitions for the service
## Listeners represent the ports the service will listen on.
##########################

[rw-listener]
type            = listener
service         = rw-service
protocol        = MariaDBClient
port            = 4008

[ro-listener]
type            = listener
service         = rr-service
protocol        = MariaDBClient
port            = 4006

Um pouco de explicações para cada seção:
  • Lista de servidores - Os servidores de back-end. Defina cada servidor MariaDB deste cluster em sua própria estrofe. O nome da estrofe será usado quando especificarmos a definição de serviço mais abaixo. O tipo de componente deve ser "servidor".
  • Configuração MaxScale - Defina todas as configurações relacionadas a MaxScale.
  • Módulo de monitoramento - Como o MaxScale deve monitorar os servidores de back-end. O tipo de componente deve ser "monitor" seguido por qualquer um dos módulos de monitoramento. Para obter a lista de monitores compatíveis, consulte Monitores MaxScale 2.3.
  • Serviço - Para onde encaminhar a consulta. O tipo de componente deve ser "serviço". Para obter a lista de roteadores compatíveis, consulte Roteadores MaxScale 2.3.
  • Listener - Como o MaxScale deve ouvir as conexões de entrada. Pode ser um arquivo de porta ou soquete. O tipo de componente deve ser "ouvinte". Geralmente, os ouvintes estão vinculados aos serviços.

Então, basicamente, gostaríamos que o MaxScale escutasse em duas portas, 4006 e 4008. A porta 4006 é especificamente para conexão round-robin, adequada para cargas de trabalho somente leitura para nossa Replicação MariaDB, enquanto a porta 4008 é especificamente para cargas de trabalho críticas de leitura e gravação. Também queremos usar MaxScale para executar ações em nossa replicação em caso de failover, switchover ou rejunção de escravos, portanto, usamos o módulo monitor chamado "mariadbmon".

Executando o contêiner


Agora estamos prontos para executar nosso contêiner MaxScale autônomo. Mapeie o arquivo de configuração com -v e certifique-se de publicar ambas as portas do listener 4006 e 4008. Opcionalmente, você pode habilitar a interface MaxScale REST API na porta 8989:
$ docker run -d \
--name maxscale \
--restart always \
-p 4006:4006 \
-p 4008:4008 \
-p 8989:8989 \
-v $PWD/maxscale.cnf:/etc/maxscale.cnf \
mariadb/maxscale

Verifique com:
$ docker logs -f maxscale
...
2019-06-14 07:15:41.060   notice : (main): Started REST API on [127.0.0.1]:8989
2019-06-14 07:15:41.060   notice : (main): MaxScale started with 8 worker threads, each with a stack size of 8388608 bytes.

Certifique-se de não ver nenhum erro ao examinar os logs acima. Verifique se os processos do docker-proxy estão escutando nas portas publicadas - 4006, 4008 e 8989:
$ netstat -tulpn | grep docker-proxy
tcp6       0      0 :::8989                 :::*                    LISTEN      4064/docker-proxy
tcp6       0      0 :::4006                 :::*                    LISTEN      4092/docker-proxy
tcp6       0      0 :::4008                 :::*                    LISTEN      4078/docker-proxy

Neste ponto, nosso MaxScale está em execução e é capaz de processar consultas.

MaxCtrl


MaxCtrl é um cliente administrativo de linha de comando para MaxScale que usa a API REST MaxScale para comunicação. Destina-se a ser o software de substituição para o cliente de linha de comando MaxAdmin legado.

Para entrar no console MaxCtrl, execute o comando "maxctrl" dentro do container:
$ docker exec -it maxscale maxctrl
 maxctrl: list servers
┌──────────┬──────────────┬──────┬─────────────┬─────────────────┬─────────────┐
│ Server   │ Address      │ Port │ Connections │ State           │ GTID        │
├──────────┼──────────────┼──────┼─────────────┼─────────────────┼─────────────┤
│ mariadb1 │ 192.168.0.91 │ 3306 │ 0           │ Master, Running │ 0-5001-1012 │
├──────────┼──────────────┼──────┼─────────────┼─────────────────┼─────────────┤
│ mariadb2 │ 192.168.0.92 │ 3306 │ 0           │ Slave, Running  │ 0-5001-1012 │
├──────────┼──────────────┼──────┼─────────────┼─────────────────┼─────────────┤
│ mariadb3 │ 192.168.0.93 │ 3306 │ 0           │ Slave, Running  │ 0-5001-1012 │
└──────────┴──────────────┴──────┴─────────────┴─────────────────┴─────────────┘

Para verificar se está tudo bem, basta executar os seguintes comandos:
maxctrl: list servers
maxctrl: list services
maxctrl: list filters
maxctrl: list sessions

Para obter mais informações sobre cada componente, prefixe com o comando "show", por exemplo:
maxctrl: show servers
┌──────────────────┬──────────────────────────────────────────┐
│ Server           │ mariadb3                                 │
├──────────────────┼──────────────────────────────────────────┤
│ Address          │ 192.168.0.93                             │
├──────────────────┼──────────────────────────────────────────┤
│ Port             │ 3306                                     │
├──────────────────┼──────────────────────────────────────────┤
│ State            │ Slave, Running                           │
├──────────────────┼──────────────────────────────────────────┤
│ Last Event       │ new_slave                                │
├──────────────────┼──────────────────────────────────────────┤
│ Triggered At     │ Mon, 17 Jun 2019 08:57:59 GMT            │
├──────────────────┼──────────────────────────────────────────┤
│ Services         │ rw-service                               │
│                  │ rr-service                               │
├──────────────────┼──────────────────────────────────────────┤
│ Monitors         │ monitor                                  │
├──────────────────┼──────────────────────────────────────────┤
│ Master ID        │ 5001                                     │
├──────────────────┼──────────────────────────────────────────┤
│ Node ID          │ 5003                                     │
├──────────────────┼──────────────────────────────────────────┤
│ Slave Server IDs │                                          │
├──────────────────┼──────────────────────────────────────────┤
│ Statistics       │ {                                        │
│                  │     "connections": 0,                    │
│                  │     "total_connections": 0,              │
│                  │     "persistent_connections": 0,         │
│                  │     "active_operations": 0,              │
│                  │     "routed_packets": 0,                 │
│                  │     "adaptive_avg_select_time": "0ns"    │
│                  │ }                                        │
├──────────────────┼──────────────────────────────────────────┤
│ Parameters       │ {                                        │
│                  │     "address": "192.168.0.93",           │
│                  │     "protocol": "MariaDBBackend",        │
│                  │     "port": 3306,                        │
│                  │     "extra_port": 0,                     │
│                  │     "authenticator": null,               │
│                  │     "monitoruser": null,                 │
│                  │     "monitorpw": null,                   │
│                  │     "persistpoolmax": 0,                 │
│                  │     "persistmaxtime": 0,                 │
│                  │     "proxy_protocol": false,             │
│                  │     "ssl": "false",                      │
│                  │     "ssl_cert": null,                    │
│                  │     "ssl_key": null,                     │
│                  │     "ssl_ca_cert": null,                 │
│                  │     "ssl_version": "MAX",                │
│                  │     "ssl_cert_verify_depth": 9,          │
│                  │     "ssl_verify_peer_certificate": true, │
│                  │     "disk_space_threshold": null,        │
│                  │     "type": "server",                    │
│                  │     "serv_weight": "1"                   │
│                  │ }                                        │
└──────────────────┴──────────────────────────────────────────┘

Conectando ao banco de dados


O usuário do banco de dados do aplicativo deve ser concedido com o host MaxScale, pois do ponto de vista do servidor MariaDB, ele só pode ver o host MaxScale. Considere o seguinte exemplo sem MaxScale na imagem:
  • Nome do banco de dados:meuaplicativo
  • Usuário:myapp_user
  • Host:192.168.0.133 (servidor de aplicativos)

Para permitir que o usuário acesse o banco de dados dentro do servidor MariaDB, deve-se executar a seguinte instrução:
MariaDB> CREATE USER 'myapp_user'@'192.168.0.133' IDENTIFIED BY 'mypassword';
MariaDB> GRANT ALL PRIVILEGES ON myapp.* to 'myapp_user'@'192.168.0.133';

Com MaxScale na imagem, é preciso executar a seguinte instrução (substitua o endereço IP do servidor de aplicativos pelo endereço IP MaxScale, 192.168.0.200):
MariaDB> CREATE USER 'myapp_user'@'192.168.0.200' IDENTIFIED BY 'mypassword';
MariaDB> GRANT ALL PRIVILEGES ON myapp.* to 'myapp_user'@'192.168.0.200';

A partir do aplicativo, existem duas portas que você pode usar para se conectar ao banco de dados:
  • 4006 - Listener round-robin, adequado para cargas de trabalho somente leitura.
  • 4008 - Ouvinte dividido de leitura e gravação, adequado para cargas de trabalho de gravação.

Se seu aplicativo tiver permissão para especificar apenas uma porta MySQL (por exemplo, Wordpress, Joomla, etc), escolha a porta RW 4008. Esta é a conexão de endpoint mais segura, independentemente do tipo de cluster. No entanto, se seu aplicativo pode lidar com conexões para várias portas MySQL, você pode enviar as leituras para o ouvinte round-robin. Este ouvinte tem menos sobrecarga e muito mais rápido se comparado ao ouvinte dividido de leitura-gravação.

Para nossa configuração de replicação MariaDB, conecte-se a um desses endpoints como combinação de host/porta do banco de dados:
  • 192.168.0.200 porta 4008 - MaxScale - leitura/gravação ou somente gravação
  • 192.168.0.200 porta 4006 - MaxScale - somente leitura balanceada
  • 192.168.0.91 porta 3306 - Servidor MariaDB (mestre) - leitura/gravação
  • 192.168.0.92 porta 3306 - Servidor MariaDB (escravo) - somente leitura
  • 192.168.0.93 porta 3306 - Servidor MariaDB (escravo) - somente leitura

Observação para o tipo de cluster multimestre, como Galera Cluster e NDB Cluster, a porta 4006 pode ser usada como conexões balanceadas de gravação múltipla. Com MaxScale você tem muitas opções para escolher ao se conectar ao banco de dados, com cada uma delas oferecendo seu próprio conjunto de vantagens.

Agrupamento MaxScale com Docker Swarm


Com o Docker Swarm, podemos criar um grupo de instâncias MaxScale via serviço Swarm com mais de uma réplica junto com Swarm Configs. Primeiramente, importe o arquivo de configuração para o Swarm:
$ cat maxscale.conf | docker config create maxscale_config -

Verifique com:
$ docker config inspect --pretty maxscale_config

Em seguida, conceda ao usuário do banco de dados MaxScale para se conectar de qualquer host Swarm na rede:
MariaDB> CREATE USER 'maxscale'@'192.168.0.%' IDENTIFIED BY 'my_s3cret';
MariaDB> GRANT ALL PRIVILEGES ON *.* TO [email protected]'192.168.0.%';

Ao iniciar o serviço Swarm para MaxScale, podemos criar vários mapeamentos de contêineres (chamados de réplicas) para o mesmo arquivo de configuração abaixo:
$ docker service create \
--name maxscale-cluster  \
--replicas=3 \
--publish published=4008,target=4008 \
--publish published=4006,target=4006 \
--config source=maxscale_config,target=/etc/maxscale.cnf \
mariadb/maxscale

O acima criará três contêineres MaxScale espalhados pelos nós do Swarm. Verifique com:
$ docker service ls
ID                  NAME                MODE                REPLICAS            IMAGE                     PORTS
yj6u2xcdj7lo        maxscale-cluster    replicated          3/3                 mariadb/maxscale:latest   *:4006->4006/tcp, *:4008->4008/tcp

Se os aplicativos estiverem sendo executados na rede Swarm, você pode simplesmente usar o nome do serviço "maxscale-cluster" como o host do banco de dados para seus aplicativos. Externamente, você pode se conectar a qualquer host do Docker nas portas publicadas e a rede Swarm roteará e balanceará as conexões para os contêineres corretos de maneira round-robin. Neste ponto, nossa arquitetura pode ser ilustrada como abaixo:

Na segunda parte, veremos casos de uso avançados do MaxScale no Docker, como controle de serviço, gerenciamento de configuração, processamento de consultas, segurança e reconciliação de cluster.