MIGRAÇÕES DE BANCO DE DADOS ZERO-DOWNTIME: ORQUESTRANDO ESCRITAS DUPLAS E LEITURAS GRADUAIS COM OS CONECTORES I+1 DO USEFLAGLY

Migrações de banco de dados zero-downtime: orquestrando escritas duplas e leituras graduais com os conectores i+1 do useflagly

Compartilhar

Como migrar esquemas de dados massivos de forma totalmente segura, utilizando flags de dupla escrita e de leitura gradual com fallback automático.

Migrar bancos de dados de larga escala sem indisponibilidade é um dos maiores desafios de engenharia. A clássica abordagem offline de colocar o sistema em manutenção para rodar scripts de migração não escala em ecossistemas de alta disponibilidade. A solução definitiva é a estratégia de escrita dupla e leitura gradual (Dual-Write/Dual-Read). No entanto, gerenciar o estado dessas transições por meio de variáveis de ambiente estáticas exige deploys constantes e introduz sérios riscos de sincronismo e downtime. Com o Useflagly, você controla essa alternância dinâmica em tempo de execução sem tocar no seu pipeline de CI/CD.

A arquitetura de transição no painel do useflagly

Para mitigar riscos, dividimos a migração em fases claras utilizando o painel do Useflagly. Para fins de organização de equipe, as flags são estruturadas na hierarquia Scenario > Flow > FlowPart > Flag. Criamos o Scenario 'infra-migrations', o Flow 'db-migration-v2' e o FlowPart 'step-transitions'. Dentro desse agrupamento organizacional, residem as duas flags operacionais principais: 'db-dual-write' e 'db-read-new-schema'. Vale lembrar que essa estrutura organizacional superior serve apenas para manter seu painel limpo; toda a inteligência e as validações residem unicamente no nível da Flag.

Configuramos as validações de cada flag usando os conectores i+1 do Useflagly para clicar e direcionar a migração em lotes controlados. Na regra 0, definimos uma validação de tipo 'custom' para o campo 'tenantId' com a condição 'is_in_list'. Na regra 1, configuramos o conector como 'AND' e definimos uma validação de tipo 'percentage' com valor '10'. O parser linear O(N) do Useflagly avaliará a regra 0 e, se válida, combinará o resultado logicamente com a regra de porcentagem de forma sequencial por prioridade crescente. Isso nos permite liberar a dupla escrita e a leitura do novo banco inicialmente apenas para 10% dos usuários dentro dos tenants selecionados.

image_1.png

import { UseFlaglyClient } from '@useflagly/sdk-javascript';

const client = new UseFlaglyClient({
  token: process.env.USEFLAGLY_TOKEN || ''
});

async function handleDatabaseMigrationFlow(userId: string, tenantId: string, payload: any) {
  const env = 'PRD';
  const body = {
    identifier: userId,
    context: { tenantId }
  };

  try {
    // 1. Decidir se escreve em ambos os bancos (Dual-Write)
    const dualWriteRes = await client.validateFlag('db-dual-write', body, env);
    const shouldDualWrite = dualWriteRes.statusCode === 200 && dualWriteRes.data['db-dual-write'];

    if (shouldDualWrite) {
      await Promise.all([
        writeToLegacyDatabase(payload),
        writeToNewDatabase(payload).catch(err => {
          console.error('Falha na escrita assíncrona do novo banco:', err);
        })
      ]);
    } else {
      await writeToLegacyDatabase(payload);
    }

    // 2. Decidir se lê do banco novo (Leitura Gradual com Fallback)
    const readNewRes = await client.validateFlag('db-read-new-schema', body, env);
    const shouldReadNew = readNewRes.statusCode === 200 && readNewRes.data['db-read-new-schema'];

    if (shouldReadNew) {
      try {
        return await readFromNewDatabase(userId);
      } catch (error: any) {
        // Fallback imediato se houver qualquer oscilação de rede ou indisponibilidade
        if (error.isNetworkError || error.statusCode === 0) {
          console.warn('Erro de rede detectado no novo banco. Fallback para o legado.');
        }
        return await readFromLegacyDatabase(userId);
      }
    }

    return await readFromLegacyDatabase(userId);

  } catch (error: any) {
    if (error.isSubscriptionError) {
      console.error('Cota de requests esgotada no Useflagly. Aplicando fallback de segurança.');
    }
    return await readFromLegacyDatabase(userId);
  }
}

Infraestrutura de baixa latência e fallback resiliente

Executar validações dinâmicas a cada escrita ou leitura de banco de dados não pode adicionar latência significativa à sua aplicação. A Useflagly resolve esse gargalo hospedando sua infraestrutura principal no Google Cloud Platform (GCP) na região us-east4, garantindo rotas de rede ultracurtas e tempos de resposta sub-milissegundo para os principais servidores de aplicação modernos. Além disso, o servidor conta com um sistema híbrido de cache duplo: a camada L1 em memória de processo (LRU de até 500 chaves com TTL de 10 minutos) e a camada L2 distribuída via Redis (TTL de 2000 segundos). Essa arquitetura robusta garante respostas em frações de milissegundo diretamente da borda, blindando seus microsserviços sem onerar o seu banco de dados transacional.

image_2.png

⚠️ ⚠️ Alerta de Missão Crítica: A migração zero-downtime só é concluída com segurança quando os dados de escrita estão 100% consistentes em ambos os bancos. Use as flags do Useflagly para manter o dual-write ativo até que todos os dados históricos sejam sincronizados e validados no novo esquema, antes de virar a chave da leitura gradual para 100% dos usuários.

🚩 useflagly.com.br

Compartilhar

Posts relacionados

Migrações de banco de dados zero-downtime: orquestrando escritas duplas e leituras graduais com os conectores i+1 do useflagly | Arquitetura | Blog Operação IA