Pular para o conteúdo

Arquitetura real · Sênior

Mercado Envios: do MySQL único para a América Latina a células

É o melhor caso BR para senior. Como rotear sem chave de célula na API: broadcast para entidades legadas (404 de todas as células = "não existe") e faixas de ID por célula para entidades novas. p95/p99 caíram cerca de 70%.

17 min de leitura · Fonte: Mercado Livre · Conteúdo revisado em 23 de outubro de 2026

Resposta curta

É o melhor caso BR para senior. Como rotear sem chave de célula na API: broadcast para entidades legadas (404 de todas as células = "não existe") e faixas de ID por célula para entidades novas. p95/p99 caíram cerca de 70%.

01 · CONTEXTO

Um banco só para a região inteira

O sistema de estoque do Mercado Envíos, do Mercado Libre, rodava sobre o que a empresa descreve como a segunda maior instância MySQL da casa. Toda entrada, saída, reserva e movimentação logística dependia de um único banco que não conseguia mais escalar.

A arquitetura inicial era simples: vários serviços de estoque ligados a um único cluster MySQL. Esse cluster cuidava da disponibilidade de estoque por centro de fulfillment, das reservas para envios de fulfillment e das movimentações logísticas entre armazéns, vendedores e destinos.

  1. Os clientes da API chamam os serviços de estoque.

    Diagrama da arquitetura: Estoque do Mercado Envíos: banco único
    CLClientes da API de estoque
    CPServiços de estoque
    DBMySQL único da região
  2. Todos os serviços de estoque convergem para um único cluster MySQL.

    Diagrama da arquitetura: Estoque do Mercado Envíos: banco único
    CLClientes da API de estoque
    CPServiços de estoque
    DBMySQL único da regiãoponto único
  3. Com esse desenho, uma única falha podia afetar operações em vários países da região.

    Diagrama da arquitetura: Estoque do Mercado Envíos: banco único
    CLClientes da API de estoque
    CPServiços de estoque
    DBMySQL único da regiãorisco regional

Segundo o post, a latência de operações críticas vinha subindo, e a pergunta passou a ser o que fazer quando escalar na vertical deixa de ser opção.

02 · POR QUE CÉLULAS

Sem flavor maior e sem microsserviços por reflexo

Por anos a escala vertical resolveu os problemas; no fim, não havia mais flavors maiores disponíveis e depender de uma única instância MySQL virou risco sistêmico.

Em vez de dividir tudo em microsserviços, a equipe pesou que multiplicar saltos de rede ou pontos de falha tornaria mais difíceis exigências do domínio como latência extremamente baixa mesmo sob pico e forte consistência de estoque. Por isso mantiveram um monólito intencional no núcleo do sistema.

AntesDepois
BancoVários serviços ligados a um único cluster MySQLCada célula com banco próprio
Alcance de uma falhaUma única falha podia afetar operações em vários paísesUm problema em uma célula fica nessa célula
Como cresceEscalar um banco giganteEscalar só as células que precisam

03 · A ARQUITETURA

Células por grupo de países, escrita separada de leitura

A arquitetura em células é conceitualmente parecida com as divisórias estanques de um navio: cada célula opera de forma autônoma, com computação, banco e tráfego próprios. Se uma célula falha, as demais continuam atendendo requisições. Esse isolamento reduz o raio de impacto.

O modelo introduziu duas camadas de segregação. Na primeira, os países foram agrupados em três células. Na segunda, os fluxos foram divididos: escritas estritamente consistentes e críticas para o negócio de um lado, leituras mais flexíveis, apoiadas em réplicas e cache, de outro.

  1. Os clientes chegam a uma camada de tráfego que fica na frente das células.

    Diagrama da arquitetura: Estoque do Mercado Envíos: células
    CLClientes da API de estoque
    NWCamada de tráfego
    CPServiço da célula A
    DBBanco da célula A
    CPServiço da célula B
    DBBanco da célula B
    CPServiço da célula C
    DBBanco da célula C
  2. A camada de tráfego é ligada ao serviço de cada célula.

    Diagrama da arquitetura: Estoque do Mercado Envíos: células
    CLClientes da API de estoque
    NWCamada de tráfego
    CPServiço da célula A
    DBBanco da célula A
    CPServiço da célula B
    DBBanco da célula B
    CPServiço da célula C
    DBBanco da célula C
  3. Cada célula tem serviço e banco próprios.

    Diagrama da arquitetura: Estoque do Mercado Envíos: células
    CLClientes da API de estoque
    NWCamada de tráfego
    CPServiço da célula A
    DBBanco da célula A
    CPServiço da célula B
    DBBanco da célula B
    CPServiço da célula C
    DBBanco da célula C
  4. Se uma célula falhar, as demais continuam atendendo requisições.

    Diagrama da arquitetura: Estoque do Mercado Envíos: células
    CLClientes da API de estoque
    NWCamada de tráfego
    CPServiço da célula Ase falhar
    DBBanco da célula Ase falhar
    CPServiço da célula B
    DBBanco da célula B
    CPServiço da célula C
    DBBanco da célula C

Implementar células é também um desafio operacional. A Fury, plataforma interna de desenvolvimento do Mercado Libre, permitiu criar serviços e bancos de cada célula com padrões consistentes e operar pipelines de deploy independentes por célula.

04 · ROTEAMENTO

Quando a API não tem chave de célula

Ao desenhar o roteamento, a equipe viu que várias APIs não tinham uma chave natural que identificasse a qual célula a entidade pertencia. Criar um atributo novo quebraria a compatibilidade com clientes existentes e exigiria coordenar mudanças com dezenas de equipes e serviços.

