Pular para o conteúdo

Incidente · Sênior

GitHub: 43 segundos de partição, 24 h degradado

Uma partição curta disparou failover entre data centers e deixou escritas divergentes para conciliar.

15 min de leitura · Incidente em 2018-10-21, durou ~24 h · Fonte: GitHub · Conteúdo revisado em 22 de outubro de 2026

Resposta curta

Uma partição curta disparou failover entre data centers e deixou escritas divergentes para conciliar. A maior parte dos serviços do GitHub voltados ao usuário roda em data centers próprios, e os dados ficam em clusters MySQL. Cada cluster segue o arranjo clássico primário-réplicas: um único nó aceita escritas, as aplicações direcionam as escritas ao primário e cada cluster chega a…

01 · CONTEXTO E ARQUITETURA

MySQL em duas costas, com Orchestrator no comando

A maior parte dos serviços do GitHub voltados ao usuário roda em data centers próprios, e os dados ficam em clusters MySQL. Cada cluster segue o arranjo clássico primário-réplicas: um único nó aceita escritas, as aplicações direcionam as escritas ao primário e cada cluster chega a ter dezenas de réplicas de leitura.

Quem decide quando o primário morreu e quem o substitui é o Orchestrator, que cuida da detecção de falha e do failover. Seus nós conversam por consenso Raft, com um ou dois nós por data center, de modo que nenhum data center sozinho tem a maioria.

  1. Os usuários falam com as aplicações, que escrevem no primário da costa leste e leem das réplicas.

    Diagrama da arquitetura: GitHub: MySQL em duas costas, antes do incidente
    CLUsuários
    CPAplicações do GitHub
    DBPrimário (costa leste)aceita escritas
    DBRéplicas (costa leste)
    DBRéplicas (costa oeste)
    CPOrchestrator (data center leste)
    CPOrchestrator (nuvem leste)
    CPOrchestrator (costa oeste)
  2. O primário replica para as réplicas das duas costas; as da costa oeste ficam com uma cópia a distância.

    Diagrama da arquitetura: GitHub: MySQL em duas costas, antes do incidente
    CLUsuários
    CPAplicações do GitHub
    DBPrimário (costa leste)
    DBRéplicas (costa leste)
    DBRéplicas (costa oeste)cópia remota
    CPOrchestrator (data center leste)
    CPOrchestrator (nuvem leste)
    CPOrchestrator (costa oeste)
  3. Três nós do Orchestrator, em lugares diferentes, formam um grupo Raft e vigiam o primário.

    Diagrama da arquitetura: GitHub: MySQL em duas costas, antes do incidente
    CLUsuários
    CPAplicações do GitHub
    DBPrimário (costa leste)
    DBRéplicas (costa leste)
    DBRéplicas (costa oeste)
    CPOrchestrator (data center leste)vigia
    CPOrchestrator (nuvem leste)vigia
    CPOrchestrator (costa oeste)vigia

O post de 2018 descreve o que esse arranjo trata: no isolamento completo de um data center, a decisão de failover é delegada ao quórum dos data centers não isolados. No incidente de outubro de 2018, os nós do Orchestrator da costa oeste e da nuvem pública da costa leste formaram quórum e passaram a fazer failover dos clusters para a costa oeste. O post do incidente ressalva que a configuração do Orchestrator precisa estar alinhada às expectativas das aplicações.

Lida assim, a lição não está em como o líder do Orchestrator é eleito, e sim em promover primários de uma costa para a outra: é essa promoção que as aplicações e a replicação entre costas precisam suportar.

02 · A PARTIÇÃO

Quarenta e três segundos sem rede

