Alta Disponibilidade e Resiliência em Bancos de Dados com MaxScale

Aplicativos críticos para a missão requerem alta disponibilidade. O objetivo da alta disponibilidade é fornecer aos usuários acesso consistente a serviços ou recursos, minimizando as chances de interrupção. Failover automático é um mecanismo específico utilizado para alcançar alta disponibilidade. Ele envolve a detecção automática de falha em um componente do sistema (como um servidor, rede ou banco de dados) e a troca imediata das operações para um componente reserva sem intervenção humana. Isso aumenta a resiliência.

MariaDB MaxScale é um proxy de banco de dados que inclui recursos para alta disponibilidade. Neste artigo, mostrarei como você pode experimentá-lo com um aplicativo simulador de loja online implementado em Java e Svelte.

Arquitetura

O diagrama a seguir mostra a arquitetura do aplicativo de demonstração:


A web application developed with JavaScript and the Svelte framework makes HTTP requests to a Java backend. The backend answers with server-sent events that the frontend uses to update the user interface on the browser.

O backend é implementado com Spring Boot e se conecta a um cluster de MariaDB usando R2DBC (reativo). A lógica do backend é, em suma, uma simulação de leituras e gravações em um banco de dados de loja online. A simulação é parametrizada e o usuário pode ajustar:

  • Visitas de produtos por minuto: Quantas leituras no banco de dados por minuto.
  • Pedidos por minuto: Quantas gravações no banco de dados por minuto.
  • Produtos por pedido: Amplificação de escrita.
  • Tempo limite em milissegundos: Quantos segundos até que uma solicitação à base de dados seja considerada falha.

O cluster de banco de dados é front-end por um proxy de banco de dados chamado MaxScale. Este proxy faz com que o cluster pareça um único banco de dados lógico para o backend Java. MaxScale também realiza divisão de leitura/escrita (enviando gravações para o servidor primário MariaDB e leituras para réplicas), bem como balanceamento de carga de leituras entre servidores de réplica usando um algoritmo configurável. Dados são automaticamente replicados do primário para os servidores de banco de dados réplica.

Construção das Imagens Docker a Partir da Fonte

I have prepared custom Docker images for every component in the simulator. You can either build the images from the source (optional) or use the already built and published images from Docker Hub. If you decide to build the images yourself, you can find the source code on GitHub:

  • Implantações MariaDB: Imagens personalizadas para implantação fácil de topologias MariaDB replicadas com MaxScale. NÃO USE ESTES IMAGENS EM PRODUÇÃO! Estas imagens são adequadas apenas para aplicações de demonstração. Use as imagens oficiais MariaDB Docker para implantações em produção.
  • Aplicação Backend: A aplicação backend que se conecta ao cluster de banco de dados.
  • Aplicação Frontend: A aplicação frontend que faz solicitações de configuração de simulação ao backend e recebe eventos para mostrar o resultado da simulação.

Cada repositório possui Dockerfiles que você pode usar para construir suas próprias imagens Docker. Por exemplo, para construir a imagem da aplicação backend, execute:

Shell

 

docker build --tag alejandrodu/online-store-simulator-java-backend .

Executando a Simulação

Todos os serviços podem ser iniciados usando o seguinte arquivo Docker Compose (docker-compose.yml):

YAML

 

version: "3.9"
services:
  server-1:
    container_name: server-1
    image: alejandrodu/mariadb
    ports:
      - "3306:3306"
    environment:
      - MARIADB_CREATE_DATABASE=demo
      - MARIADB_CREATE_USER=user:Password123!
      - MARIADB_CREATE_REPLICATION_USER=replication_user:ReplicationPassword123!
      - MARIADB_CREATE_MAXSCALE_USER=maxscale_user:MaxScalePassword123!

  server-2:
    container_name: server-2
    image: alejandrodu/mariadb
    ports:
      - "3307:3306"
    environment:
      - MARIADB_REPLICATE_FROM=replication_user:ReplicationPassword123!@server-1:3306

  server-3:
    container_name: server-3
    image: alejandrodu/mariadb
    ports:
      - "3308:3306"
    environment:
      - MARIADB_REPLICATE_FROM=replication_user:ReplicationPassword123!@server-1:3306

  maxscale:
    container_name: maxscale
    image: alejandrodu/mariadb-maxscale
    command: --admin_host 0.0.0.0 --admin_secure_gui false
    ports:
      - "4000:4000"
      - "8989:8989"
      - "27017:27017"
    environment:
      - MAXSCALE_USER=maxscale_user:MaxScalePassword123!
      - MARIADB_HOST_1=server-1 3306
      - MARIADB_HOST_2=server-2 3306
      - MARIADB_HOST_3=server-3 3306
    healthcheck:
      test: ["CMD", "maxctrl", "list", "servers"]
      interval: 5s
      timeout: 10s
      retries: 5

  java-backend:
    container_name: java-backend
    image: alejandrodu/online-store-simulator-java-backend
    ports:
      - "8080:8080"
    environment:
    - spring.r2dbc.url=r2dbc:mariadb://maxscale:4000/demo
    - spring.r2dbc.username=user
    - spring.r2dbc.password=Password123!
    - spring.liquibase.url=jdbc:mariadb://maxscale:4000/demo
    - spring.liquibase.user=user
    - spring.liquibase.password=Password123!
    depends_on:
      maxscale:
        condition: service_healthy

  svelte-frontend:
    container_name: svelte-fronted
    image: alejandrodu/online-store-simulator-svelte-frontend
    ports:
      - "5173:80"
    environment:
      - BACKEND_URL=http://java-backend:8080

