O MariaDB oferece recursos integrados de fragmentação de vários hosts com o mecanismo de armazenamento Spider. Spider suporta particionamento e transações XA e permite que tabelas remotas de diferentes instâncias MariaDB sejam tratadas como se estivessem na mesma instância. A tabela remota pode ser de qualquer mecanismo de armazenamento. A vinculação de tabelas é feita pelo estabelecimento da conexão de um servidor MariaDB local a um servidor MariaDB remoto, e o link é compartilhado para todas as tabelas que fazem parte da mesma transação.
Nesta postagem do blog, vamos orientá-lo na implantação de um cluster de dois shards MariaDB usando o ClusterControl. Vamos implantar alguns servidores MariaDB (para redundância e disponibilidade) para hospedar uma tabela particionada com base em um intervalo de uma chave de fragmentação selecionada. A chave de fragmentação escolhida é basicamente uma coluna que armazena valores com limite inferior e superior, como neste caso, valores inteiros entre 0 e 1.000.000, tornando-a a melhor chave candidata para balancear a distribuição de dados entre dois fragmentos. Portanto, vamos dividir os intervalos em duas partições:
-
0 - 499999:fragmento 1
-
500000 - 1000000:fragmento 2
O diagrama a seguir ilustra nossa arquitetura de alto nível do que vamos implantar:
Algumas explicações do diagrama:
-
mariadb-gw-1:instância MariaDB que executa o mecanismo de armazenamento Spider, atua como um roteador de fragmento. Damos um nome a este host como MariaDB Gateway 1 e este será o servidor MariaDB primário (ativo) para alcançar os shards. O aplicativo se conectará a este host como uma conexão MariaDB padrão. Este nó se conecta aos shards via HAProxy escutando nas portas 127.0.0.1 3307 (shard1) e 3308 (shard2).
-
mariadb-gw-2:instância MariaDB que executa o mecanismo de armazenamento Spider, atua como um roteador de fragmento. Damos um nome a este host como MariaDB Gateway 2 e este será o servidor MariaDB secundário (passivo) para alcançar os shards. Ele terá a mesma configuração que mariadb-gw-1. O aplicativo se conectará a este host somente se o MariaDB primário estiver inativo. Este nó se conecta aos shards via HAProxy escutando nas portas 127.0.0.1 3307 (shard1) e 3308 (shard2).
-
mariadb-shard-1a:MariaDB master que serve como o nó de dados primário para a primeira partição. Os servidores de gateway MariaDB devem gravar apenas no mestre do shard.
-
mariadb-shard-1b:réplica MariaDB que serve como nó de dados secundário para a primeira partição. Ele deve assumir a função de mestre caso o mestre do shard fique inativo (o failover automático é gerenciado pelo ClusterControl).
-
mariadb-shard-2a:MariaDB master que serve como nó de dados primário para a segunda partição. Os servidores de gateway MariaDB gravam apenas no mestre do shard.
-
mariadb-shard-2b:réplica MariaDB que serve como nó de dados secundário para a segunda partição. Ele deve assumir a função de mestre caso o mestre do shard fique inativo (o failover automático é gerenciado pelo ClusterControl).
-
ClusterControl:Uma ferramenta centralizada de implantação, gerenciamento e monitoramento para nossos fragmentos/clusters MariaDB.
Implantando clusters de banco de dados usando ClusterControl
ClusterControl é uma ferramenta de automação para gerenciar o ciclo de vida do seu sistema de gerenciamento de banco de dados de código aberto. Vamos usar o ClusterControl como uma ferramenta centralizada para implantações de cluster, gerenciamento de topologia e monitoramento para fins desta postagem no blog.
1) Instale o ClusterControl.
2) Configure o SSH sem senha do servidor ClusterControl para todos os nós do banco de dados. No nó ClusterControl:
(clustercontrol)$ whoami
root
$ ssh-keygen -t rsa
$ ssh-copy-id [email protected]
$ ssh-copy-id [email protected]
$ ssh-copy-id [email protected]
$ ssh-copy-id [email protected]
$ ssh-copy-id [email protected]
$ ssh-copy-id [email protected]
3) Como vamos implantar 4 conjuntos de clusters, é uma boa ideia usar a ferramenta CLI ClusterControl para essa tarefa específica para agilizar e simplificar o processo de implantação. Vamos primeiro verificar se podemos nos conectar com as credenciais padrão executando o seguinte comando (a credencial padrão é configurada automaticamente em /etc/s9s.conf):
(clustercontrol)$ s9s cluster --list --long
Total: 0
Se não obtivermos nenhum erro e virmos uma saída semelhante à acima, estamos prontos.
4) Observe que as etapas 4,5,6 e 7 podem ser executadas de uma só vez, pois o ClusterControl oferece suporte à implantação paralela. Começaremos implantando o primeiro servidor MariaDB Gateway usando o ClusterControl CLI:
(clustercontrol)$ s9s cluster --create \
--cluster-type=mysqlreplication \
--nodes="192.168.22.101?master" \
--vendor=mariadb \
--provider-version=10.5 \
--os-user=root \
--os-key-file=/root/.ssh/id_rsa \
--db-admin="root" \
--db-admin-passwd="SuperS3cr3tPassw0rd" \
--cluster-name="MariaDB Gateway 1"
5) Implante o segundo servidor MariaDB Gateway:
(clustercontrol)$ s9s cluster --create \
--cluster-type=mysqlreplication \
--nodes="192.168.22.102?master" \
--vendor=mariadb \
--provider-version=10.5 \
--os-user=root \
--os-key-file=/root/.ssh/id_rsa \
--db-admin="root" \
--db-admin-passwd="SuperS3cr3tPassw0rd" \
--cluster-name="MariaDB Gateway 2"
6) Implante uma Replicação MariaDB de 2 nós para o primeiro estilhaço:
(clustercontrol)$ s9s cluster --create \
--cluster-type=mysqlreplication \
--nodes="192.168.22.111?master;192.168.22.112?slave" \
--vendor=mariadb \
--provider-version=10.5 \
--os-user=root \
--os-key-file=/root/.ssh/id_rsa \
--db-admin="root" \
--db-admin-passwd="SuperS3cr3tPassw0rd" \
--cluster-name="MariaDB - Shard 1"
7) Implante uma Replicação MariaDB de 2 nós para o segundo estilhaço:
(clustercontrol)$ s9s cluster --create \
--cluster-type=mysqlreplication \
--nodes="192.168.22.121?master;192.168.22.122?slave" \
--vendor=mariadb \
--provider-version=10.5 \
--os-user=root \
--os-key-file=/root/.ssh/id_rsa \
--db-admin="root" \
--db-admin-passwd="SuperS3cr3tPassw0rd" \
--cluster-name="MariaDB - Shard 2"
Enquanto a implantação está em andamento, podemos monitorar a saída do trabalho da CLI:
(clustercontrol)$ s9s job --list --show-running
ID CID STATE OWNER GROUP CREATED RDY TITLE
25 0 RUNNING admin admins 07:19:28 45% Create MySQL Replication Cluster
26 0 RUNNING admin admins 07:19:38 45% Create MySQL Replication Cluster
27 0 RUNNING admin admins 07:20:06 30% Create MySQL Replication Cluster
28 0 RUNNING admin admins 07:20:14 30% Create MySQL Replication Cluster
E também da interface do usuário do ClusterControl:
Depois que a implantação for concluída, você deverá ver algo que os clusters de banco de dados estão listados assim no painel do ClusterControl:
Nossos clusters agora estão implantados e executando o MariaDB 10.5 mais recente. Em seguida, precisamos configurar o HAProxy para fornecer um único endpoint aos estilhaços do MariaDB.
Configurar HAProxy
O HAProxy é necessário como um ponto de extremidade único para a replicação mestre-escravo do shard. Caso contrário, se um mestre cair, é preciso atualizar a lista de servidores do Spider usando a instrução CREATE OR REPLACE SERVER nos servidores gateway, executar ALTER TABLE e passar um novo parâmetro de conexão. Com o HAProxy, podemos configurá-lo para escutar no host local do servidor gateway e monitorar diferentes shards MariaDB com portas diferentes. Vamos configurar o HAProxy em ambos os servidores de gateway da seguinte forma:
-
127.0.0.1:3307 -> Shard1 (servidores de back-end são mariadb-shard-1a e mariadb-shard- 1b)
-
127.0.0.1:3308 -> Shard2 (servidores de back-end são mariadb-shard-2a e mariadb-shard- 2b)
No caso de o mestre do shard ficar inativo, o ClusterControl fará o failover do escravo do shard como o novo mestre e o HAProxy redirecionará as conexões para o novo mestre de acordo. Vamos instalar o HAProxy nos servidores gateway (mariadb-gw-1 e mariadb-gw-2) usando o ClusterControl, pois ele configurará automaticamente os servidores backend (configuração do mysqlchk, permissões de usuário, instalação do xinetd) com alguns truques, conforme mostrado abaixo.
Primeiro de tudo, na interface do usuário do ClusterControl, escolha o primeiro shard, MariaDB - Shard 1 -> Manage -> Load Balancers -> HAProxy -> Deploy HAProxy e especifique o endereço do servidor como 192.168.22.101 ( mariadb-gw-1), semelhante à captura de tela a seguir:
Da mesma forma, mas este para shard 2, vá para MariaDB - Shard 2 -> Gerenciar -> Load Balancers -> HAProxy -> Implantar HAProxy e especificar o endereço do servidor como 192.168.22.102 (mariadb-gw-2). Aguarde até que a implementação termine para ambos os nós HAProxy.
Agora precisamos configurar o serviço HAProxy em mariadb-gw-1 e mariadb-gw-2 para balancear a carga de todos os shards de uma vez. Usando o editor de texto (ou ClusterControl UI -> Manage -> Configurations), edite as 2 últimas diretivas "listen" do /etc/haproxy/haproxy.cfg para ficar assim:
listen haproxy_3307_shard1
bind *:3307
mode tcp
timeout client 10800s
timeout server 10800s
tcp-check connect port 9200
tcp-check expect string master\ is\ running
balance leastconn
option tcp-check
default-server port 9200 inter 2s downinter 5s rise 3 fall 2 slowstart 60s maxconn 64 maxqueue 128 weight 100
server 192.168.22.111 192.168.22.111:3306 check # mariadb-shard-1a-master
server 192.168.22.112 192.168.22.112:3306 check # mariadb-shard-1b-slave
listen haproxy_3308_shard2
bind *:3308
mode tcp
timeout client 10800s
timeout server 10800s
tcp-check connect port 9200
tcp-check expect string master\ is\ running
balance leastconn
option tcp-check
default-server port 9200 inter 2s downinter 5s rise 3 fall 2 slowstart 60s maxconn 64 maxqueue 128 weight 100
server 192.168.22.121 192.168.22.121:3306 check # mariadb-shard-2a-master
server 192.168.22.122 192.168.22.122:3306 check # mariadb-shard-2b-slave
Reinicie o serviço HAProxy para carregar as alterações (ou use ClusterControl -> Nodes -> HAProxy -> Restart Node):
$ systemctl restart haproxy
A partir da interface do usuário do ClusterControl, podemos verificar se apenas um servidor de back-end está ativo por estilhaço (indicado pelas linhas verdes), conforme mostrado abaixo:
Neste ponto, nossa implantação de cluster de banco de dados está concluída. Podemos continuar a configurar o sharding do MariaDB usando o mecanismo de armazenamento Spider.
Preparando Servidores MariaDB Gateway
Em ambos os servidores MariaDB Gateway (mariadb-gw-1 e mariadb-gw-2), execute as seguintes tarefas:
Instale o plugin Spider:
MariaDB> INSTALL PLUGIN spider SONAME 'ha_spider.so';
Verifique se o mecanismo de armazenamento é compatível:
MariaDB> SELECT engine,support FROM information_schema.engines WHERE engine = 'spider';
+--------+---------+
| engine | support |
+--------+---------+
| SPIDER | YES |
+--------+---------+
Opcionalmente, também podemos verificar se o plug-in foi carregado corretamente do banco de dados information_schema:
MariaDB> SELECT PLUGIN_NAME,PLUGIN_VERSION,PLUGIN_STATUS,PLUGIN_TYPE FROM information_schema.plugins WHERE plugin_name LIKE 'SPIDER%';
+--------------------------+----------------+---------------+--------------------+
| PLUGIN_NAME | PLUGIN_VERSION | PLUGIN_STATUS | PLUGIN_TYPE |
+--------------------------+----------------+---------------+--------------------+
| SPIDER | 3.3 | ACTIVE | STORAGE ENGINE |
| SPIDER_ALLOC_MEM | 1.0 | ACTIVE | INFORMATION SCHEMA |
| SPIDER_WRAPPER_PROTOCOLS | 1.0 | ACTIVE | INFORMATION SCHEMA |
+--------------------------+----------------+---------------+--------------------+
Adicione a seguinte linha na seção [mysqld] dentro do arquivo de configuração do MariaDB:
plugin-load-add = ha_spider
Crie o primeiro "nó de dados" para o primeiro estilhaço que deve ser acessível via HAProxy 127.0.0.1 na porta 3307:
MariaDB> CREATE OR REPLACE SERVER Shard1
FOREIGN DATA WRAPPER mysql
OPTIONS (
HOST '127.0.0.1',
DATABASE 'sbtest',
USER 'spider',
PASSWORD 'SpiderP455',
PORT 3307);
Crie o segundo "nó de dados" para o segundo estilhaço que deve ser acessível via HAProxy 127.0.0.1 na porta 3308:
CREATE OR REPLACE SERVER Shard2
FOREIGN DATA WRAPPER mysql
OPTIONS (
HOST '127.0.0.1',
DATABASE 'sbtest',
USER 'spider',
PASSWORD 'SpiderP455',
PORT 3308);
Agora podemos criar uma tabela Spider que precisa ser particionada. Neste exemplo, vamos criar uma tabela chamada sbtest1 dentro do banco de dados sbtest, e particionada pelo valor inteiro na coluna 'k':
MariaDB> CREATE SCHEMA sbtest;
MariaDB> CREATE TABLE sbtest.sbtest1 (
`id` int(11) NOT NULL AUTO_INCREMENT,
`k` int(11) NOT NULL DEFAULT '0',
`c` char(120) NOT NULL DEFAULT '',
`pad` char(60) NOT NULL DEFAULT '',
PRIMARY KEY (`id`, `k`)
)
ENGINE=Spider
COMMENT 'wrapper "mysql", table "sbtest1"'
PARTITION BY RANGE (k) (
PARTITION shard1 VALUES LESS THAN (499999) COMMENT = 'srv "Shard1"',
PARTITION shard2 VALUES LESS THAN MAXVALUE COMMENT = 'srv "Shard2"'
);
Observe que as cláusulas COMMENT ='srv "ShardX"' da instrução CREATE TABLE são críticas, onde passamos informações de conexão sobre o servidor remoto. O valor deve ser idêntico ao nome do servidor como na instrução CREATE SERVER. Vamos preencher esta tabela usando o gerador de carga Sysbench conforme mostrado mais abaixo.
Crie o usuário do banco de dados do aplicativo para acessar o banco de dados e permita-o nos servidores do aplicativo:
MariaDB> CREATE USER [email protected]'192.168.22.%' IDENTIFIED BY 'passw0rd';
MariaDB> GRANT ALL PRIVILEGES ON sbtest.* TO [email protected]'192.168.22.%';
Neste exemplo, como esta é uma rede interna confiável, usamos apenas um curinga na instrução para permitir qualquer endereço IP no mesmo intervalo, 192.168.22.0/24.
Agora estamos prontos para configurar nossos nós de dados.
Preparando servidores de fragmentos MariaDB
Em ambos os servidores mestre MariaDB Shard (mariadb-shard-1a e mariadb-shard-2a), execute as seguintes tarefas:
1) Crie o banco de dados de destino:
MariaDB> CREATE SCHEMA sbtest;
2) Crie o usuário 'spider' e permita conexões dos servidores gateway (mariadb-gw-1 e mariadb-gw2). Este usuário deve ter todos os privilégios na tabela fragmentada e também no banco de dados do sistema MySQL:
MariaDB> CREATE USER 'spider'@'192.168.22.%' IDENTIFIED BY 'SpiderP455';
MariaDB> GRANT ALL PRIVILEGES ON sbtest.* TO [email protected]'192.168.22.%';
MariaDB> GRANT ALL ON mysql.* TO [email protected]'192.168.22.%';
Neste exemplo, como esta é uma rede interna confiável, usamos apenas um curinga na instrução para permitir qualquer endereço IP no mesmo intervalo, 192.168.22.0/24.
3) Crie a tabela que vai receber os dados de nossos servidores gateway via mecanismo de armazenamento Spider. Essa tabela "receptora" pode estar em qualquer mecanismo de armazenamento suportado pelo MariaDB. Neste exemplo, usamos o mecanismo de armazenamento InnoDB:
MariaDB> CREATE TABLE sbtest.sbtest1 (
`id` int(11) NOT NULL AUTO_INCREMENT,
`k` int(11) NOT NULL DEFAULT '0',
`c` char(120) NOT NULL DEFAULT '',
`pad` char(60) NOT NULL DEFAULT '',
PRIMARY KEY (`id`, `k`)
) ENGINE = INNODB;
É isso. Não se esqueça de repetir os passos no outro fragmento.
Teste
Para testar usando o Sysbench para gerar algumas cargas de trabalho de banco de dados, no servidor de aplicação, temos que instalar o Sysbench previamente:
$ yum install -y https://repo.percona.com/yum/percona-release-latest.noarch.rpm
$ yum install -y sysbench
Gere algumas cargas de trabalho de teste e envie-as para o primeiro servidor de gateway, mariadb-gw-1 (192.168.11.101):
$ sysbench \
/usr/share/sysbench/oltp_insert.lua \
--report-interval=2 \
--threads=4 \
--rate=20 \
--time=9999 \
--db-driver=mysql \
--mysql-host=192.168.11.101 \
--mysql-port=3306 \
--mysql-user=sbtest \
--mysql-db=sbtest \
--mysql-password=passw0rd \
--tables=1 \
--table-size=1000000 \
run
Você pode repetir o teste acima em mariadb-gw-2 (192.168.11.102) e as conexões de banco de dados devem ser roteadas para o shard correto de acordo.
Ao olhar para o primeiro fragmento (mariadb-shard-1a ou mariadb-shard-1b), podemos dizer que esta partição contém apenas linhas onde a chave do fragmento (coluna k) é menor que 500000:
MariaDB [sbtest]> SELECT MIN(k),MAX(k) FROM sbtest1;
+--------+--------+
| min(k) | max(k) |
+--------+--------+
| 200175 | 499963 |
+--------+--------+
Em outro fragmento (mariadb-shard-2a ou mariadb-shard-2b), ele contém dados de 500.000 até 999.999 conforme esperado:
MariaDB [sbtest]> SELECT MIN(k),MAX(k) FROM sbtest1;
+--------+--------+
| min(k) | max(k) |
+--------+--------+
| 500067 | 999948 |
+--------+--------+
Enquanto para o servidor MariaDB Gateway (mariadb-gw-1 ou mariadb-gw-2), podemos ver todas as linhas semelhantes a se a tabela existir dentro desta instância MariaDB:
MariaDB [sbtest]> SELECT MIN(k),MAX(k) FROM sbtest1;
+--------+--------+
| min(k) | max(k) |
+--------+--------+
| 200175 | 999948 |
+--------+--------+
Para testar o aspecto de alta disponibilidade, quando um shard master não estiver disponível, por exemplo quando o master (mariadb-shard-2a) do shard 2 ficar inativo, o ClusterControl irá automaticamente realizar a promoção do slave no o escravo (mariadb-shard-2b) para ser um mestre. Durante esse período, você provavelmente poderá ver este erro:
ERROR 1429 (HY000) at line 1: Unable to connect to foreign data source: Shard2
E enquanto estiver indisponível, você receberá o seguinte erro subsequente:
ERROR 1158 (08S01) at line 1: Got an error reading communication packets
Em nossa medição, o failover levou cerca de 23 segundos após o início do failover e, assim que o novo mestre for promovido, você poderá gravar na tabela a partir do servidor gateway como de costume.
Conclusão
A configuração acima é uma prova de princípio de como o ClusterControl pode ser usado para implantar uma configuração fragmentada do MariaDB. Ele também pode melhorar a disponibilidade de serviço de uma configuração de fragmentação MariaDB com seu recurso de recuperação automática de nó e cluster, além de todos os recursos de gerenciamento e monitoramento padrão do setor para dar suporte à sua infraestrutura geral de banco de dados.