Giter Club home page Giter Club logo

ailtonmorais / newsql-disponibilidade Goto Github PK

View Code? Open in Web Editor NEW
0.0 1.0 2.0 1.35 MB

Tutorial que aborda NewSQL com relação a disponibilidade como parte da avaliação da disciplina de Tópicos em Banco de Dados (2020/2) - Profa. Dra. Sahudy Gonzalez, do programa de mestrado em Ciência da Computação da UFScar Sorocaba. Autor: Ailton Morais

Home Page: https://github.io/newsql-disponibilidade/

mysql-cluster cockroachdb alta-disponibilidade docker banco-de-dados

newsql-disponibilidade's Introduction


Departamento de Computação (DComp-So)

Centro de Ciências e Gestão em Tecnologias (CCGT)

UNIVERSIDADE FEDERAL DE SÃO CARLOS - Campus Sorocaba


Sobre

Tutorial que aborda NewSQL com relação a disponibilidade como parte da avaliação da disciplina de Tópicos em Banco de Dados (2020/2) - Profa. Dra. Sahudy Gonzalez, do programa de mestrado em Ciência da Computação da UFScar Sorocaba.

NewSQL - Disponibilidade

Autor: Ailton Morais

Índice

  1. Introdução
    1.1. MySQL Cluster
    1.2. CockroachDB
    1.3. Estudo de Caso
  2. Visão Geral
    2.1. Alta Disponibilidade
    2.1.1. MySQL Cluster
    2.1.2. CockroachDB
  3. Resiliência a Falhas
    3.1. MySQL Cluster
    3.2. CockroachDB
  4. Instalação e Configuração
    4.1. Docker
    4.2. MySQL Cluster
    4.3. CockroachDB
  5. Disponibilidade na Prática
    5.1. MySQL Cluster
    5.2. CockroachDB
  6. Benchmark - MySQL vs CockroachDB
  7. Conclusão
  8. Referências Bibliográficas

1. Introdução

A proposta do tutorial é apresentar o passo a passo desde a instalação, configuração, casos de uso e testes que irão ajudar a entender a abordagem da disponibilidade do MySQL Cluster & CockroachDB

1.1. MySQL Cluster

MySQL Cluster é um banco de dados distribuído que combina escalabilidade linear e alta disponibilidade. Foi projetado para aplicativos de missão crítica, fornece acesso em tempo real na memória com consistência transacional em conjuntos de dados particionados e distribuídos [1].

O Cluster MySQL tem replicação entre clusters em vários locais geográficos integrados e uma arquitetura nada compartilhada com reconhecimento de localidade de dados o que torna a escolha perfeita para execução em hardware comum e em infraestrutura em nuvem distribuída globalmente [1].

1.2. CockroachDB

CockroachDB é um banco de dados SQL distribuído construído em um armazenamento de chave-valor transacional e fortemente consistente. Ele é dimensionado horizontalmente, sobrevive a falhas de disco, máquina, rack e até mesmo de datacenter com interrupção de latência mínima e sem intervenção manual, suporta transações ACID fortemente consistentes e fornece uma API SQL familiar para estruturar, manipular e consultar dados [4].

1.3. Estudo de Caso

Neste tutorial será utilizado o banco de dados do Northwind que foi criado pela Microsoft para atender os seus produtos, mas ao longo do tempo se tornou uma amostra bastante utilizada em tutoriais de banco de dados não desenvolvidos pela Microsoft. Dentre as amostras do banco de bados Northwind podemos destacar:

  • Suppliers

  • Customers

  • Employees

  • Products

  • Shippers

  • Orders

No total o banco de dados Northwind contém 14 tabelas. O diagrama com o relacionamento entre as tabelas pode ser visto abaixo:


Figura 1: Diagram ER. Fonte: (YugabyteDB 2020a)

Voltar ao índice

2. Visão Geral

Os bancos de dados relacionais surguiram para necessidade de armazenamento de dados, mas na época não existia as tecnologias Web e os diversos tipos de dispositivos que geram uma enorme quantidade de dados se compararmos com a nossa realidade atual.

Com a evolução tecnológica e o astronômico crescimento dos dispositivos móveis conectados a internet abriu caminho para a era da Internet das Coisas e já estamos vivendo mudanças significativas na sociedade. Veja algumas declarações que demonstram tal potencial:

  • A Internet das Coisas será uma revolução muito maior que a internet e os celulares juntos! [13];

  • A Internet das Coisas representa uma nova inteligência para os negócios, é uma mudança de paradigma do consumo, uma revolução do comportamento humano, um caminho para um novo mundo onde tudo e todos estarão conectados e sem fronteiras. Um caminho para um mundo que ainda não imaginamos [14].

A partir destes desafios surgiram os novos sistemas de banco de dados nomeados como NoSQL (Not Only SQL). Estas soluções fornecem alta disponbilidade, escalabilidade e uma arquitetura distribuída com crescimento horizontal. Mesmo sendo capaz de manipular grandes quantidades de dados, os banco de dados NoSQL geralmente não possuem suporte para as propriedades ACID [21]:

  • Atomicity: Transação deve ser executado por completo ou não executada;

  • Consistency: Se o resultado final não for válido ou ocorrer falha, os dados devem ser o mesmo antes do inicio da transação;

  • Isolation: Um transação em andamente não deve sofrer interferência de outra transação concorrente;

  • Durability: Garante os dados disponíveis em definitivo.

Para quebrar alguns paradgimas foi criado os sistemas de banco de dados NewSQL que combinam funcionalidades do modelo relacional e NoSQL. Segundo [15] os sistemas NewSQL são soluções modernas que buscam prover o mesmo desempenho escalável dos bancos de dados NoSQL para cargas de trabalho OLTP com tı́pico suporte completo a todas as propriedades ACID, como encontrado nos banco de dados relacionais.

Os sistemas de banco de dados NewSQL são adequados para aplicações que utilizavam o SGBD tradicional, mas que surgiu a necessidade de escalabilidade adicional e aprimoramento de desempenho [16].