Às 22:52 UTC de 21 de outubro, uma manutenção de rotina para trocar equipamento óptico de 100G com falha cortou a conectividade entre o hub de rede da costa leste e o data center principal da costa leste. A conectividade voltou em 43 segundos.

  1. O link entre o hub de rede e o data center principal cai; o primário continua vivo, mas deixou de ser visto de fora.

    Diagrama da arquitetura: GitHub: o hub de rede perde o data center principal
    CLUsuários
    NWHub de rede (costa leste)
    CPAplicações do GitHub
    DBPrimário (costa leste)isolado
    DBRéplicas (costa leste)
    DBRéplicas (costa oeste)
    CPOrchestrator (data center leste)
    CPOrchestrator (nuvem leste)
    CPOrchestrator (costa oeste)
  2. O nó do Orchestrator dentro do data center perde contato com os outros nós e o grupo Raft inicia a deseleção do líder.

    Diagrama da arquitetura: GitHub: o hub de rede perde o data center principal
    CLUsuários
    NWHub de rede (costa leste)
    CPAplicações do GitHub
    DBPrimário (costa leste)
    DBRéplicas (costa leste)
    DBRéplicas (costa oeste)
    CPOrchestrator (data center leste)sem contato
    CPOrchestrator (nuvem leste)
    CPOrchestrator (costa oeste)
  3. Os nós da costa oeste e da nuvem pública da costa leste ainda se enxergam e formam quórum.

    Diagrama da arquitetura: GitHub: o hub de rede perde o data center principal
    CLUsuários
    NWHub de rede (costa leste)
    CPAplicações do GitHub
    DBPrimário (costa leste)
    DBRéplicas (costa leste)
    DBRéplicas (costa oeste)
    CPOrchestrator (data center leste)
    CPOrchestrator (nuvem leste)quórum
    CPOrchestrator (costa oeste)quórum
  4. Com quórum, o Orchestrator passa a mandar as escritas dos clusters para a costa oeste.

    Diagrama da arquitetura: GitHub: o hub de rede perde o data center principal
    CLUsuários
    NWHub de rede (costa leste)
    CPAplicações do GitHub
    DBPrimário (costa leste)isolado
    DBRéplicas (costa leste)
    DBRéplicas (costa oeste)vai virar primário
    CPOrchestrator (data center leste)
    CPOrchestrator (nuvem leste)
    CPOrchestrator (costa oeste)

A rede voltou antes de quase todo mundo perceber, mas a decisão do Orchestrator já estava tomada. Às 22:54 UTC os alertas começaram a indicar falhas em vários sistemas.

03 · FAILOVER E DIVERGÊNCIA

O failover correto que deu errado

O Orchestrator organizou as topologias dos clusters na costa oeste. Quando a rede voltou, os clusters dos dois data centers continham escritas que o outro não tinha.

  1. O Orchestrator promove um novo primário na costa oeste, que passa a aceitar as escritas.

    Diagrama da arquitetura: GitHub: depois do failover entre costas
    CLUsuários
    CPAplicações do GitHub
    DBPrimário (costa leste)
    DBRéplicas (costa leste)
    DBNovo primário (costa oeste)novo primário
    DBRéplicas (costa oeste)
    QFila de hooks e Pages
    CPEntrega de webhooks e Pages
    DBBackups
  2. O primário antigo da costa leste ficou com escritas que não chegaram à costa oeste.

    Diagrama da arquitetura: GitHub: depois do failover entre costas
    CLUsuários
    CPAplicações do GitHub
    DBPrimário (costa leste)escritas só aqui
    DBRéplicas (costa leste)
    DBNovo primário (costa oeste)
    DBRéplicas (costa oeste)
    QFila de hooks e Pages
    CPEntrega de webhooks e Pages
    DBBackups
  3. As aplicações da costa leste agora escrevem na costa oeste, e a latência entre costas passa a pesar em cada operação.

    Diagrama da arquitetura: GitHub: depois do failover entre costas
    CLUsuários
    CPAplicações do GitHublatência entre costas
    DBPrimário (costa leste)
    DBRéplicas (costa leste)
    DBNovo primário (costa oeste)
    DBRéplicas (costa oeste)
    QFila de hooks e Pages
    CPEntrega de webhooks e Pages
    DBBackups
  4. A equipe pausa a entrega de webhooks e os builds do Pages para proteger os dados já recebidos; a fila começa a crescer.

    Diagrama da arquitetura: GitHub: depois do failover entre costas
    CLUsuários
    CPAplicações do GitHub
    DBPrimário (costa leste)
    DBRéplicas (costa leste)
    DBNovo primário (costa oeste)
    DBRéplicas (costa oeste)
    QFila de hooks e Pagesacumulando
    CPEntrega de webhooks e Pagespausado
    DBBackups

