Configuração e Teste Prático de Estratégia de Sharding Horizontal com ShardingSphere

Conceitos Fundamentais

O sharding horizontal de tabelas envolve distribuir os dados de uma única tabela por múltiplas tabelas dentro do mesmo banco de dados, onde cada tabela contém apenas uma parte dos dados totais. A essência é particionar uma tabela grande em N tabelas menores, todas com a mesma estrutura mas dados distintos; a combinação dos dados de todas as tabelas representa o conjunto completo. Isso é aplicado a tabelas com volumes massivos de dados, como tabelas de pedidos, utilizando regras como RANGE ou HASH modulo para divisão. Porém, como as tabelas permanecem no mesmo banco, ainda existem limitações de I/O em operações de banco único, sendo a principal vantagem a redução do tempo de bloqueio de tabelas durante operações DDL, como adicionar colunas.

Este método é ideal em cenários onde uma tabela alcança milhões de registros, resultando em consultas lentas que necessitam otimização para diminuir tempos de resposta. Exemplos incluem registros de envio de microblogs, mensagens de aplicativos de mensagens, ou logs, particionados por ID crescente ou tempo. Dados de atividades como check-ins em sites também se beneficiam da divisão por tempo.

Implementação Prática

Adição de Dependências

<dependency>
    <groupId>org.apache.shardingsphere</groupId>
    <artifactId>sharding-jdbc-spring-boot-starter</artifactId>
    <version>4.1.1</version>
</dependency>

Configuração da Aplicação

# Fonte de dados principal para o banco de dados - Versão: MySQL 8
shardingsphere:
  datasource:
    primary:
      connectionTimeout: 30000
      driver-class-name: com.mysql.cj.jdbc.Driver
      idleTimeout: 60000
      jdbc-url: jdbc:mysql://[host]:3306/[nome_banco]?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=America/Sao_Paulo&allowPublicKeyRetrieval=true
      maintenanceInterval: 30000
      maxLifetime: 1800000
      maxPoolSize: 50
      minPoolSize: 50
      password: [senha]
      type: com.zaxxer.hikari.HikariDataSource
      username: [usuario]
    names: primary

  props:
    sql:
      show: true

  sharding:
    tables:
      pedido_tabela:
        actual-data-nodes: primary.pedido_$->{0..1}
        table-strategy:
          inline:
            algorithm-expression: pedido_$->{campo_modulo % 2}
            sharding-column: campo_modulo
        key-generator:
          column: id
          props:
            worker:
              id: 1
          type: SNOWFLAKE

Teste de Inserção

@Test
public void testarInsercaoPedidos() {
    Random gerador = new Random();
    for (int contador = 0; contador < 10; contador++) {
        PedidoEntidade pedido = new PedidoEntidade();
        pedido.setCodigoCliente((long) gerador.nextInt(500));
        pedidoRepositorio.salvar(pedido);
    }
}

Aálise dos Resultados

Ao executar o teste, registros com o campo codigoCliente par são direcionados para a tabela pedido_0, enquanto aqueles com valor ímpar vão para pedido_1. Isso demonstra a implementação bem-sucedida do sharding horizontal, otimizando o desempenho ao dividir a carga de dados.

Tags: ShardingSphere sharding-horizontal MySQL spring-boot HikariCP

Publicado em 6-8 23:41 por Thomas