Os sistemas de banco de dados NewSQL tem como característica a execução de transações de leitura e gravação que:

  • São de curta duração;

  • Atingue um pequeno subconjunto de dados;

  • Não fazem varredura de tabela completa;

  • Possuem consultas repetidas com diferentes entradas.

De acordo com [15] pode existir uma caracterização mais restrita com a implementação de um sistema de banco de dados NewSQL que utiliza:

  • Um esquema de controle de simultaneidade sem bloqueio;

  • Uma arquitetura distribuída não compartilhada.

STONEBRAKER e CATTEL, 2011[18] definem as cinco principais características de um SGBD NewSQL abaixo:

  1. SQL como o principal mecanismo de interação de aplicativos;

  2. Suporte ACID para transações;

  3. Um mecanismo de controle de simultaneidade não bloqueável, portanto as leituras em tempo real não entrarão em conflito com as escritas;

  4. Uma arquitetura que oferece um desempenho por nó muito maior que o disponível nas soluções SGBDs tradicionais;

  5. Uma arquitetura de escala, não compartilhada, capaz de funcionar em um grande número de nós sem sofrerem estrangulamentos.

Segundo [15] as três categorias que melhor representam os sistemas de banco de dados NewSQL são:

  1. Sistemas inovadores construídos a partir do zero usando uma nova arquitetura;

  2. Middleware que re-implementam a mesma infra-estrutura que foi desenvolvida na década de 2000 pelo Google e outros;

  3. Ofertas de banco de dados como serviço de provedores de computação em nuvem que também são baseadas em novas arquiteturas.

Certamente podemos considerar que os sistemas de banco de dados NewSQL conseguem resolver os principais problemas de escalabilidade, desempenho e disponibilidade que temos no sistema relacional tradicional. Segundo [17] o NewSQL deve ser considerado como uma alternativa ao NoSQL ou banco de dados relacional clássico para novos aplicativos OLTP.

2.1. Alta Disponibilidade

A alta disponibilidade não está relacionada somente ao tempo que um sistema está acessível, mas também ao tempo que o sistema precisa para responder às solicitações dos usuários. Geralmente além dos testes é necessário prover componentes redundantes para obter um nível de disponibilidade alta mesmo em caso de falhas em parte da infra-estrutura.

2.1.1. MySQL Cluster

Para garantir a alta disponibilidade o MySQL Cluster se apoia em [2]:

  • Replicação síncrona: Os dados em cada nó de dados são replicados de forma síncrona para outro nó de dados;

  • Failover automático: - O mecanismo de pulsação do MySQL Cluster detecta instantaneamente quaisquer falhas e faz failover automaticamente, normalmente em um segundo, para outros nós no cluster, sem interromper o serviço aos clientes;

  • Autocorreção: Os nós com falha são capazes de se autocorrigir reiniciando automaticamente e ressincronizando com outros nós antes de reingressar no cluster, com total transparência do aplicativo;

  • Arquitetura de nada compartilhado: Nenhum ponto único de falha, cada nó tem seu próprio disco e memória, portanto, o risco de uma falha causada por componentes compartilhados, como armazenamento, é eliminado;

  • Replicação geográfica: A replicação geográfica permite que os nós sejam espelhados em data centers remotos para recuperação de desastres.

2.1.2. CockroachDB

Para o CockroachDB escalar os serviços horizontalmente é fundamental, para tal devemos utilizar a replicação dos dados em diversos servidores. Em caso de falha de um desses servidores, podemos continuar com os serviços operacionais. Segue um resumo com os principais conceitos utilizados para garantir a disponibilidade [6]:

  • Consistência: Usa a "consistência" tanto no sentido da semântica ACID (Atomicity, Consistency, Isolation, Durability) quanto no teorema CAP (Consistency, Availability, Partition Tolerance), embora menos formalmente do que qualquer definição. O objetivo é garantir os dados livres de anomalias;

  • Intervalo: Armazena todos os dados do usuário (tabelas, índices, etc.) e quase todos os dados do sistema em um mapa gigante classificado de pares de chave-valor. Este keyspace é dividido em "intervalos", pedaços contíguos do keyspace, de forma que cada chave pode sempre ser encontrada em um único intervalo;

  • Consenso: Quando um intervalo recebe uma gravação, um quorum de nós contendo réplicas do intervalo confirma a gravação. Isso significa que seus dados são armazenados com segurança e a maioria dos nós concorda com o estado atual do banco de dados, mesmo se alguns dos nós estiverem offline. Quando uma gravação não chega a um consenso, o progresso de encaminhamento é interrompido para manter a consistência dentro do cluster;

  • Replicação: Criação e distribuição de cópias de dados, bem como a garantia de que as cópias permaneçam consistentes. No entanto, existem vários tipos de replicação: a saber, síncrona e assíncrona. O CockroachDB usa a replicação síncrona que requer que todas as gravações se propaguem para um quorum de cópias dos dados antes de serem consideradas confirmadas;

  • Transações: Conjunto de operações realizadas em seu banco de dados que atendem aos requisitos da semântica ACID. Este é um componente crucial para um sistema consistente confie no seu banco de dados;

  • Disponibilidade Multi-ativa: O consenso de alta disponibilidade permite que cada nó no cluster controle leituras e gravações para um subconjunto dos dados armazenados (em uma base por intervalo).

3. Resiliência a Falhas

A confiabiliade de um sistema gerenciador de banco de dados tem um relação direta com a resiliência a falhas e redundância dos dados. Segundo [19] a solução para o problema de confiabilidade é introduzir a redundância; ou seja, armazenamos informações extras que normalmente não são necessárias, mas que podem ser usadas no caso de falha de um disco, para recriar a informação perdida. Assim, mesmo que um disco falhe os dados não são perdidos [...]

3.1. MySQL Cluster

No mínimo de três computadores para executar um cluster viável. No entanto, o número mínimo recomendado de computadores em um Mysql Cluster NDB é quatro: um para cada para executar o gerenciamento e os nós SQL, e dois computadores para servir como nós de dados. O objetivo dos dois nós de dados é fornecer redundância; o nó de gerenciamento deve ser executado em uma máquina separada para garantir serviços de arbitragem contínuos no caso de um dos nós de dados falhar [3].


