Database Sharding - C-Suite
Este documento descreve a estratégia de Database Sharding para preparar o ecossistema C-Suite para crescimento.
Visão Geral
Database Sharding divide dados em múltiplos bancos de dados menores (shards) para melhorar performance e escalabilidade.
Estratégias de Sharding
1. Sharding por Organização
Vantagens:
- Isolamento de dados por cliente
- Fácil backup/restore por organização
- Compliance (LGPD/GDPR)
Desvantagens:
- Desbalanceamento se organizações têm tamanhos muito diferentes
- Complexidade de queries cross-org
Implementação:
def get_shard_for_org(org_id: int) -> str:
"""Determine shard for organization"""
# Simple modulo sharding
num_shards = int(os.getenv("DB_NUM_SHARDS", "4"))
shard_num = org_id % num_shards
return f"csuite_shard_{shard_num}"
2. Sharding por Região
Vantagens:
- Reduz latência geográfica
- Compliance regional
- Disaster recovery por região
Desvantagens:
- Complexidade de sincronização
- Queries cross-region
Implementação:
def get_shard_for_region(region: str) -> str:
"""Determine shard for region"""
region_map = {
"us-east": "csuite_shard_us",
"sa-east": "csuite_shard_sa",
"eu-west": "csuite_shard_eu"
}
return region_map.get(region, "csuite_shard_default")
3. Sharding por Hash
Vantagens:
- Distribuição uniforme
- Balanceamento automático
Desvantagens:
- Dificulta queries por range
- Migração complexa
Implementação
Módulo de Sharding
# common/common_sharding.py (exemplo conceitual)
import os
from typing import Optional
from common.core_config import get_db_config
class ShardManager:
"""Manages database shards"""
def __init__(self):
self.sharding_strategy = os.getenv("SHARDING_STRATEGY", "org_id")
self.num_shards = int(os.getenv("NUM_SHARDS", "4"))
def get_shard(self, org_id: int) -> str:
"""Get shard name for organization"""
if self.sharding_strategy == "org_id":
shard_num = org_id % self.num_shards
return f"csuite_shard_{shard_num}"
# Other strategies...
def get_shard_config(self, shard_name: str):
"""Get database config for shard"""
# Load config for specific shard
return get_db_config(shard_name)
Atualizar common_db_pool
# Adicionar suporte a shards em common_db_pool.py
def get_sharded_db_engine(org_id: int, database: str = "csuite"):
"""Get engine for sharded database"""
shard_manager = ShardManager()
shard_name = shard_manager.get_shard(org_id)
return get_db_engine(shard_name)
Migração
Fase 1: Preparação
- Criar shards
- Configurar routing
- Testar em staging
Fase 2: Migração Gradual
- Migrar novas organizações para shards
- Migrar organizações existentes gradualmente
- Monitorar performance
Fase 3: Completa
- Todos os dados em shards
- Remover banco principal
- Otimizar queries
Queries Cross-Shard
Agregações
def aggregate_across_shards(query_func):
"""Execute query across all shards"""
results = []
for shard in shards:
result = query_func(shard)
results.append(result)
return aggregate(results)
Joins
Evitar joins cross-shard. Preferir:
- Denormalização
- Materialized views
- Separate queries
Monitoramento
Métricas
- Tamanho de cada shard
- Queries por shard
- Balanceamento de carga
- Latência por shard
Alertas
- Shard desbalanceado
- Shard próximo do limite
- Queries cross-shard lentas
Best Practices
- Escolha estratégia apropriada: Baseada em padrões de acesso
- Evite queries cross-shard: Design para evitar
- Monitore balanceamento: Ajuste conforme necessário
- Planeje migração: Gradual e testada
- Documente routing: Como dados são roteados