Arquitetura de Resiliência em Cloud: Estratégias Multi-Region

Análise técnica de estratégias multi-region para outages de cloud: DR patterns, circuit breakers, failover real e como construir resiliência que funciona além do diagrama.

Arquitetura de Resiliência em Outages de Cloud: O Que Acontece Quando us-east-1 Cai

Quando a AWS us-east-1 saiu do ar em 13 de dezembro de 2023, não foram apenas Fortnite, Alexa e Snapchat que pararam. Durante três horas, milhares de sistemas descobriram da pior forma possível: aquela região marcada como “DR secondary” no seu diagrama de arquitetura não funciona do jeito que você imaginou durante o design review.

O outage afetou Lambda, API Gateway e CloudWatch por causa de um problema no subsistema de rede interna entre Availability Zones. E aqui está o detalhe técnico que importa: não foi uma falha isolada de AZ, foi uma falha sistêmica na região inteira. Seus health checks continuaram respondendo 200 OK enquanto suas funções Lambda não conseguiam fazer nada. Seus alarmes no CloudWatch não dispararam porque o próprio CloudWatch estava comprometido. E o mais irônico: você não conseguia nem ver o status do incidente porque o dashboard de status da AWS também depende de us-east-1.

Este não é mais um artigo sobre “a importância de multi-region”. É uma análise técnica do que realmente funciona quando a teoria encontra um datacenter em chamas.

As Quatro Estratégias de DR (e Por Que Três Delas Falham na Prática)

A AWS define oficialmente quatro abordagens para disaster recovery. Cada uma traz trade-offs brutais entre custo e tempo de recuperação. A diferença entre RPO (Recovery Point Objective) e RTO (Recovery Time Objective) deixa de ser conceito teórico quando você está explicando pro CEO por que o sistema está fora do ar há 40 minutos.

Backup & Restore é a estratégia que todo mundo implementa primeiro porque é a mais barata. Você faz snapshots regulares e torce pra não precisar usar. O problema real: S3 Cross-Region Replication replica 99% dos objetos menores que 100KB em 15 minutos, mas objetos grandes podem levar horas. Se seu RPO é medido em minutos, CRR não vai te salvar. RDS Read Replicas cross-region têm lag típico de 5-30 segundos dependendo da carga, o que parece aceitável até você perceber que durante um outage, aquela carga pendente não vai replicar.

Pilot Light mantém componentes críticos sempre rodando na região secundária: banco de dados replicando, configurações prontas, mas compute desligado. RPO de minutos, RTO de 10-30 minutos. O desafio técnico: você precisa testar esse failover regularmente, e todo teste é um evento de risco. LinkedIn reporta que consegue servir apenas 30% das requisições de cache stale sem impacto perceptível ao usuário. Os outros 70% precisam de acesso real ao banco de dados replicado. Se essa replicação tiver inconsistência, você vai descobrir durante o failover.

Warm Standby mantém uma versão reduzida do ambiente rodando constantemente. RPO de segundos, RTO de minutos. O problema não documentado: como você garante que aquela versão “reduzida” vai escalar rápido o suficiente quando precisar? Auto-scaling leva tempo pra provisionar instâncias. Warm up de JVMs leva tempo. Conexões de banco de dados precisam ser estabelecidas. Aurora Global Database oferece RPO menor que 1 segundo e RTO menor que 1 minuto para failover cross-region, mas isso assume que você tem capacidade de read/write já provisionada.

Multi-Site Active/Active é onde a física encontra a economia. RPO near-zero (< 1 segundo), RTO < 1 minuto, custo aproximadamente 2x da infraestrutura primária. Não é só dobrar os recursos. DynamoDB Global Tables adiciona 30-100ms de latência versus single-region por causa da replicação assíncrona. E replicação assíncrona significa possibilidade de conflitos de escrita. Se duas regiões processam updates do mesmo item simultaneamente, alguém precisa resolver esse conflito. Last-write-wins funciona pra contadores, mas não funciona pra transações financeiras.

A AWS reporta que 99% dos incidentes são resolvidos dentro de cada AZ sem propagar para outras regiões. Multi-AZ realmente funciona na maioria dos casos. Mas aquele 1% - quando falha no nível de região - expõe toda arquitetura que tratou multi-region como checkbox de compliance.

A Mecânica Real de Failover Multi-Region