Figura 2: Sem um único ponto de falha, o MySQL Cluster oferece extrema resiliência a falhas. Fonte: (MySQL 2020b)

Na figura acima temos uma arquitetura que garante nenhum ponto de falha, ou seja, cada nó tem o seu próprio disco e memória o que elimina uma falha em componentes compartilhado.

3.2. CockroachDB

No mínimo de três computadores (3 nós) para executar um cluster viável, quando você estiver pronto para executar o seu sistema em produção em uma única região. É importante implantar pelo menos 3 nós do CockroachDB para aproveitar as vantagens dos recursos de replicação, distribuição, rebalanceamento e resiliência automáticos [7].


Figura 3: Topologia Básica. Fonte: (Cockroach 2020c)

Voltar ao índice

4. Instalação e Configuração

A distribuição Ubuntu 18.04 do Linux será o sitema operacional utilizado em todo o processo de instalação e experimentos deste tutorial. Em meados de 2004 foi lançado a primeira versão do Ubuntu que cresceu e se tornou a mais popular distribuição Linux Desktop conhecida por ser considerado um sistema operacional fácil de ser usado. Todos os comandos mostrados ao longo deste tutorial podem ser reproduzidos em qualquer distribuição derivada do Debian. É importante lembrar que os bancos de dados MySQL Cluster e CockroachDB serão instalados no Docker. Os requisitos mínimos para executar este tutorial são:

  • 8GB de RAM
  • 1.80GHz de CPU
  • 10GB de espaço em disco

4.1. Docker

O Docker é uma plataforma de código aberto desenvolvida na linguagem go. O Docker permite criar, testar e implementar aplicações em um ambiente apartado da máquina original conhecido como contâiner. Isso possibilita que qualquer software seja empacotado de maneira padronizada.


Figura 4: Docker logo. Fonte: (Docker 2020a)

Siga as instruções abaixo para instalação [10].

  1. Execute o comando de atualização para garantir as listas de fontes mais recentes:
$ sudo apt update
  1. Instale os pacotes de pré-requisitos para garantir que o apt utilize pacotes via HTTPS:
$ sudo apt install apt-transport-https ca-certificates curl software-properties-common
  1. Adicione a chave GPG para o repositório oficial do Docker em seu sistema:
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
  1. Adicione o repositório do Docker as fontes do APT:
$ sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu bionic stable"
  1. Execute o comando de atualização para garantir as listas de fontes mais recentes:
$ sudo apt update
  1. Instale o Docker:
$ sudo apt install docker-ce
  1. Neste o ponto o Docker deve ser instalado, o daemon iniciado e o processo ativado. Verifique executando o comando abaixo:
$ sudo systemctl status docker
  1. Confirme se o comando executado acima mostra o serviço como ativo, conforme exibido abaixo:
Output
● docker.service - Docker Application Container Engine
   Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
   Active: active (running) since Thu 2018-07-05 15:08:39 UTC; 2min 55s ago
     Docs: https://docs.docker.com
 Main PID: 10096 (dockerd)
    Tasks: 16
   CGroup: /system.slice/docker.service
           ├─10096 /usr/bin/dockerd -H fd://
           └─10113 docker-containerd --config /var/run/docker/containerd/containerd.toml

4.2. MySQL Cluster

Nesta seção será mostrado o processo de instalação e configuração da versão 8.0 do MySQL Cluster no Docker. Cada node será executado em hosts separados usando a configuração de rede do Docker. Utilizaremos comandos do git, se for necessário clique aqui para obter mais detalhes.


Figura 5: MySQL Docker logo. Fonte: (Medium 2020a)

Ao final do processo teremos 1 node de gerenciamento, 2 nodes de dados e 2 nodes SQL conforme ilustrado na figura abaixo.


Figura 6: NDB Cluster Diagram. Fonte: (Medium 2020a)

Siga os passos abaixo para instalação e configuração do MySQL Cluster [11].

  1. Configure a subnet no Docker:
$ docker network create cluster --subnet=10.100.0.0/16
  1. Clone o MySQL do repositório oficial:
$ sudo git clone https://github.com/mysql/mysql-docker.git
  1. Acesse o diretório do MySQL Cluster que foi criado:
$ sudo cd mysql-docker/
  1. Crie um novo branch:
$ sudo git checkout mysql-cluster
  1. Abra o arquivo "8.0/cnf/mysql-cluster.cnf" e configure conforme abaixo:
[ndb_mgmd]
NodeId=1
hostname=10.100.0.2
datadir=/var/lib/mysql

[ndbd]
NodeId=2
hostname=10.100.0.3
datadir=/var/lib/mysql

[ndbd]
NodeId=3
hostname=10.100.0.4
datadir=/var/lib/mysql

[mysqld]
NodeId=4
hostname=10.100.0.10

[mysqld]
NodeId=5
hostname=10.100.0.11
  1. Abra o arquivo "8.0/cnf/my.cnf" e configure conforme abaixo:
[mysqld]
ndbcluster
ndb-connectstring=10.100.0.2
user=mysql

[mysql_cluster]
ndb-connectstring=10.100.0.2
  1. Crie a imagem no Docker (docker build -t <image_name> ):
$ docker build -t mysql-cluster /opt/mysql-docker/8.0/

Após concluir todos os passos citados acima podemos iniciar o processo de criação dos nodes do cluster.

  1. Crie o node de gerenciamento com o nome management1 e IP 10.100.0.2:
$ docker run -d --net=cluster --name=management1 --ip=10.100.0.2 mysql-cluster ndb_mgmd
  1. Crie os 2 nodes de dados:
$ docker run -d --net=cluster --name=ndb1 --ip=10.100.0.3 mysql-cluster ndbd
$ docker run -d --net=cluster --name=ndb2 --ip=10.100.0.4 mysql-cluster ndbd
  1. Crie os 2 nodes de SQL:
$ docker run -d --net=cluster --name=mysql1 --ip=10.100.0.10 -e MYSQL_RANDOM_ROOT_PASSWORD=true mysql-cluster mysqld
$ docker run -d --net=cluster --name=mysql2 --ip=10.100.0.11 -e MYSQL_RANDOM_ROOT_PASSWORD=true mysql-cluster mysqld
  1. Execute o comando abaixo para acessar a console cluster:
$ docker run -it --net=cluster mysql-cluster ndb_mgm

A console de gerenciamento do cluster será iniciada.

[Entrypoint] MySQL Docker Image 8.0.22-1.1.18-cluster
[Entrypoint] Starting ndb_mgm
-- NDB Cluster -- Management Client --
ndb_mgm>
  1. Execute o comando "show" para verificar o status dos nodes do cluster:
ndb_mgm> show

Confirme se todos os nodes estão em execução.

Connected to Management Server at: 10.100.0.2:1186
Cluster Configuration
---------------------
[ndbd(NDB)]	2 node(s)
id=2	@10.100.0.3  (mysql-8.0.22 ndb-8.0.22, Nodegroup: 0, *)
id=3	@10.100.0.4  (mysql-8.0.22 ndb-8.0.22, Nodegroup: 0)

[ndb_mgmd(MGM)]	1 node(s)
id=1	@10.100.0.2  (mysql-8.0.22 ndb-8.0.22)

[mysqld(API)]	2 node(s)
id=4	@10.100.0.10  (mysql-8.0.22 ndb-8.0.22)
id=5	@10.100.0.11  (mysql-8.0.22 ndb-8.0.22)

ndb_mgm>

Na sequência vamos configurar os nodes MySQL para que permitir o login remoto no banco de dados. Os nodes SQL foram criados com senha randômica.

  1. Recupere a senha padrão do 1° node MySQL (docker logs <node_name> 2>&1 | grep PASSWORD):
$ docker logs mysql1 2>&1 | grep PASSWORD

A senha randômica padrão será exibida.

[Entrypoint] GENERATED ROOT PASSWORD: EaXaS)eWyx%eLULiM0c@HAMoNXLu
  1. Acesse o 1° node MySQL (docker exec -it <node_name> mysql -uroot -p):
$ docker exec -it mysql1 mysql -uroot -p
  1. Digite a senha padrão do 1° node MySQL:
$ Enter password:

O console do 1° node do MySQL será exibido.

Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 79
Server version: 8.0.22-cluster MySQL Cluster Community Server - GPL

Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
  1. Altere a senha padrão do 1° node MySQL:
mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY 'MyNewPass'; 
  1. Atualize os privilégios de acesso:
mysql> flush privileges; 

Repita os passos 13 a 17 para o 2° node mysql do cluster.

4.3. CockroachDB

Nesta etapa iremos instalar e configurar a versão 20.2.2 do CockroachDB no Docker. Cada node será executado em hosts separados usando a configuração de rede do Docker.


Figura 7: Cockroach logo. Fonte: (Cockroach 2020a)

Ao final do processo teremos 3 nodes e cada node terá uma instância de banco de dados conforme podemos ver na figura abaixo.


Figura 8: Start a Cluster in Docker. Fonte: (Cockroach 2020c)

Aplique a sequência de comandos abaixo para ter todos os nodes em operacão [7].

  1. Baixe a imagem do cockroachdb no Docker:
$ sudo docker pull cockroachdb/cockroach:v20.2.2 
  1. Crie a rede no Docker:
$ docker network create -d bridge roachnet 
  1. Inicie o 1° node:
$ docker run -d \
--name=roach1 \
--hostname=roach1 \
--net=roachnet \
-p 26257:26257 -p 8080:8080  \
-v "${PWD}/cockroach-data/roach1:/cockroach/cockroach-data"  \
cockroachdb/cockroach:v20.2.2 start \
--insecure \
--join=roach1,roach2,roach3
  • Antes de iniciar os demais nodes, vamos entender cada parâmetro do comando acima.
    • docker run: Comando Docker que inicia um novo container;
    • -d: Esta flag permite rodar o comando em background;
    • --name: O nome do container;
    • --hostname: Este é um identificador único utilizado para juntar outros nodes no cluster;
    • --net: O nome do identificador de rede criado no passo 1;
    • -p 26257:26257 -p 8080:8080: Porta de comunicação com o node e de requisição HTTP;
    • -v "${PWD}/cockroach-data/roach1:/cockroach/cockroach-data": Caminho de armazenamento do log do node;
    • cockroachdb/cockroach:v20.2.2 start --insecure: Comando que inicia o node em modo inseguro;
    • --join: Lista de hostnames que compoem o cluster.
  1. Inicie o 2° node:
$ docker run -d \
--name=roach2 \
--hostname=roach2 \
--net=roachnet \
-p 26257:26257 -p 8080:8080  \
-v "${PWD}/cockroach-data/roach2:/cockroach/cockroach-data"  \
cockroachdb/cockroach:v20.2.2 start \
--insecure \
--join=roach1,roach2,roach3
  1. Inicie o 3° node:
$ docker run -d \
--name=roach3 \
--hostname=roach3 \
--net=roachnet \
-p 26257:26257 -p 8080:8080  \
-v "${PWD}/cockroach-data/roach3:/cockroach/cockroach-data"  \
cockroachdb/cockroach:v20.2.2 start \
--insecure \
--join=roach1,roach2,roach3
  1. Acesse o 1° node do cockroach (docker exec -it <node_name> ./cockroach init --insecure):
$ docker exec -it roach1 ./cockroach init --insecure

Execute o comando abaixo para verificar detalhes do node iniciado.

$ grep 'node starting' cockroach-data/roach1/logs/cockroach.log -A 11

O resultado deve ser parecido com o log abaixo.

CockroachDB node starting at 2021-01-02 21:36:24.902390034 +0000 UTC (took 11.9s)
build:               CCL v20.2.2 @ 2020/11/25 14:45:44 (go1.13.14)
webui:               ‹http://roach1:8080›
sql:                 ‹postgresql://root@roach1:26257?sslmode=disable›
RPC client flags:    ‹/cockroach/cockroach <client cmd> --host=roach1:26257 --insecure›
logs:                ‹/cockroach/cockroach-data/logs›
temp dir:            ‹/cockroach/cockroach-data/cockroach-temp236940084›
external I/O path:   ‹/cockroach/cockroach-data/extern›
store[0]:            ‹path=/cockroach/cockroach-data›
storage engine:      pebble
status:              restarted pre-existing node
clusterID:           ‹fc1b7739-d5bd-4e2b-a2b6-6d93ae12bc9a›