A divergência foi pequena: um dos clusters mais ocupados teve 954 escritas na janela afetada, e o total não replicado para a costa oeste foi relativamente pequeno. Mesmo assim, o data center da costa oeste passou mais de 30 minutos recebendo escritas.

O ponto de projeto está aqui: durante a partição houve dois candidatos a primário, e cada lado tinha motivos para se achar certo. É o problema clássico de consistência quando a replicação é assíncrona: pequena que seja a diferença, ninguém sabe qual lado deve prevalecer sem um critério externo.

04 · A RECUPERAÇÃO

O que custou vinte e quatro horas

Às 23:07 UTC a equipe travou manualmente a ferramenta de deploy, e às 23:13 UTC ficou claro que o problema atingia vários clusters. Às 23:19 UTC veio a escolha deliberada de pausar webhooks e builds do Pages, e às 00:05 UTC o plano: restaurar de backups, sincronizar as réplicas nos dois sites e voltar a uma topologia estável.

  1. O backup dos clusters afetados é iniciado e vira a fonte da restauração.

    Diagrama da arquitetura: GitHub: depois do failover entre costas
    CLUsuários
    CPAplicações do GitHub
    DBPrimário (costa leste)
    DBRéplicas (costa leste)
    DBNovo primário (costa oeste)
    DBRéplicas (costa oeste)
    QFila de hooks e Pages
    CPEntrega de webhooks e Pages
    DBBackupsbackup
  2. As réplicas da costa leste são restauradas dos backups; restaurar vários terabytes leva horas.

    Diagrama da arquitetura: GitHub: depois do failover entre costas
    CLUsuários
    CPAplicações do GitHub
    DBPrimário (costa leste)
    DBRéplicas (costa leste)restaurando
    DBNovo primário (costa oeste)
    DBRéplicas (costa oeste)
    QFila de hooks e Pages
    CPEntrega de webhooks e Pages
    DBBackupsbackup
  3. Aos poucos as réplicas restauradas passam a replicar a partir da costa oeste; os clusters maiores continuam restaurando.

    Diagrama da arquitetura: GitHub: depois do failover entre costas
    CLUsuários
    CPAplicações do GitHub
    DBPrimário (costa leste)
    DBRéplicas (costa leste)sincronizando
    DBNovo primário (costa oeste)fonte da verdade
    DBRéplicas (costa oeste)
    QFila de hooks e Pages
    CPEntrega de webhooks e Pages
    DBBackups
  4. Os primários voltam à costa leste, e a costa oeste volta a ser réplica.

    Diagrama da arquitetura: GitHub: depois do failover entre costas
    CLUsuários
    CPAplicações do GitHub
    DBPrimário (costa leste)primário de volta
    DBRéplicas (costa leste)
    DBNovo primário (costa oeste)volta a réplica
    DBRéplicas (costa oeste)
    QFila de hooks e Pages
    CPEntrega de webhooks e Pages
    DBBackups

Mesmo com os primários de volta às 11:12 UTC, o atraso de replicação crescia em vez de cair às 13:15 UTC, e ainda havia dezenas de réplicas com várias horas de atraso. Só quando as réplicas sincronizaram foi possível o failover para a topologia original, às 16:24 UTC.

Havia ainda mais de cinco milhões de eventos de hook e 80 mil builds de Pages na fila, e a equipe teve de equilibrar essa carga com o tráfego normal. Às 23:03 UTC de 22 de outubro tudo estava processado, depois de 24 horas e 11 minutos de degradação. A reconciliação manual de alguns segundos de escritas seguia em andamento.

05 · O QUE O DESIGN DEVERIA TER

Disponibilidade de escrita contra consistência