Route53 Application Recovery Controller foi lançado especificamente pra resolver o problema de “como eu faço failover sem ter acesso à região primária”. Ele opera independente de qualquer região específica e pode automatizar failovers em menos de 1 minuto com safety checks integrados.

O detalhe técnico que a documentação menciona discretamente: DNS TTL precisa ser 60 segundos ou menos pra DR efetivo, mas clientes podem não respeitar TTL. Você pode configurar perfeitamente seu Route53, fazer health checks de 10 segundos (standard) ou até 1 segundo (fast), mas se o cliente HTTP do usuário final decidiu cachear aquele DNS por 5 minutos, seu failover perfeito vai levar 5 minutos pra ele.

Route53 health checks têm detecção de falha típica em 30-60 segundos dependendo da configuração. Combina com latência cross-region de 60-70ms entre us-east-1 e us-west-2, e você consegue failover transparente se sua aplicação tolera essa latência adicional. Mas “tolera” é palavra chave: se você tem lógica de negócio que assume latência de single-digit milliseconds, adicionar 60ms quebra SLAs.

DynamoDB Global Tables oferece replicação multi-region com RPO menor que 1 segundo usando replicação assíncrona. A latência de replicação média entre us-east-1 e us-west-2 fica entre 0.5-2 segundos. Aurora Global Database tem lag de replicação típico menor que 1 segundo, com mediana de 300-500ms entre regiões US. Números específicos importam porque definem o que você perde durante failover.

Netflix implementa Multi-Site Active/Active e reporta 99.99% de disponibilidade - aproximadamente 52 minutos de downtime por ano. Não por acidente ou sorte, mas porque eles testam falhas em produção constantemente desde 2011 com Chaos Monkey, desligando instâncias aleatoriamente. A estratégia não é evitar falhas, é garantir que sistemas continuam operando quando componentes falham.

A lacuna real da documentação oficial: todos os exemplos são de empresas de escala extrema (Netflix, LinkedIn, Uber). Para empresas de médio porte processando 10-100 mil requisições por segundo, os trade-offs mudam. Você tem complexidade técnica similar, mas sem time de 50 engenheiros de infraestrutura. A documentação não especifica métricas de custo operacional de manter Warm Standby versus Pilot Light em cenários reais, apenas que Active/Active custa ~2x.

Circuit Breakers e Degradação Graceful: Além do Timeout

Hystrix morreu em 2018. A biblioteca que definiu como implementar circuit breakers em microservices está em modo manutenção desde então, última release 1.5.18. O sucessor recomendado é Resilience4j, construído para Java 8+ com programação funcional. A diferença na abordagem reflete uma década de aprendizado sobre o que realmente funciona em produção.

Circuit breakers operam em três estados: CLOSED (requisições passam normalmente), OPEN (todas as requisições falham imediatamente sem tentar), e HALF_OPEN (algumas requisições são permitidas pra testar recuperação). A transição entre estados depende de métricas de falha coletadas em janela deslizante.

Resilience4j configurações típicas incluem slidingWindowSize de 100 requisições, failureRateThreshold de 50%, e waitDurationInOpenState de 60000ms (1 minuto). Traduzindo: se 50 das últimas 100 requisições falharem, abre o circuit. Depois de 1 minuto, tenta algumas requisições pra ver se o serviço se recuperou. O detalhe operacional: minimumNumberOfCalls padrão é 100, então o circuit breaker requer volume mínimo de tráfego pra funcionar efetivamente. Se você tem endpoint que recebe 10 requisições por minuto, pode levar 10 minutos pra acumular dados suficientes pra abrir o circuit.

Netflix reportou que Hystrix reduziu latência P99 de 99ms para 5ms em casos de falha de dependências. Como? Fail-fast. Ao invés de esperar timeout de 30 segundos em chamada HTTP que nunca vai completar, circuit breaker detecta padrão de falha e retorna erro imediatamente. Usuário vê erro em 5ms ao invés de página travada por 30 segundos.

Circuit breaker sozinho não resolve nada. Você precisa de fallback strategy. E aqui mora o problema real: fallback precisa ser idempotente e mais simples que operação principal. Se seu sistema processa pagamento, qual é o fallback seguro quando processador de cartão está fora? Não existe. Você pode enfileirar a transação, mas isso muda o contrato da API de síncrono pra assíncrono. Você pode retornar cache da última consulta, mas dados stale podem estar incorretos. LinkedIn descobriu que apenas 30% das requisições podem ser servidas de cache stale sem impacto perceptível.

