O Isolamento de AZ Aguentou. Sua Arquitetura Não.
Uma falha de refrigeração derrubou racks em uma zona de us-east-1 e um quórum morreu junto. O que o raio de explosão cobre, e um detector somente leitura.

Na noite de 7 de maio, a refrigeração falhou em um data hall de uma zona de disponibilidade em us-east-1, os racks perderam energia, e o raio de explosão da AWS fez o que a documentação promete: o dano ficou contido dentro de use1-az4. Todas as outras zonas continuaram servindo. As empresas que caíram naquela noite caíram dentro da própria arquitetura, e sabemos disso com uma precisão incomum porque a Coinbase publicou um postmortem na segunda-feira que diz exatamente isso com as próprias palavras. A negociação ficou, na formulação deles, "unavailable or degraded for roughly eight hours, with full recovery of all systems taking another twelve", durante um evento em que a fronteira de zona da plataforma funcionou.
Esta é a Parte 1 de Nothing Fails Alone, uma série sobre a distância entre a disponibilidade que você compra de um provedor de nuvem e a disponibilidade que você de fato constrói em cima dela. Cada parte pega um incidente real, extrai a afirmação arquitetural que ele coloca à prova e entrega um pequeno lab que você pode rodar contra a sua própria conta. Os labs vivem em um repositório companheiro, nothing-fails-alone no GitHub, e cada um deles é somente leitura.
O que de fato aconteceu em use1-az4
O primeiro relatório de incidente no AWS Health Dashboard foi carimbado às 17:25 PDT de 7 de maio, e como o evento resolvido já saiu do dashboard, a formulação abaixo é a que The Register citou na época: problemas na zona de disponibilidade use1-az4 de us-east-1. Uma atualização seguinte descreveu o mecanismo sem rodeios: "EC2 instances and EBS volumes hosted on impacted hardware are affected by the loss of power during the thermal event." Às 18:47 PDT, a AWS disse que estava trabalhando para trazer as temperaturas de volta a níveis normais e avisou que outros serviços que dependiam das instâncias EC2 e volumes EBS afetados naquela zona também poderiam ser prejudicados.
O postmortem da Coinbase preenche a causa física: várias unidades de chiller falharam ao mesmo tempo em um único data hall, e a perda de refrigeração disparou um desligamento de segurança térmica dos racks afetados. É o que "loss of power during the thermal event" significa na prática. Os racks não foram destruídos; foram deliberadamente desligados, porque rodar computação sem refrigeração a destrói. As instâncias EC2 e os volumes EBS naqueles racks ficaram offline juntos, em um prédio, em uma zona.
A recuperação foi gradual e honesta em ser gradual. Às 22:11 PDT daquela noite, a AWS reportou capacidade adicional de refrigeração online e alguns racks recuperados, com mais a serem recuperados "in a controlled and safe manner". A capacidade de refrigeração voltou aos níveis pré-incidente às 13:50 PDT de 8 de maio, cerca de vinte horas após o primeiro relatório, com a recuperação das instâncias vindo atrás da restauração da refrigeração. Se o seu modelo mental de um evento de AZ é uma interrupção de quinze minutos, recalibre: um evento térmico é medido em horas porque a física é, e os racks voltam rack a rack, não todos de uma vez.
O que não aconteceu
As outras zonas de disponibilidade em us-east-1 permaneceram saudáveis. Essa é a parte deste incidente que deveria receber mais atenção do que recebe, porque é a parte que a AWS de fato prometeu. Zonas de disponibilidade são instalações fisicamente separadas com energia e refrigeração independentes, e em 7 de maio essa independência foi testada por uma falha real de instalação e aguentou. O domínio de falha foi um data hall; o raio de explosão ficou dentro de uma zona.
Houve exatamente uma ressalva honesta, e vale citá-la porque ela importa mais adiante nesta série. A AWS desviou o tráfego para longe da zona atingida, aconselhou os clientes a mover cargas de trabalho para as outras zonas de us-east-1 e então admitiu: "Customers may experience longer than usual provisioning times." Claro que podem. Quando uma zona morre, toda arquitetura multi-AZ corretamente construída naquela região começa a repor capacidade nas zonas sobreviventes ao mesmo tempo. A fronteira de zona aguentou, mas as zonas sobreviventes são um pool compartilhado, e um failover em massa é uma manada em disparada contra esse pool. Guarde essa ressalva; a Parte 3 desta série trata do que o seu plano de recuperação tem em comum com o plano de recuperação de todo mundo.
As próprias palavras da Coinbase
Postmortems de empresas de capital aberto costumam ser lixados até não sobrar nada. Este não é, e é por isso que vale a pena ler na íntegra. Duas frases carregam toda a história arquitetural. Primeira: "Our matching engine was pinned to a single building." Segunda, a explicação de como: o matching engine da Coinbase Exchange "runs as a Raft-based replicated cluster inside an AWS Cluster Placement Group". E então a frase que transforma um evento de zona em uma queda de oito horas: "There was no automated cross-zone failover."
Um cluster placement group é single-AZ por construção. Isso não é uma limitação que a AWS esconde; é o produto. O objetivo da estratégia de cluster é empacotar instâncias em hardware fisicamente próximo, no mesmo segmento de rede de alta largura de banda, para que a latência nó a nó seja tão baixa quanto o EC2 consegue fazer. Você não pode ter isso e separação de zona ao mesmo tempo, porque separação de zona é distância e distância é latência. Para um matching engine, onde microssegundos de latência nó a nó são o produto, um cluster placement group é a escolha correta, e a Coinbase diz exatamente isso: "We make this choice deliberately."
O problema é o que vivia dentro dele. O Raft existe para sobreviver à perda de uma minoria de nós. Coloque cinco nós Raft em um cluster placement group e você construiu um protocolo de consenso cujos membros compartilham um prédio, o que significa que compartilham um domínio de falha, o que significa que o protocolo não pode mais fazer a única coisa para a qual ele existe. Quando a AWS terminou instâncias EC2 dentro do placement group da Coinbase às 21:29 ET, três de cinco nós do matching engine caíram juntos e o quórum se foi. Um quórum que compartilha um data hall não é um quórum; é uma falha com cinco nomes.
Sem failover cross-zone automatizado por trás, a recuperação virou um processo humano. Exigiu uma mudança de código emergencial, entregue durante o incidente, para remover uma premissa de inicialização de que os cinco nós do cluster eram resolvíveis. O matching engine voltou em modo cancel-only às 02:25 ET de 8 de maio, a negociação plena foi retomada às 03:49 ET, o site de varejo e o app mobile ficaram totalmente recuperados às 09:53 ET, e o backlog de tópicos de event-streaming foi zerado às 14:00 ET. Cerca de oito horas fora do ar, mais doze até a recuperação plena, durante um evento que a AWS conteve em uma zona.
Multi-AZ é algo que você compra e algo que você constrói
O formato geral deste incidente não é uma história da Coinbase. É a distância entre comprar infraestrutura multi-AZ e construir um sistema multi-AZ, e essa distância tem um pequeno número de formatos recorrentes. Cada um destes é uma configuração que parece redundante no diagrama de arquitetura e não é:
- O Auto Scaling group de subnet única. O ASG vai alegremente repor instâncias falhas para sempre, na mesma zona, porque a lista de subnets que você deu a ele resolve para uma única AZ. Quando aquela zona degrada, a capacidade desejada não pode ser atingida até que um humano edite o grupo. Auto-recuperação que se recupera para dentro da falha não é auto-recuperação.
- RDS sem Multi-AZ. Sem standby síncrono, a perda de zona não é um failover, é um restore: de um snapshot, medido em horas, com perda de dados até o último ponto de backup. O plano de DR ao lado dele geralmente assume um failover sub-minuto, porque alguém leu a documentação de Multi-AZ e ninguém conferiu o flag no console.
- O quórum em um cluster placement group. O padrão da Coinbase: três, cinco ou sete nós de Raft, etcd ou ZooKeeper empacotados em um grupo que é single-AZ por definição. A camada de consenso se reporta como saudável e tolerante a falhas até o exato momento em que o prédio discorda.
- A dependência de NAT cross-AZ. Uma subnet privada na zona B cuja rota padrão aponta para um NAT gateway na zona A. A falha da zona A derruba o tráfego de saída de instâncias cuja própria zona está perfeitamente saudável. Essa é invisível em todo diagrama porque a seta aponta para "NAT", não para uma zona.
Nenhuma delas é exótica. Todas passam por um teste de carga, por um game day que só mata instâncias e pela maioria das revisões de arquitetura, porque cada uma só falha quando uma zona inteira falha, e zonas inteiras falham raro o suficiente para que a premissa fique sem teste por anos.
O lab: um detector de concentração single-AZ
Afirmações devem ser testáveis, então esta parte vem com um lab: 01-single-az-detector, um único arquivo Python que varre a conta e a região atuais em busca dos padrões acima e mais três. Ele é somente leitura no sentido estrito: toda chamada de API que ele faz é um Describe*. Ele roda sete verificações: Auto Scaling groups single-AZ, cluster placement groups, clusters de tamanho de quórum dentro de placement groups, instâncias RDS single-AZ, clusters RDS cujos membros estão todos em uma zona, replication groups do ElastiCache sem Multi-AZ, e subnets privadas cuja rota padrão cruza zonas para alcançar um NAT gateway.
$ python3 detect.py
SEVERITY | RESOURCE | AZ | WHY
--------------------------------------------------------------------------...
CRITICAL | placement-group/matching-prod | us-east-1a (use1-az4) | 3 instances in cluster placement group 'matching-prod': a quorum-sized cluster in a group that is single-AZ by construction. ...
HIGH | asg/api-workers | us-east-1c (use1-az2) | Auto Scaling group spans exactly one AZ. Every replacement instance lands in the same zone ...
HIGH | rds-cluster/orders | us-east-1a (use1-az4) | All members of DB cluster 'orders' sit in one AZ. Aurora failover needs a reader in a different zone ...
MEDIUM | subnet-0a1b2c3d -> nat-0e4f5a6b | us-east-1b (use1-az6) -> us-east-1a (use1-az4) | Private subnet in us-east-1b (use1-az6) routes 0.0.0.0/0 through a NAT gateway in us-east-1a (use1-az4) ...
4 finding(s).A verificação que merece a severidade CRITICAL é QUORUM_IN_ONE_AZ: um cluster placement group contendo exatamente 3, 5 ou 7 instâncias em execução. Essas contagens não são arbitrárias; são o formato de um quórum de Raft, etcd ou ZooKeeper, e uma carga em formato de quórum concentrada em uma zona é a exata configuração que derrubou a Coinbase. Um placement group com alguma outra contagem de instâncias ainda é sinalizado, mas como HIGH: é uma otimização de latência que alguém deveria confirmar ter sido escolhida de propósito.
Dois comportamentos são deliberados. Primeiro, o código de saída: o scan sai com 0 sempre que conclui, com achados ou não, porque isto é um relatório, não um portão. Se o IAM negar uma das APIs, aquela verificação é pulada com um aviso de uma linha no stderr, as verificações restantes ainda rodam, e o código de saída permanece 0; você recebe código de saída 2 apenas quando o scan não pode rodar de jeito nenhum, sem credenciais, sem região, sem boto3. Confira o stderr antes de confiar em uma tabela limpa. Segundo, todo achado reporta a zona tanto como nome quanto como ID, por exemplo us-east-1a (use1-az4). O nome é um alias que a AWS randomiza por conta; o ID é a zona física. O Health Dashboard disse use1-az4, e sem o ID você não consegue dizer se aquela era a sua us-east-1a. Essa distinção parece trivialidade hoje. A Parte 2 é sobre o incidente em que ela deixa de ser trivialidade.
Modos de falha e o que observar
O trade-off por baixo de tudo isso é legítimo, então nomeie-o em vez de fingir que ele não existe. Colocação single-AZ compra latência, transferência de dados cross-AZ custa dinheiro, e replicação síncrona entre zonas custa latência de escrita. A Coinbase não tropeçou em um placement group; eles projetaram nele e aceitaram um risco. A falha não foi a escolha, foi que a consequência da escolha, nenhum caminho automatizado para fora da zona, foi descoberta às 21:29 durante o incidente em vez de decidida em uma revisão de design antes dele.
O que observar na sua própria conta, além de rodar o detector: aritmética de quórum, não só localização do quórum, porque dois de três nós etcd em uma zona é o mesmo defeito com uma linha de tabela mais amigável. ASGs que listam várias subnets que todas resolvem para a mesma zona, e é por isso que o detector resolve as subnets do VPCZoneIdentifier em vez de confiar na lista de AZ. Caches sem réplicas: uma perda de zona deixa o ElastiCache frio, e a tempestade de misses resultante cai no seu banco de dados no pior momento possível. E provisionar capacidade durante um evento real de zona, que é a única coisa que o detector não consegue ver, porque é uma propriedade da arquitetura de todo mundo, não da sua. A própria AWS te avisou, no meio do incidente: longer than usual provisioning times. A fronteira de zona é real, e aguentou. O que você constrói em cima dela é seu.
Leia isto a seguir
- Parte 2 desta série: Duas Zonas, Dezoito Horas, Uma Causa, onde a distinção entre nome de AZ e ID de AZ deixa de ser trivialidade.
- Multi-Tenant LLM Apps: Isolating Customers on a Shared Model em ercan.ai, a mesma lição uma camada acima: a plataforma te dá uma fronteira, e o isolamento ainda é trabalho seu.
- O repositório companheiro: nothing-fails-alone, todos os labs desta série, somente leitura por design.
Para consultoria em AWS, arquitetura de nuvem, revisões de resiliência e trabalho de plataforma, comece em ercanermis.com.
Referências
Mais de Ercan
Mais dois sites, mesmo autor, terreno diferente.
IA, LLMs, agentes, ML aplicado.
Notas de campo sobre cargas de IA. Análise de custos do Bedrock, padrões de agentes, trade-offs de armazenamento vetorial, modos de falha em produção.
Visitar ercan.ai →O hub. Sobre, consultoria, contato.
Hub pessoal para as duas trilhas de escrita. Quem sou eu, como funciona a consultoria, como me contatar.
Visitar ercanermis.com →