Caso seja necessário, repita o passo 6 para acessar o 2° e 3° node do cockroach.

Voltar ao índice

5. Disponibilidade na Prática

A disponibilidade é um fator crítico que deve ser considerado ao escolher um banco de dados. Certamente diversos fatores podem influenciar nesta escolha, mas conforme já foi detalhado ao longo deste material temos fatores importantes que tornam o banco de dados mais resiliente e disponível sempre que seja necessário consultar os dados.

Nas seções anteriores mergulhamos em todas as características relevantes dos bancos de dados que foram escolhidos para este tutorial e foi mostrado com detalhes os passos para instalação e configuração de cada um deles. A disponibilidade do banco de dados é um processo que envolve a melhor escolha possível para o negócio em questão, uma boa definição da arquitetura e infra-estrutura adequada.

Na disponibilidade na pŕatica, vamos explorar o conceito de replicação que é realizado de forma síncrona pelos bancos de dados deste estudo. Neste caso iremos criar um novo database em um node e confirmar se o dado foi replicado para os demais nodes do cluster. Para validar o conceito de failover automático vamos parar um node do cluster e verificar na ferramenta de monitoramento disponibilizada pelo banco de dados se o node é detectado como indisponível para uso. O nosso último teste será com o conceito de autocorreção, tendo o objetivo de confirmar se ao reiniciar um node que esteja indisponível o banco de dados primeiro atualiza este node com os dados mais recentes antes de permitir o reingresso no cluster.

A partir de agora vamos mostrar a disponibilidade com foco na redundância, já que construimos este caminho tendo uma estrutura resiliente e redundante para os banco de dados deste estudo.

5.1. MySQL Cluster

Na seção de (Alta Disponibilidade), foi mostrado que o MySQL Cluster se apoia na replicação, failover automático, autocorreção, arquitetura sem compartilhamento e replicação geográfica para garantir um alto nível de disponibilidade. Acompanhe na prática alguns destes conceitos:

  1. Replicação - A replicação é realizada de forma síncrona para os nós de dados. É importante lembrar que temos 2 nós de dados e 2 nós SQL que podem ser acessados diretamente pelas aplicações dependendo da arquitetura de acesso que será definida. Para confirmar os nodes existentes execute o comando abaixo.
$ docker ps

O resultado deve ser similar ao resultado mostrado.

CONTAINER ID   IMAGE           COMMAND                  CREATED       STATUS                          PORTS                                     NAMES
ba2c07ad51da   mysql-cluster   "/entrypoint.sh mysq…"   3 weeks ago   Up About a minute (healthy)     1186/tcp, 2202/tcp, 3306/tcp, 33060/tcp   mysql2
56887df6ca9b   mysql-cluster   "/entrypoint.sh mysq…"   3 weeks ago   Up About a minute (healthy)     1186/tcp, 2202/tcp, 3306/tcp, 33060/tcp   mysql1
49b02cc3e06a   mysql-cluster   "/entrypoint.sh ndbd"    3 weeks ago   Up About a minute (unhealthy)   1186/tcp, 2202/tcp, 3306/tcp, 33060/tcp   ndb2
c5e38486e34f   mysql-cluster   "/entrypoint.sh ndbd"    3 weeks ago   Up About a minute (unhealthy)   1186/tcp, 2202/tcp, 3306/tcp, 33060/tcp   ndb1
7b81a0345ee7   mysql-cluster   "/entrypoint.sh ndb_…"   3 weeks ago   Up About a minute (unhealthy)   1186/tcp, 2202/tcp, 3306/tcp, 33060/tcp   management1

Também é possível acessar o console de gerenciamento do Mysql Cluster. Execute o comando abaixo para iniciar o NDB Manager.

$ docker run -it --net=cluster mysql-cluster ndb_mgm

A tela de console deve ser exibida.

[Entrypoint] MySQL Docker Image 8.0.22-1.1.18-cluster
[Entrypoint] Starting ndb_mgm
-- NDB Cluster -- Management Client --
ndb_mgm>

Execute o comando show para verificar o status do cluster.

ndb_mgm> show

Veja o resultado do comando.

Connected to Management Server at: 10.100.0.2:1186
Cluster Configuration
---------------------
[ndbd(NDB)]	2 node(s)
id=2	@10.100.0.3  (mysql-8.0.22 ndb-8.0.22, Nodegroup: 0, *)
id=3	@10.100.0.4  (mysql-8.0.22 ndb-8.0.22, Nodegroup: 0)

[ndb_mgmd(MGM)]	1 node(s)
id=1	@10.100.0.2  (mysql-8.0.22 ndb-8.0.22)

[mysqld(API)]	2 node(s)
id=4	@10.100.0.10  (mysql-8.0.22 ndb-8.0.22)
id=5	@10.100.0.11  (mysql-8.0.22 ndb-8.0.22)

ndb_mgm>

Caso os nodes não estejam ativos, execute o comando abaixo para reiniciar os nodes.

$ docker start management1 ndb1 ndb2 mysql1 mysql2

Para apresentar o conceito de replicação vamos criar o database northwind no node 1 e mostrar o resultado da replicação. Antes de executar, veja os banco de dados que temos nos nodes SQL.

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| bank               |
| information_schema |
| mysql              |
| ndbinfo            |
| performance_schema |
| sys                |
+--------------------+
6 rows in set (0.01 sec)

Agora vamos acessar o 1° node SQL (docker exec -it <node_name> mysql -uroot -p).

$ docker exec -it mysql1 mysql -uroot -p

Crie o banco de dados do nosso estudo de caso.

mysql> create database northwind;
Query OK, 1 row affected (0.38 sec)