Vá para o diretório no qual o arquivo Docker Compose está, e inicie os serviços em modo desanexado da seguinte forma:

Shell

 

docker compose up -d

Configurando MaxScale

Antes de iniciar a simulação, configure MaxScale para replay de transações. Além disso, ajuste os tempos limite para tornar a simulação mais interessante.

Acesse http://localhost:8989/ e faça login na interface usando:

  • Nome de Usuário:admin
  • Senha:mariadb

Você verá um painel com o estado do cluster MariaDB.


Há um servidor primário (server-1), e duas réplicas (server-2 e server-3). A replicação já está configurada de server-1 (primário) para server-2 e server-3 (réplicas). Todos os servidores devem estar funcionando.

Clique em mdb_monitor e depois no ícone lápis para habilitar a edição de parâmetros. Defina os seguintes parâmetros:

  • auto_failover (true): Isso habilita o failover automático. Quando um servidor MariaDB está inativo, o MaxScale seleciona um servidor de réplica e o reconfigura como o novo primário para que as gravações possam continuar a ocorrer.
  • auto_rejoin (true): Isso habilita o reencontro automático de servidores recuperados. Quando um servidor falho está ativo novamente, o MaxScale o detecta e o configura como um servidor de réplica disponível.
  • failcount (1): Define o número de iterações de monitor (um componente no MaxScale que verifica o status do servidor) necessárias para que um servidor esteja inativo para ativar o processo de failover. Definimos um valor de 1 para garantir que o failover comece imediatamente após a falha.
  • backend_connect_timeout (1000): Tempo limite de conexão para conexões de monitor. Definimos um valor baixo (um segundo) para ativar rapidamente o failover para esta demonstração.
  • backend_read_timeout (1000): Tempo limite de leitura para conexões de monitoramento.
  • backend_write_timeout (1000): Tempo limite de escrita para conexões de monitoramento.
  • master_failure_timeout (1000): Tempo limite de falha primária.
  • monitor_interval (1000): Frequência de monitoramento dos servidores.

ATENÇÃO: Estes valores são adequados para esta demonstração, mas provavelmente não são os melhores para ambientes de produção!

Após definir os parâmetros, clique em Concluir Edição e Confirmar.

Você também precisa ativar a reexecução de transações, que executa automaticamente transações falhas em andamento em servidores que caíram logo após uma declaração SQL ser roteada. Esta é uma funcionalidade útil para desenvolvedores de software, pois evita a necessidade de codificar casos de falha e repetição de transação.

No menu principal, clique em Painel de Controle e depois em qualquer um dos links serviço_de_roteamento_de_consulta na lista de servidores. Edite os parâmetros conforme segue:

  • transaction_replay (true): Ativa a repetição automática de transações falhas.
  • transaction_replay_retry_on_deadlock (true): Mesmo que o anterior quando ocorre um deadlock.
  • transaction_replay_retry_on_mismatch (true): Mesmo que o anterior quando ocorre uma discrepância de checksum.

Após definir os parâmetros, clique em Concluir Edição e Confirmar.

Iniciando a Simulação

Com tudo configurado, você pode começar a simulação. Navegue até http://localhost:5173/ e configure os seguintes parâmetros (espero que os nomes sejam autoexplicativos):

  • Visitas de produtos por minuto:6000
  • Pedidos por minuto:60
  • Timeout em milissegundos:8000

Mas antes de começar a simulação, você precisa criar os produtos para a loja online. Clique em Dados | Criar produtos…. Deixe os valores padrão e clique em Criar. Você deve ver a IU atualizando à medida que os produtos são criados no banco de dados.

Agora você pode finalmente clicar em Iniciar e ver a simulação em ação.


Simulando uma Falha no Servidor

Neste ponto, o servidor primário está manipulando escritas (pedidos). O que acontece se você parar esse servidor? Na linha de comando execute:

Shell

 

docker stop server-1

Dependendo de vários fatores, você pode ter alguns “visitantes decepcionados” ou até algumas “oportunidades perdidas” no simulador. Ou talvez você não tenha nenhum! Visitas de produtos (leituras) e pedidos (escritas) continuam acontecendo graças ao MaxScale. Sem failover automático, você tem que reconfigurar tudo manualmente, o que resulta em mais tempo offline e em muitos visitantes decepcionados e oportunidades perdidas!

Inicie o servidor falho:

Shell

 

docker start server-1

Vá ao Painel do MaxScale (http://localhost:8989/) e verifique que server-1 agora é uma réplica funcional.

Você pode realizar uma mudança manual para tornar servidor-1 o servidor primário novamente. Clique em monitor_mdb e, em seguida, passe o mouse sobre a seção MASTER. Clique no ícone lápis e selecione servidor-1. Clique em Trocar e verifique novamente no Painel se o novo servidor primário é servidor-1.

Conclusão

O failover automático é apenas um dos componentes em sistemas altamente disponíveis. Você pode usar um proxy de banco de dados como MaxScale para configurar failover automático, mas também outros componentes como balanceamento de carga, roteamento de consultas, reexperimentação de transações, isolamento de topologia e muito mais. Confira a documentação aqui.

Source:
https://dzone.com/articles/high-availability-and-resiliency-in-databases