English· Español· Deutsch· Nederlands· Français· 日本語· ქართული· 繁體中文· 简体中文· Português· Русский· العربية· हिन्दी· Italiano· 한국어· Polski· Svenska· Türkçe· Українська· Tiếng Việt· Bahasa Indonesia

un

visitante
1 / ?

Os Três Conceitos de Falha que Valem a Pena Conhecer

Boas-vindas

Sistemas distribuídos falham em padrões. Uma vez que você aprende os padrões, cada relatório de pós-mortem se torna um exercício de reconhecimento em vez de um mistério.

Três conceitos cobrem a maior parte do que é importante na análise de falhas em produção:

Ponto único de falha (SPOF): um componente cuja falha derruba um sistema maior. Frequentemente oculto: o servidor DNS em que todos dependem; o certificado contra o qual tudo é renovado; o único mestre do banco de dados.

Falha em cascata: a falha de um componente dispara a falha de outro, que por sua vez dispara a falha de outro. Um banco de dados lento causa timeouts na camada de API, o que causa novas tentativas (retries), que sobrecarregam ainda mais o banco de dados, o que causa mais timeouts. A explosão se espalha.

Raio de explosão (Blast radius): quanto do sistema cai quando uma peça falha. As escolhas arquitetônicas limitam ou deixam sem limite esse raio. Um SPOF (ponto único de falha) tem raio de explosão ilimitado. Um serviço compartimentado (bulkheaded) tem raio limitado.

Ao final desta lição, você será capaz de:

- Identificar SPOFs em uma arquitetura por inspeção

- Reconhecer padrões de falha em cascata: rebanho trovejante (thundering herd), tempestade de novas tentativas (retry storm), fila da morte (queue of death)

- Ler uma linha do tempo real e separar o gatilho do defeito latente que o gatilho revelou

- Escrever itens de ação sem culpa (blameless) que visam sistemas em vez de pessoas, cobrindo prevenção / detecção / recuperação

- Raciocinar sobre compartimentação (bulkheads) e disjuntores (circuit breakers) como ferramentas para limitar o raio de explosão

Encontre o Ponto Único de Falha

Inspeção da Arquitetura em Camadas

Considere uma pequena arquitetura web:

- DNS: api.example.com -> IP de um único servidor de nomes 203.0.113.10 hospedado por um único provedor de DNS

- CDN: um único fornecedor de CDN à frente de api.example.com

- Ingress: duas máquinas de proxy reverso atrás de um balanceador de carga

- Backend: seis réplicas da API em duas zonas de disponibilidade (três por zona)

- Banco de dados: um primário + uma réplica de leitura, na mesma zona de disponibilidade

- Cache: cluster Redis, três nós distribuídos nas mesmas duas zonas de disponibilidade

Pergunta: quais componentes são SPOFs? Dica: SPOFs nem sempre são do tipo óbvio de 'máquina única'. Um cluster de três máquinas em uma única zona de disponibilidade é um SPOF para a falha dessa zona.

Identifique pelo menos três SPOFs nesta arquitetura. Para cada um, nomeie o que falha quando ele falha e proponha uma mudança concreta que removeria o SPOF (sem reescrever a aplicação).

Três Padrões Clássicos de Cascata

Falhas se propagam através das dependências

Padrão 1: Turbilhão de clientes (Thundering herd). Um recurso compartilhado (cache, lock, banco de dados) falha ou é reiniciado. Todos os clientes que dependiam dele tentam novamente simultaneamente. A onda de requisições sobrecarrega o que volta a ficar disponível; as novas tentativas se acumulam mais rápido do que a recuperação consegue absorvê-las; a recuperação nunca se completa.

Padrão 2: Tempestade de novas tentativas (Retry storm). Um serviço a jusante fica lento. Os chamadores a montante, em vez de falhar, tentam novamente. As novas tentativas multiplicam a carga original. O serviço lento fica ainda mais lento, disparando mais tentativas. Eventualmente, a carga excede a capacidade até de uma versão saudável do serviço.

