Em 17 de agosto, o GitHub sofreu uma interrupção que durou 7 horas e 47 minutos. Essa interrupção afetou desenvolvedores e organizações de todo o mundo ao prejudicar o github.com, a autenticação, o GitHub Actions, as APIs, os pull requests, os issues e o Copilot. Se você tentou publicar software naquele dia, deixamos você na mão.
Esse foi nosso segundo incidente significativo em agosto, após a falha do Actions em 6 de agosto. Em março e abril, compartilhei o trabalho que estávamos realizando para aumentar a confiabilidade do GitHub. Fizemos progressos, mas esses incidentes deixam claro que precisamos acelerar esse trabalho.
O que aconteceu
Nossa investigação revelou que a interrupção começou quando o tráfego atingiu um novo pico e um componente crítico da infraestrutura em nosso data center no centro dos EUA não conseguiu escalar para acompanhar esse tráfego. A pressão de capacidade resultante se propagou por nossos sistemas, provocou falhas de autenticação e afetou vários serviços do GitHub.
Foram necessárias várias ações coordenadas para a recuperação. As equipes redirecionaram o tráfego, isolaram a infraestrutura afetada e restauraram os serviços gradualmente. A maioria dos serviços do GitHub se recuperou mais cedo naquele dia, mas alguns serviços do Copilot demoraram mais. As falhas nesses serviços acionaram um loop de novas tentativas no lado do cliente, o que aumentou o tráfego durante a recuperação. Primeiro, tivemos de mitigar esse comportamento para poder restaurar o tráfego com segurança. A análise abrangente da causa raiz inclui uma linha do tempo técnica detalhada.
Nenhuma alteração de código ou configuração causou qualquer uma das duas interrupções. A causa subjacente de ambos os incidentes foi a insuficiência de capacidade. Não conseguimos escalar os componentes críticos antes que a demanda ultrapassasse a capacidade. Desde abril, o número mensal de commits aumentou de 1,4 bilhões para 2,9 bilhões. Esse crescimento explica a pressão sobre nossos sistemas, mas não justifica essas interrupções.
O que fizemos e o que vem a seguir
Como parte dos compromissos de confiabilidade que assumimos no início deste ano, concentramos nossos esforços em três prioridades: adicionar capacidade, aumentar a eficiência e eliminar gargalos arquiteturais. Desde então, adicionamos mais de 3 milhões de núcleos de CPU, 120 petabytes de armazenamento de alta velocidade e uma quantidade significativa de capacidade de rede. Em nossos data centers existentes, aceleramos nossa migração para o Azure enquanto instalávamos hardware na medida permitida pela capacidade elétrica disponível.
Hoje, o Azure atende aproximadamente 58% da carga da plataforma do GitHub e metade de todas as operações do Git; essa proporção subiu de 12% da carga da plataforma em maio. Essa infraestrutura em expansão também sustentou o crescimento das execuções de trabalhos do GitHub Actions mostrado abaixo.
A infraestrutura e a capacidade do Azure também aceleraram nossos esforços para escalar os maiores monorepos. Nosso próximo marco é uma arquitetura que escala a capacidade de leitura linearmente com o número de leitores e possibilita operações de leitura ilimitadas.
Vamos implementá-la gradualmente, começando pelos maiores monorepos.
A escala não é o único desafio que enfrentamos. À medida que o ritmo e a complexidade das mudanças aumentaram, nossas práticas operacionais existentes não conseguiram acompanhar. Direcionamos equipes e recursos para a disponibilidade; investimos em testes mais robustos, processos de implantação mais seguros, melhor observabilidade e mecanismos de alerta mais eficazes. Fizemos progressos, mas esse trabalho ainda não foi concluído.
Além disso, estamos isolando os sistemas críticos uns dos outros e eliminando as dependências compartilhadas entre eles. Esse trabalho foi concebido para reduzir a probabilidade de uma interrupção e limitar seu impacto caso ela ocorra.
Aprendemos com cada interrupção e adicionamos novos trabalhos ao nosso conjunto de tarefas de disponibilidade. Os incidentes de 6 de agosto e 17 de agosto levaram a duas mudanças urgentes.
Primeiro, estamos implementando limites de novas tentativas, orçamentos de novas tentativas e tempos limite variáveis consistentes nas interações entre serviços, a fim de evitar tempestades de novas tentativas e cargas em cascata. Segundo, estamos revisando os alertas de baixa prioridade de CPU e memória para identificar componentes que possam falhar durante aumentos repentinos de tráfego.
Nosso compromisso com a alta disponibilidade não é apenas uma promessa técnica.