Acessando o 2° node SQL é possível confirmar que o comando foi replicado.

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| bank               |
| information_schema |
| mysql              |
| ndbinfo            |
| northwind          |
| performance_schema |
| sys                |
+--------------------+
7 rows in set (0.01 sec)
  1. Failover automático - O Mysql Cluster detecta automaticamente as falhas e faz o failover automático para os demais nós disponíveis do cluster sem interromper o serviço ao usuário.

Para estes testes vamos interromper 1 nó de dado e 1 nó SQL.

$ docker stop mysql1 ndb2

Tente acessar o 1° node SQL.

$ docker exec -it mysql1 mysql -uroot -p

O resultado será:

Error response from daemon: Container 56887df6ca9b1a3da24043b004fa1be4500b6e09dd078a522a54f3daed08cb31 is not running

Vamos verificar o status do cluster novamente.

ndb_mgm> show

Veja o resultado do comando. Note que temos 2 nodes que não estão sendo executados no momento e que foram detectados automaticamente no console de gerenciamento do cluster.

Cluster Configuration
---------------------
[ndbd(NDB)]	2 node(s)
id=2	@10.100.0.3  (mysql-8.0.22 ndb-8.0.22, Nodegroup: 0, *)
id=3 (not connected, accepting connect from 10.100.0.4)

[ndb_mgmd(MGM)]	1 node(s)
id=1	@10.100.0.2  (mysql-8.0.22 ndb-8.0.22)

[mysqld(API)]	2 node(s)
id=4 (not connected, accepting connect from 10.100.0.10)
id=5	@10.100.0.11  (mysql-8.0.22 ndb-8.0.22)

ndb_mgm>
  1. Autocorreção - Quando um node que possue os dados replicados fica indisponível é importante garantir que antes de reingressar no cluster esteja com os dados atualizados. No caso do MySQL Cluster faz este trabalho com transparência sem a necessidade de intervenção manual dos usuários.

É importante lembrar que no momento temos 1 node de dados e 1 node SQL fora de operação. Para provar o conceito de autocorreção vamos criar as tabelas e inserir dados no banco de dados northwind usando o 2° node SQL do cluster.

Acesse o 2° node SQL.

$ docker exec -it mysql2 mysql -uroot -p

Acesse o banco de dados northwind.

mysql> use northwind

Execute os comandos de create para criar as tabelas:

Importante: Para utilizar os recursos do MySQL Cluster todas as tabelas devem obrigatoriamente ter o ENGINE=NDBCLUSTER.

Execute os comandos de insert para popular as tabelas categories, suppliers e products:

Agora vamos reiniciar o node de dados e SQL que estão fora de operação.

$ docker start mysql1 ndb2

Se a sua console já esteja aberta, aguarde a exibição da mensagem abaixo.

ndb_mgm> Node 3: Started (version 8.0.22)

Caso contrário, verifique o status executando comando show na console de gerenciamento do cluster.

ndb_mgm> show
Cluster Configuration
---------------------
[ndbd(NDB)]	2 node(s)
id=2	@10.100.0.3  (mysql-8.0.22 ndb-8.0.22, Nodegroup: 0, *)
id=3	@10.100.0.4  (mysql-8.0.22 ndb-8.0.22, Nodegroup: 0)

[ndb_mgmd(MGM)]	1 node(s)
id=1	@10.100.0.2  (mysql-8.0.22 ndb-8.0.22)

[mysqld(API)]	2 node(s)
id=4	@10.100.0.10  (mysql-8.0.22 ndb-8.0.22)
id=5	@10.100.0.11  (mysql-8.0.22 ndb-8.0.22)

Chegou o momento de acessar o 1° node SQL e confirmar a autocorreção do node com os dados replicados.

$ docker exec -it mysql1 mysql -uroot -p

Veja o resultado das tabelas criadas e os dados inseridos com os comandos listados abaixo.

mysql> use northwind;

Liste as tabelas replicadas para o 1° node SQL.

mysql> show tables;

O retorno deve ser:

+------------------------+
| Tables_in_northwind    |
+------------------------+
| categories             |
| customer_customer_demo |
| customer_demographics  |
| customers              |
| employee_territories   |
| employees              |
| order_details          |
| orders                 |
| products               |
| region                 |
| shippers               |
| suppliers              |
| territories            |
| us_states              |
+------------------------+
14 rows in set (0.00 sec)

mysql>

Agora confirme se os dados inseridos foram replicados.

mysql> select count(*) from categories;

Retorno:

+----------+
| count(*) |
+----------+
|        8 |
+----------+
1 row in set (0.00 sec)
mysql> select count(*) from suppliers;

Retorno:

+----------+
| count(*) |
+----------+
|       29 |
+----------+
1 row in set (0.00 sec)
mysql> select count(*) from products;

Retorno:

+----------+
| count(*) |
+----------+
|       77 |
+----------+
1 row in set (0.00 sec)

5.2. CockroachDB

A replicação, distribuição, rebalanceamento e resiliência automáticos são pontos fortes do CockroachDB para garantir um alto nível de disponibilidade. Vamos ver alguns conceitos na prática:

Importante lembrar que temos 3 nodes disponíveis para os nossos testes.

  1. Replicação - Utiliza a replicação síncrona e requer que todas as gravações se propaguem para um quorum de cópias dos dados antes de serem consideradas confirmadas. Para confirmar os nodes existentes execute o comando abaixo.
$ docker ps

O resultado deve ser similar ao resultado mostrado.

CONTAINER ID   IMAGE                           COMMAND                  CREATED       STATUS          PORTS                                              NAMES
e9db89e8f36f   cockroachdb/cockroach:v20.2.2   "/cockroach/cockroac…"   3 weeks ago   Up 5 seconds    8080/tcp, 26257/tcp                                roach3
8dc3754dadb1   cockroachdb/cockroach:v20.2.2   "/cockroach/cockroac…"   3 weeks ago   Up 7 seconds    8080/tcp, 26257/tcp                                roach2
44ce3d718ba7   cockroachdb/cockroach:v20.2.2   "/cockroach/cockroac…"   3 weeks ago   Up 11 seconds   0.0.0.0:8080->8080/tcp, 0.0.0.0:26257->26257/tcp   roach1