Em termos de CAP, durante a partição o sistema escolheu manter a disponibilidade de escrita promovendo outro primário, e pagou com consistência: dois lados com histórias diferentes. Em arquitetura multirregião, falhar automaticamente entre regiões com replicação assíncrona transforma uma falha curta de rede em um problema de dados.

  1. O Orchestrator passa a ter um limite regional: dentro da região ele promove réplicas automaticamente.

    Diagrama da arquitetura: GitHub: desenho alvo com fronteira regional
    CLUsuários
    CPAplicações do GitHub
    DBPrimário (costa leste)
    DBRéplicas (costa leste)
    DBRéplicas (costa oeste)
    CPOrchestrator com limite regionallimite regional
    DBPrimário de outra região
  2. Uma partição entre regiões não promove ninguém sozinha: o primário segue o mesmo, e a decisão de trocar de região passa por uma pessoa.

    Diagrama da arquitetura: GitHub: desenho alvo com fronteira regional
    CLUsuários
    CPAplicações do GitHub
    DBPrimário (costa leste)continua primário
    DBRéplicas (costa leste)
    DBRéplicas (costa oeste)só réplica
    CPOrchestrator com limite regional
    DBPrimário de outra região
  3. A meta de longo prazo é servir tráfego de mais de um data center ao mesmo tempo, em um desenho ativo/ativo/ativo.

    Diagrama da arquitetura: GitHub: desenho alvo com fronteira regional
    CLUsuários
    CPAplicações do GitHub
    DBPrimário (costa leste)
    DBRéplicas (costa leste)
    DBRéplicas (costa oeste)
    CPOrchestrator com limite regional
    DBPrimário de outra regiãooutra região ativa
Opção de failoverO que a fonte registraRisco registrado na fonte
Automático entre regiões (o que houve)O Orchestrator passou a fazer failover dos clusters para a costa oesteEscritas presentes em um data center e ausentes no outro; latência repentina entre costas
Automático só dentro da regiãoAção técnica listada: impedir a promoção de primários entre fronteiras regionaisA fonte não descreve o custo desta opção
Ativo/ativo/ativoMeta declarada: tolerar a falha total de um data center sem impacto ao usuário, com redundância N+1 no nível de instalaçãoSegundo o GitHub, um esforço grande que levará algum tempo
Opção de failoverO que ganha (leitura didática)O que arrisca (leitura didática)
Automático só dentro da regiãoMantém a rapidez do failover para falha de nóUma região inteira fora do ar deixa de ter resposta automática
Manual entre regiõesDá tempo de avaliar as escritas pendentesMais indisponibilidade de escrita enquanto se decide

GitHub listou como ações a configuração do Orchestrator para impedir a promoção de primários entre fronteiras regionais, a meta de redundância N+1 no nível de instalação e testar suas premissas de forma mais proativa.

06 · LIÇÕES

O que levar para a entrevista

As lições a seguir são interpretação didática do caso, não afirmações do post.

Primeiro, automação de failover precisa conhecer a topologia: promover um nó na mesma região e promover um nó em outra região são decisões de risco muito diferentes. Segundo, em replicação assíncrona o failover tem um custo de dados, e o projeto tem de dizer de antemão quem vence quando houver divergência. Terceiro, o tempo de recuperação depende do tamanho dos dados e do atraso das réplicas, não do tempo da falha. Quarto, pausar trabalho secundário, como webhooks, é uma ferramenta legítima para proteger a integridade.

Perguntas frequentes

O que é GitHub: 43 segundos de partição, 24 h degradado?

Uma partição curta disparou failover entre data centers e deixou escritas divergentes para conciliar.

O que o design de GitHub: 43 segundos de partição, 24 h degradado cobre?

Ele está organizado nestas seções: MySQL em duas costas, com Orchestrator no comando, Quarenta e três segundos sem rede, O failover correto que deu errado, O que custou vinte e quatro horas, Disponibilidade de escrita contra consistência e O que levar para a entrevista.

Quanto tempo leva GitHub: 43 segundos de partição, 24 h degradado e qual é o nível?

Leva cerca de 15 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.