A documentação de patterns de circuit breaker para serviços serverless (Lambda, API Gateway) praticamente não existe em forma estruturada. Implementar circuit breaker quando sua função Lambda tem cold start de 2 segundos adiciona complexidade significativa. Você precisa de state compartilhado entre invocações (DynamoDB? ElastiCache?), e esse state se torna single point of failure.

Application Load Balancer cross-zone adiciona 1-2ms de latência quando habilitado, mas distribui tráfego entre AZs automaticamente. Se você tem latency budget apertado, cada milissegundo importa. Se você tem requirements de alta disponibilidade, perder 2ms pra ganhar resiliência a falha de AZ é trade-off correto. Arquitetura é sobre escolher qual problema você quer ter.

Operacionalizando Resiliência: Além da Arquitetura no Papel

Outages revelam a diferença entre ter DR strategy documentada e ter DR strategy que funciona. Você pode ter Aurora Global Database configurado perfeitamente, mas se ninguém no time sabe como executar failover manual, ou se o runbook assume acesso à região primária que não existe mais durante outage, teoria vira ficção.

Benchmarks públicos não estão disponíveis para complexidade operacional entre estratégias DR - tempo de setup inicial, overhead de manutenção, frequência necessária de testing. A AWS não publica essas métricas porque variam drasticamente por workload. Sistema transacional com milhões de writes por segundo tem desafios completamente diferentes de sistema analítico batch que processa dados uma vez por dia.

Route53 health checks podem ter taxas de falso positivo dependendo da configuração, mas taxas específicas não são documentadas publicamente. Configurar threshold muito sensível gera failovers desnecessários. Configurar muito tolerante significa demorar pra detectar falha real. Você precisa ajustar baseado em observabilidade do seu sistema específico, não em best practices genéricas.

Latência cross-region entre us-east-1 e eu-west-1 fica em 80-90ms. Se sua aplicação serve usuários globalmente, você já está lidando com essa latência de qualquer forma. Se todos os seus usuários estão na costa leste dos EUA, adicionar 80ms pra servir de Europa durante DR pode violar SLAs. Impacto de latência cross-region em diferentes tipos de workload não tem documentação consolidada porque depende fundamentalmente do comportamento do usuário e tolerância da aplicação.

AWS Global Accelerator pode otimizar roteamento cross-region, mas benchmarks além de regiões US/EU não estão amplamente documentados. Se você opera na América Latina ou Ásia-Pacífico, precisa medir na sua infraestrutura específica.

Resiliência real é construída em três camadas: arquitetura que suporta degradação, operações que praticam failover regularmente, e cultura que trata incidentes como oportunidade de aprendizado ao invés de busca por culpados. O outage de us-east-1 vai ser resolvido. A questão é: quando o próximo acontecer, seu sistema vai estar preparado de verdade ou só no diagrama da apresentação?

Construindo Resiliência Incremental

Multi-region active/active não é onde você começa. É onde você eventualmente chega depois de resolver problemas mais fundamentais: monitoring que funciona quando região primária cai, runbooks que são executáveis sem depender de serviços da região afetada, times que sabem executar failover sob pressão.

Comece com multi-AZ dentro de uma região. A AWS reporta que 99% dos incidentes são contidos em AZ única. Isso resolve a vasta maioria dos problemas antes de adicionar complexidade de cross-region. Implemente circuit breakers nos pontos de integração críticos. Teste degradação graceful desligando dependências intencionalmente em ambiente de staging.

Depois adicione replicação cross-region para dados críticos. DynamoDB Global Tables ou Aurora Global Database dão fundação técnica, mas não resolvem decisões de quando e como fazer failover. Route53 Application Recovery Controller automatiza parte do processo, mas alguém precisa definir os critérios.

Eventualmente, considere warm standby ou active/active, mas apenas quando você tem clareza do custo real - não só AWS billing, mas overhead operacional de manter dois ambientes sincronizados, complexidade de debug quando comportamento diverge entre regiões, e risco de split-brain durante partição de rede.

O melhor DR plan é aquele que você consegue executar sob pressão com o time que você tem hoje, não o que parece impressionante em architecture review com o time que você gostaria de ter. Outages são inevitáveis. Estar preparado é escolha deliberada, testada repetidamente, não checkbox de compliance marcado uma vez e esquecido.


← Voltar para home