Caso os nodes não estejam ativos, execute o comando abaixo para reiniciar os nodes.

$ docker start roach1 roach2 roach3

Para apresentar o conceito de replicação vamos criar o database northwind no node 1 e mostrar o resultado da replicação. Antes de executar, veja os bancos de dados que temos nos nodes SQL.

  database_name | owner
----------------+--------
  bank          | root
  defaultdb     | root
  postgres      | root
  system        | node
(4 rows)

Agora vamos acessar o 1° node SQL (docker exec -it <node_name> ./cockroach sql --insecure).

$ docker exec -it roach1 ./cockroach sql --insecure

Crie o banco de dados do nosso estudo de caso.

root@:26257/defaultdb> create database northwind;
CREATE DATABASE

Time: 513ms total (execution 512ms / network 1ms)

Acessando o 2° e o 3° node SQL é possível confirmar que o comando foi replicado.

root@:26257/defaultdb> show databases;
  database_name | owner
----------------+--------
  bank          | root
  defaultdb     | root
  northwind     | root
  postgres      | root
  system        | node
(5 rows)

Time: 4ms total (execution 3ms / network 1ms)
  1. Failover automático - O CockroachDB também consegue detectar automaticamente a indisponibilidade de um node e manter o serviço ao usuário ativo. Para estes testes vamos interromper o 2° node.
$ docker stop roach1

Tente acessar o 1° node.

$ docker exec -it roach1 ./cockroach sql --insecure

O resultado será:

Error response from daemon: Container 44ce3d718ba741e88c660a1747a862d5c322e0055e5ec8b3434fd6cf71832d92 is not running

Vamos verificar o status do cluster novamente.

$ docker ps

O resultado deve ser similar ao exibido abaixo.

CONTAINER ID   IMAGE                           COMMAND                  CREATED       STATUS              PORTS                                              NAMES
e9db89e8f36f   cockroachdb/cockroach:v20.2.2   "/cockroach/cockroac…"   3 weeks ago   Up 36 minutes       8080/tcp, 26257/tcp                                roach3
44ce3d718ba7   cockroachdb/cockroach:v20.2.2   "/cockroach/cockroac…"   3 weeks ago   Up About a minute   0.0.0.0:8080->8080/tcp, 0.0.0.0:26257->26257/tcp   roach1

Outra maneira de verificar o status do cluster é acessando o localhost. Veja o resultado:


Figura 9: Node status. Fonte: Gerado pelo autor

  1. Autocorreção - No CockroachDB a resiliência automática é reponsável por garantir que um node que estava inoperante só reingresse no cluster após a atualização dos dados. Todo este processo é tranparente e não necessita de intervenção manual.

É importante lembrar que no momento temos 2° node fora de operação. Para provar o conceito de autocorreção vamos criar as tabelas e inserir dados no banco de dados northwind usando o 3° node SQL do cluster.

Acesse o 3° node SQL.

$ docker exec -it roach3 ./cockroach sql --insecure

Acesse o banco de dados northwind.

root@:26257/northwind> use northwind;

Execute os comandos de create para criar as tabelas:

Execute os comandos de insert para popular as tabelas categories, suppliers e products:

Agora vamos reiniciar o 2° node que está fora de operação.

$ docker start roach2

Execute o comando abaixo para confirmar o status dos nodes.

$ docker start roach2

Verifique se o 2° node já está em operação novamente.

CONTAINER ID   IMAGE                           COMMAND                  CREATED       STATUS             PORTS                                              NAMES
e9db89e8f36f   cockroachdb/cockroach:v20.2.2   "/cockroach/cockroac…"   3 weeks ago   Up About an hour   8080/tcp, 26257/tcp                                roach3
8dc3754dadb1   cockroachdb/cockroach:v20.2.2   "/cockroach/cockroac…"   3 weeks ago   Up 2 minutes       8080/tcp, 26257/tcp                                roach2
44ce3d718ba7   cockroachdb/cockroach:v20.2.2   "/cockroach/cockroac…"   3 weeks ago   Up 28 minutes      0.0.0.0:8080->8080/tcp, 0.0.0.0:26257->26257/tcp   roach1

Chegou o momento de acessar o 2° node e confirmar a autocorreção do node com os dados replicados.

$ docker exec -it roach2 ./cockroach sql --insecure

Veja o resultado das tabelas criadas e os dados inseridos com os comandos listados abaixo.

root@:26257/defaultdb> use northwind;

Liste as tabelas replicadas para o 2° node.

root@:26257/northwind> show tables;

O retorno deve ser:

  schema_name |       table_name       | type  | owner | estimated_row_count
--------------+------------------------+-------+-------+----------------------
  public      | categories             | table | root  |                   0
  public      | customer_customer_demo | table | root  |                   0
  public      | customer_demographics  | table | root  |                   0
  public      | customers              | table | root  |                   0
  public      | employee_territories   | table | root  |                   0
  public      | employees              | table | root  |                   0
  public      | order_details          | table | root  |                   0
  public      | orders                 | table | root  |                   0
  public      | products               | table | root  |                   0
  public      | region                 | table | root  |                   0
  public      | shippers               | table | root  |                   0
  public      | suppliers              | table | root  |                   0
  public      | territories            | table | root  |                   0
  public      | us_states              | table | root  |                   0
(14 rows)

Time: 150ms total (execution 149ms / network 1ms)

Agora confirme se os dados inseridos foram replicados.

root@:26257/northwind> select count(*) from categories;

Retorno:

  count
---------
      8
(1 row)
root@:26257/northwind> select count(*) from suppliers;

Retorno:

  count
---------
     29
(1 row)
root@:26257/northwind> select count(*) from products;

Retorno:

  count
---------
     77
(1 row)

Voltar ao índice

6. Benchmark - MySQL vs CockroachDB

Benchmarks provêm um método de comparação da performance de vários subsistemas dentre as diferentes arquiteturas de chips e sistemas. Benchmarking é útil para o entendimento de como o gerenciador de banco de dados responde sob a variação de condições. Pode-se criar cenários que testam o tratamento de deadlock, performance dos utilitários, diferentes métodos de carregar dados, características da taxa de transição quando mais usuários são adicionados e ainda o efeito na aplicação usando uma nova versão do produto [20].