Padrão 3: Fila da morte. Uma fila de processamento sem pressão de retorno (backpressure) recebe itens mais rápido do que consegue processá-los. A fila cresce sem limites. A memória se esgota; o consumidor trava; é reiniciado; encontra uma fila ainda maior; trava novamente.

Fio condutor comum: uma pequena perturbação inicial dispara um loop de realimentação positiva. A própria resposta do sistema amplifica a falha em vez de amortecê-la.

Mecanismos de Amortecimento

Backoff exponencial com jitter. Clientes que fazem nova tentativa esperam cada vez mais tempo, com um deslocamento aleatório. Isso impede ondas de novas tentativas sincronizadas.

Disjuntor (Circuit breaker). Um chamador rastreia a taxa de falha do sistema de destino. Ao ultrapassar um limiar, o chamador para de fazer chamadas por um período de resfriamento e falha imediatamente em suas próprias requisições. Evita trabalho desperdiçado e permite que o sistema de destino se recupere.

Bulkhead. Isolar recursos por dependência. Pool de conexões A para o banco de dados, pool de conexões B separado para o cache. Um banco de dados lento não pode esgotar todas as conexões; as chamadas ao cache continuam.

Descarte de carga (Load shedding). Sobrecarregado, descartar requisições na borda em vez de aceitá-las e falhar lentamente. Um 429 em 1 ms é melhor que um 500 em 30 segundos.

Pressão de retorno (Backpressure). Acelerar produtores quando consumidores não conseguem acompanhar. As filas se tornam limitadas; os remetentes bloqueiam; a fonte original do trabalho sente o atrito.

Falha em cascata: gatilho -> amplificação -> colapso, com mecanismos de amortecimento

Diagnosticar uma Cascata

A camada de API de uma equipe entra em colapso durante uma troca de banco de dados de rotina. Linha do tempo:

- 14:00:00 — o operador promove o banco de dados standby. Indisponibilidade esperada: ~10 segundos.

- 14:00:08 — o primário fica indisponível. As requisições da camada de API começam a falhar com erros de conexão ao banco de dados.

- 14:00:08 — a camada de API faz novas tentativas (configuração padrão: 5 tentativas, sem backoff, intervalos de 100ms).

- 14:00:11 — o standby é promovido, aceitando novas conexões.

- 14:00:11 — a camada de API abre milhares de novas conexões de banco de dados simultaneamente (cada réplica × cada requisição concorrente × cada nova tentativa).

- 14:00:13 — o pool de conexões do novo primário é esgotado; novas conexões são rejeitadas.

- 14:00:13-14:05:00 — as réplicas da camada de API esgotam os pools de conexão, lançam exceções, entram em crash, reiniciam e repetem o ciclo.

- 14:05:00 — o operador para manualmente o tráfego da camada de API; o banco de dados se estabiliza.

- 14:10:00 — a restauração gradual do tráfego é concluída. Duração total da interrupção: ~10 minutos (vs. ~10 segundos esperados).

Identifique o padrão de cascata em jogo, nomeie os mecanismos de amortecimento que teriam impedido isso (pelo menos dois) e explique por que a falha de contingência (failover) do primário para o standby (que deveria ser uma interrupção de 10 segundos) causou, em vez disso, uma interrupção de 10 minutos.

DNS SERVFAIL: Dois Defeitos Compensados

Uma Pós-Mortem com Forma Real

O que se segue é uma versão sanitizada de um incidente real. Nomes de fornecedores alterados, IPs anonimizados; a forma, a linha do tempo e as lições são reais.

Resumo

O site example.com retornou SERVFAIL de todos os resolvers DNS públicos por aproximadamente 3-4 horas. Todas as outras 46 zonas no mesmo mestre DNS não foram afetadas. Causa raiz: dois defeitos compensados.

1. O Fornecedor A (um provedor secundário de DNS) adicionou um novo IP interno de sincronização que não estava na lista de permissão allow-axfr-ips do primário.

2. A zona example.com tinha um conflito de CNAME que violava a RFC há anos (demo.example.com tinha registros CNAME e MX/TXT no mesmo rótulo) que fez com que o Fornecedor A rejeitasse a zona em um novo AXFR.