A saída foi usar duas estratégias. Para entidades legadas, um fallback de roteamento retrocompatível; para dados novos, uma estratégia determinística de IDs.

  1. O cliente faz a mesma requisição de sempre, sem mudanças.

    Diagrama da arquitetura: Estoque do Mercado Envíos: células
    CLClientes da API de estoque
    NWCamada de tráfego
    CPServiço da célula A
    DBBanco da célula A
    CPServiço da célula B
    DBBanco da célula B
    CPServiço da célula C
    DBBanco da célula C
  2. A camada de tráfego encaminha a requisição a todas as células.

    Diagrama da arquitetura: Estoque do Mercado Envíos: células
    CLClientes da API de estoque
    NWCamada de tráfego
    CPServiço da célula A
    DBBanco da célula A
    CPServiço da célula B
    DBBanco da célula B
    CPServiço da célula C
    DBBanco da célula C
  3. A célula que guarda a entidade responde.

    Diagrama da arquitetura: Estoque do Mercado Envíos: células
    CLClientes da API de estoque
    NWCamada de tráfego
    CPServiço da célula A
    DBBanco da célula A
    CPServiço da célula Btem a entidade
    DBBanco da célula B
    CPServiço da célula C
    DBBanco da célula C
  4. Se todas as células devolvem 404, o recurso realmente não existe.

    Diagrama da arquitetura: Estoque do Mercado Envíos: células
    CLClientes da API de estoque
    NWCamada de tráfego
    CPServiço da célula Asem entidade
    DBBanco da célula A
    CPServiço da célula Bsem entidade
    DBBanco da célula B
    CPServiço da célula Csem entidade
    DBBanco da célula C

05 · IDS COMO CHAVE

Faixas de ID por célula

O broadcast resolveu o problema dos registros legados, mas as entidades novas pediam roteamento determinístico. Os IDs atrapalhavam: eram públicos e parte de contratos de API antigos, eram sequenciais e gerados por uma única instância MySQL, e não tinham significado embutido. Isso trazia o risco de colisão de IDs entre células se dois primários gerassem números sobrepostos.

A solução foi dar a cada célula uma faixa exclusiva de IDs. Uma entidade nova criada numa célula recebe um ID que nunca colide com o de outra célula, os IDs mantêm o formato original e o próprio ID passa a ser a chave de roteamento.

Entidades legadasEntidades novas
Como a célula é encontradaA camada de tráfego encaminha a requisição a todas as célulasO próprio ID passa a ser a chave de roteamento
Efeito para o clienteO cliente faz a mesma requisição de sempreOs IDs mantêm o formato original
Ponto de atençãoO broadcast de requisições adiciona overheadFaixas exclusivas evitam colisão entre células

06 · MIGRAÇÃO E RESULTADO

Migrar dezenas de terabytes sem parar a logística

A equipe migrou dezenas de terabytes para três células independentes. A leitura continuou sem interrupção e as escritas foram pausadas só numa janela breve e controlada. O roteiro de cada janela era copiar o banco para a célula de destino, pausar as escritas por pouco tempo e manter as leituras no banco original.

Como a maioria dos fluxos é assíncrona, a pausa curta de escrita teve impacto mínimo nos clientes finais. Depois que a célula recebia seus dados, ela entrava no ar aos poucos: primeiro ligaram as leituras e validaram fluxos críticos, depois liberaram as escritas, protegidas contra contaminação entre células. Após a validação, o tráfego de leitura foi deslocado para a nova célula sem indisponibilidade.

  1. As escritas vão ao primário da célula, onde precisam ser estritamente consistentes.

    Diagrama da arquitetura: Dentro de uma célula: escrita e leitura
    CPServiço de estoque da célula
    DBPrimário da célula
    DBRéplica da célula
    CHCache da célula
  2. As leituras, mais flexíveis, são apoiadas em réplicas e cache.

    Diagrama da arquitetura: Dentro de uma célula: escrita e leitura
    CPServiço de estoque da célula
    DBPrimário da célula
    DBRéplica da célula
    CHCache da célula
  3. O serviço SQL totalmente gerenciado trouxe replicação com garantias de consistência abaixo de 100 ms.

    Diagrama da arquitetura: Dentro de uma célula: escrita e leitura
    CPServiço de estoque da célula
    DBPrimário da célula
    DBRéplica da célula
    CHCache da célula
  4. Com as réplicas atendendo leitura, as leituras no primário foram eliminadas.

    Diagrama da arquitetura: Dentro de uma célula: escrita e leitura
    CPServiço de estoque da célula
    DBPrimário da célula
    DBRéplica da célulaserve leitura
    CHCache da célula

Um ano após a migração, a latência p95/p99 havia caído cerca de 70%, a degradação recorrente causada pelas janelas de backup foi eliminada e a equipe passou de escalar um banco gigante a escalar só as células que precisam.

Perguntas frequentes

O que é Mercado Envios: do MySQL único para a América Latina a células?

É o melhor caso BR para senior. Como rotear sem chave de célula na API: broadcast para entidades legadas (404 de todas as células = "não existe") e faixas de ID por célula para entidades novas. p95/p99 caíram cerca de 70%.

O que o design de Mercado Envios: do MySQL único para a América Latina a células cobre?

Ele está organizado nestas seções: Um banco só para a região inteira, Sem flavor maior e sem microsserviços por reflexo, Células por grupo de países, escrita separada de leitura, Quando a API não tem chave de célula, Faixas de ID por célula e Migrar dezenas de terabytes sem parar a logística.

Quanto tempo leva Mercado Envios: do MySQL único para a América Latina a células e qual é o nível?

Leva cerca de 17 minutos para ler e tem nível Sênior.

Agora projete você mesmo

Rode este caso como uma entrevista na escola de System Design: você toma as decisões, o tutor as questiona e você vê a nota do seu desenho.