Para este estudo de caso vamos utilizar um teste prático de simultaneidade de operações publicado no github [5]. Caso tenha o MySQL e CockroachDB é possível reproduzir os mesmos testes baixando os scripts disponibilizados no repositório. Acompanhe os resultados obtidos:

  • 10 conexões simultâneas. O resultado é o total de segundos necessário para finalizar todas as operações.
Teste MySQL CockroachDB
10x Insert 0.11 0.57
100x Insert 1.15 5.54
10x Select 0.05 0.07
100x Select 2.30 4.06
10x Update 0.10 0.540
100x Update 1.14 5.55
  • 100 conexões simultâneas. O resultado é o total de segundos necessário para finalizar todas as operações.
Teste MySQL CockroachDB
10x Insert 0.21 2.68
100x Insert 2.14 26.18
10x Select 0.88 3.86
100x Select 84.86 342.15
10x Update 0.25 2.99
100x Update 2.13 26.55

Conforme o teste de simultaneidade apresentado acima o MySQL foi superior ao CockroachDB em todos as operações independente de ter 10 ou 100 conexões simultâneas.

O desempenho é algo muito complicado de medir em um banco de dados. O desempenho do CockroachDB certamente é afetado por seu modelo de consistência. Em particular, CockroachDB lida com transações usando isolamento serializável e grava usando replicação de consenso.

Voltar ao índice

7. Conclusão

Ao longo deste tutorial foi possível acompanhar todo o processo para prova do conceito de disponibilidade do MySQL Cluster e CockroachDB. Foi apresentado os seguintes processos:

  1. Instalação
  2. Configuração
  3. Criação do banco de dados
  4. Criação das tabelas
  5. Inclusão de registros nas tabelas
  6. Prova do conceito de disponibilidade
  7. Benchmark

Com o ambiente criado foi realizado os mesmos tipos de testes para verificar o comportamento de cada banco de dados em particular. Na seção de (Alta Disponibilidade) temos os principais conceitos que o MySQL Cluster e CockroachDB utilizam para garantir um alto nível de disponibilidade, mas nos testes práticos o foco foi:

  1. Replicação
  2. Failover automático
  3. Autocorreção

Foi respeitado a recomendação da documentação oficial de cada banco de dados para ter no mínimo de três computadores (3 nós) para executar um cluster viável e com isso aproveitar a as vantagens dos recursos de replicação, distribuição, rebalanceamento e resiliência automáticos.

Em resumo os banco de dados escolhidos atenderam o conceito de disponibilidade a partir da arquitetura proposta e nos testes de simultaneidade o MySQL foi muito superior ao CockroachDB.

Voltar ao índice

8. Referências Bibliográficas

  1. MySQL. MySQL CLUSTER, 2020a. Acesso em 14 out 2020 às 19h20m.

2. MySQL. MySQL CLUSTER, 2020b. Acesso em 17 out 2020 às 11h00m.

3. MySQL. Appendix A MySQL 5.7 FAQ: NDB Cluster, 2020c. Acesso em 17 out 2020 às 18h15m.

4. Cockroach Labs. What is CockroachDB 2020a, 2020a. Acesso em 16 out 2020 às 17h30m.

5. Caleb Lloyd. Concurrency Benchmark Results, 2020a. Acesso em 30 dez 2020 às 10h30m.

6. Cockroach Labs. Architecture Overview, 2020b. Acesso em 17 out 2020 às 15h30m.

7. Cockroach Labs. Start a Cluster in Docker, 2020c. Acesso em 04 dez 2020 às 19h10m.

8. YugabyteDB. YugabyteDB, 2020a. Acesso em 29 dez 2020 às 10h15m.

9. Docker. Docker, 2020a. Acesso em 29 dez 2020 às 10h50m.

10. Digitalocean. Digitalocean, 2020a. Acesso em 29 dez 2020 às 11h00m.

11. Medium. Medium, 2020a. Acesso em 30 dez 2020 às 13h45m.

12. GithubGist. GithubGist, 2020a. Acesso em 30 dez 2020 às 14h05m.

13. Krco, Srdjan, et al. Comic book. The internet of things, 2012, p. 15. Acesso em 21 dez 2020 às 21h10m.

14. Dias, Renata Rapim de Freitas. Internet das Coisas sem Mistérios: Uma nova inteligência para os negócios. São Paulo: Netpress Books, 2016.

15. Pavlo, A. and Aslett. What’s really new with newsql? SIGMOD Rec., 45(2), 2016.

16. YUAN, L.-Y.; WU, L.; YOU, J.-H.; CHI, Y. A demonstration of rubato db: A highly scalable newsql database system for oltp and big data applications. In: ACM. Proceedings of the 2015 ACM SIGMOD International Conference on Management of Data. [S.l.], 2015. p. 907–912.

17. KAUR, K.; SACHDEVA, M. Performance evaluation of newsql databases. In: IEEE. Inventive Systems and Control (ICISC), 2017 International Conference on. [S.l.], 2017. p. 1–5.

18. STONEBRAKER, Michael, CATTELL, Rick. 10 Rules for Scalable Performance in ‘Simple Operation’ Datastores. Communications Of The Acm, v. 54, n. 6, p. 72-80, jun. 2011.

19. SILBERSCHATZ, A.; KORTH, H. F.; SUDARSHAN, S. Sistema de banco de dados. 5 ed. Rio de Janeiro: Elsevier, 2006. p. 300.

20. Wikipédia. Benchmark (computação), 2020a. Acesso em 03 dec 2020 às 19h10m.

21. KNOB, Ronan R. et al. Uma Análise de Soluções NewSQL. In: XV Escola Regional de Banco de Dados (ERBD), 2019, Chapecó. Porto Alegre: Sociedade Brasileira de Computação, p. 21 - 30. ISSN 2595-413X.

newsql-disponibilidade's People

Contributors

ailtonmorais avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.