Linha do Tempo (UTC)

- ~15:00 — O Fornecedor A adiciona o novo IP de sincronização 198.51.100.42 à sua infraestrutura

- 15:02 — o primeiro AXFR-out denied para 198.51.100.42 aparece nos logs do DNS primário (sem alertas para este sinal)

- ~18:00 — a janela de expiração do SOA foi atingida; o Fornecedor A remove a zona example.com do cache

- ~18:30 — SERVFAIL detectado externamente

- ~19:45 — causa raiz identificada

- 20:00 — 198.51.100.42 adicionado a allow-axfr-ips; primário reiniciado

- 20:05 — NOTIFY enviado; AXFR iniciado; zona continua com SERVFAIL (conflito de CNAME)

- 20:07 — check-zone revela 1 erro: conflito de CNAME em demo.example.com

- 20:09 — CNAME substituído por registro A; verificação da zona limpa (0 erros)

- 20:10 — NOTIFY enviado; AXFR concluído; o Fornecedor A começa a servir a zona

- 20:11 — dig @8.8.8.8 example.com A retorna o IP correto — RESOLVIDO

Por que apenas example.com?

Todas as 47 zonas compartilham o mesmo DNS primário. O bloqueio de IP do AXFR afetou todas as zonas. Mas apenas example.com tinha o conflito de CNAME & apenas example.com precisava de um novo AXFR no momento em que a negação foi aplicada. Outras zonas já haviam sido atualizadas antes da negação ou ainda não precisavam de atualização.

Defeito latente

O conflito de CNAME em demo.example.com existia há anos. Funcionava porque o primário servia a zona a partir do seu banco de dados (tolerante a violações do RFC) & o Fornecedor A estava servindo a partir de dados em cache obsoletos de antes da introdução da violação. Quando o Fornecedor A descartou seu cache & precisou de dados novos, a violação se manifestou.

Gatilho

O Fornecedor A adicionou silenciosamente um novo IP de sincronização. A lista de permissões do primário não o incluía. AXFR negado. Três horas depois (expiração do SOA), o Fornecedor A descartou a zona. O defeito latente surgiu quando o sistema tentou se recuperar.

Escrever Itens de Ação Sem Culpa

Sem Culpa: Alvo os Sistemas, Não as Pessoas

Um item de ação sem culpa nomeia algo que o sistema deve fazer de forma diferente, não algo que uma pessoa deve fazer de forma diferente. 'Treinar o operador' é culpabilizador. 'Adicionar uma verificação automatizada que detecte isso antes da implantação' é sem culpa.

Bons itens de ação sem culpa se agrupam em três dimensões:

- Prevenção: tornar a coisa ruim mais difícil ou impossível

- Detecção: notá-la mais cedo, caso ocorra

- Recuperação: limitar o dano quando ocorrer

Cada item deve nomear (1) a mudança específica no sistema, (2) uma equipe responsável e (3) a dimensão que atende.

Escreva três itens de ação sem culpa que abordem a análise pós-mortem do DNS-SERVFAIL acima. Distribua-os entre prevenção / detecção / recuperação (um por dimensão). Cada item deve nomear uma mudança específica no sistema e uma equipe responsável. NÃO aponte para nenhum humano como a causa.

Compartimentos que afundam sem o navio

Empréstimo da Engenharia Naval

Navios possuem anteparas estanques: paredes verticais que dividem o casco em compartimentos. Um compartimento pode inundar sem afundar o navio; outro pode falhar sem afetar o restante.

Sistemas distribuídos emprestam a mesma palavra e a mesma ideia.

Padrão de anteparas (bulkhead): isolar recursos por dependência. Um serviço que chama três APIs de baixo nível usa três pools de conexões separados, três pools de threads separados e três orçamentos de repetição separados. Uma dependência lenta ou falha não pode consumir os recursos alocados para as outras duas.

Sem anteparas: uma dependência lenta esgota o pool de threads compartilhado; chamadas a outras dependências ficam bloqueadas aguardando threads; o serviço inteiro se torna irresponsivo.

Com anteparas: uma dependência lenta esgota seu próprio pool; chamadas a ela falham rapidamente; chamadas a outras dependências continuam normalmente; o raio de explosão (blast radius) permanece limitado à dependência que falhou.

Disjuntores

Padrão de disjuntor (Circuit breaker): um wrapper com estado ao redor de uma dependência de baixo nível que rastreia a taxa de falha. Três estados:

- Fechado (normal): as chamadas passam. As falhas são contadas.

- Aberto (disparado): ao ultrapassar um limiar de falhas (por exemplo, 50% de falhas nos últimos 30 segundos), o disjuntor abre. As chamadas falham imediatamente sem tentar a dependência. Isso evita que o chamador desperdice trabalho e protege a dependência de receber carga enquanto está instável.

- Meio-aberto (teste): após um período de espera, o disjuntor permite que uma pequena fração das chamadas passe. Se elas tiverem sucesso, ele volta ao estado normal (fechado). Se falharem, ele reabre para outro período de espera.

A insight principal: o disjuntor evita esforço desperdiçado durante períodos de instabilidade conhecida e dá à dependência de baixo nível uma chance de se recuperar sem carga contínua.

Bulkheads limitam o raio de explosão. Disjuntores impedem que a explosão se sustente.

Limitar o Raio de Explosão

Seu serviço de API chama quatro serviços de baixo nível: Serviço de Usuário, Serviço de Recomendação, Serviço de Notificação e uma API de Pagamento de terceiros. A equipe ouviu que "o Serviço de Recomendação tem estado um pouco instável" e quer garantir que, quando ele falhar, o restante do sistema permaneça saudável.

Hoje, o serviço utiliza um único pool de threads compartilhado com 200 threads e um único pool de conexões HTTP compartilhado. Todos os quatro downstreams competem por esses recursos. Não há circuit breakers.

Proponha um design de bulkhead + circuit-breaker para este serviço de API. Seja específico: como você particiona os pools de threads / conexões entre as quatro dependências, quais limiares de circuit-breaker fazem sentido para o instável Recommendation Service e o que a API voltada para o usuário deve fazer quando o Recommendation Service estiver em circuito aberto?

Projetar uma Revisão de Modos de Falha

Síntese

Você aprendeu a identificar SPOFs por inspeção, reconhecer padrões de falha em cascata, separar o gatilho do defeito latente ao ler um pós-mortem, redigir itens de ação sem culpa nas áreas de prevenção / detecção / recuperação, e limitar o raio de explosão com bulkheads + circuit breakers + degradação graciosa.

Aplique as cinco.

Seu time está lançando um novo serviço search.example.com que depende de três serviços downstream: um índice de busca primário (index.example.com), um serviço de analytics (analytics.example.com) e um serviço de recomendações (recs.example.com). O time quer que você lidere uma 'revisão de modos de falha' antes do lançamento.

Descreva a revisão de modos de falha que você lideraria. Inclua: como você identificaria SPOFs (uma técnica), como você preveniria falhas em cascata entre o serviço de busca e seus três downstreams (dois padrões), um item de ação concreto para o serviço de recomendações (que o time sinalizou como o menos confiável) e qual monitoramento você exigiria que estivesse em funcionamento no lançamento.

Para Onde Este Curso Vai a Seguir

Para Onde Este Curso Vai a Seguir

Agora você pode identificar um SPOF, reconhecer uma cascata, ler um pós-mortem de forma produtiva, escrever itens de ação sem culpa e limitar o raio de explosão por design.

A lição final deste curso (cs_distsys_observability_and_capacity) ensina o que medir para que você descubra que um problema está acontecendo antes que os usuários percebam. Verificações de saúde, endpoints de versão, os quatro sinais dourados em uma camada de proxy e como as decisões de capacidade de pico se conectam aos dados observados.

Lição complementar: geometry_of_failure_modes_and_blast_radius deriva a centralidade de intercessão (qual nó do grafo é o gargalo) e o corte mínimo (o limite do raio de explosão).

Muito bem. Em frente.