Estudo comentado: como sistemas complexos falham? — parte 2

Adriano Croco
8 min readApr 15, 2024

Olá!

Este texto é uma continuação. A primeira parte você encontra aqui.

Todas as ações dos praticantes são apostas.

Após acidentes, o fracasso manifesto frequentemente parece ter sido inevitável e as ações do praticante como erros ou desconsideração deliberada de certo fracasso iminente. Mas todas as ações dos praticantes são na verdade apostas, ou seja, ações que ocorrem diante de resultados incertos. O grau de incerteza pode mudar de momento a momento. Que as ações dos praticantes são apostas fica claro após acidentes; em geral, a análise post hoc considera essas apostas como ruins. Mas o inverso, que os resultados bem-sucedidos também são o resultado de apostas, não é amplamente apreciado.

Em tecnologia, não sei se eu concordo com o conceito de “aposta” do ponto de vista técnico. Experimente tentar resolver um problema sem ter uma mínima noção do que se faz, é bastante improvável que você consiga bons resultados na base da tentativa e erro. Porém, há alguns casos que são peculiares na história da área. Eu consigo pensar em dois exemplos: o Shopify ter a escala que tem usando Ruby e MySQL ou até mesmo o Nubank ter construído seus sistemas em cima de Clojure. Ao meu ver, decisões bem fora da caixa no momento que foram tomadas.

Ações na ponta resolvem toda a ambiguidade.

As organizações são ambíguas, frequentemente intencionalmente, sobre a relação entre metas de produção, uso eficiente de recursos, economia e custos de operações e riscos aceitáveis de acidentes de baixa e alta consequência. Toda a ambiguidade é resolvida pelas ações dos praticantes na ponta do sistema. Após um acidente, as ações dos praticantes podem ser consideradas ‘erros’ ou ‘violações’, mas essas avaliações são fortemente tendenciosas pelo viés retrospectivo e ignoram as outras forças motivadoras, especialmente a pressão de produção.

Eu já perdi a conta de quantas vezes eu ou alguém que eu estava acompanhando em algum incidente tivemos que tomar uma decisão no calor do momento para fazer as coisas voltarem ao normal sem depender de múltiplas aprovações ou análise de risco mais sofisticadas (leia-se: pedir ajuda para algum chefe).

Nesse ponto, é bem isso mesmo. Eu gosto muito de uma frase do grande filósofo e boxeador nas horas vagas Mike Tyson que ilustra bem esse ponto da ambiguidade: todo mundo tem um plano até levar um soco na cara.

a vida em sua essência

Portanto, é esperado que o firefighter tome algumas decisões ali em produção que possam parecer ousadas, mas tá tudo bem.

Os praticantes humanos são o elemento adaptável de sistemas complexos.

Praticantes e gerenciamento de primeira linha adaptam ativamente o sistema para maximizar a produção e minimizar acidentes. Essas adaptações frequentemente ocorrem em uma base momento a momento. Algumas dessas adaptações incluem:
(1) Restruturação do sistema para reduzir a exposição de partes vulneráveis ​​ao fracasso.
(2) Concentração de recursos críticos em áreas de demanda esperada alta.
(3) Fornecimento de caminhos para retirada ou recuperação de falhas esperadas e inesperadas.
(4) Estabelecimento de meios para a detecção precoce de mudanças no desempenho do sistema para permitir reduções graciosas na produção ou outros meios de aumentar a resiliência.

Em tecnologia, podemos pensar em várias técnicas que atendem os pontos mencionados como Hardening (1), Autoscaling (2), Retries (3), Exponential Backoffs (3) e Alertas (4).

Em todos os casos, são técnicas criadas por humanos por causa da nossa capacidade de adaptação ao lidar com a rigidez da complexidade envolvida em sistemas dessa natureza.

A expertise humana em sistemas complexos está constantemente mudando.

Sistemas complexos requerem expertise humana substancial em sua operação e gerenciamento. Essa expertise muda de caráter à medida que a tecnologia muda, mas também muda pela necessidade de substituir especialistas que saem. Em cada caso, o treinamento e o aprimoramento da habilidade e expertise são parte da função do próprio sistema. Em qualquer momento, portanto, um dado sistema complexo conterá praticantes e aprendizes com graus variados de expertise. Questões críticas relacionadas à expertise surgem da necessidade de usar expertise escassa como um recurso para as necessidades de produção mais difíceis ou exigentes e da necessidade de desenvolver expertise para uso futuro.

Se for parar para pensar, é por isso que Staff Engineers são tão escassos (e deveriam ser mais valorizados, inclusive). Isso também explica porque partes dos sistemas estão boas e outras não. Geralmente, isso é causado justamente por causa dessa assimetria de expertise em diferentes componentes, alguns foram feitos por Juniors, outros pelos Staffs e por aí vai.

Lembrando que esse artigo é de 2002! Portanto, saiba que a área de tecnologia não mudou tanto assim ao longo do tempo. No final, não importa o framework ou cloud que você use, o que importa é sistema em pé e bem feito.

A mudança introduz novas formas de fracasso.

A baixa taxa de acidentes manifestos em sistemas confiáveis pode encorajar mudanças, especialmente o uso de nova tecnologia, para diminuir o número de falhas de baixa consequência, mas alta frequência. Essas mudanças podem realmente criar oportunidades para novas falhas de baixa frequência, mas alta consequência. Quando novas tecnologias são usadas para eliminar falhas de sistemas bem entendidas ou para obter desempenho de alta precisão, muitas vezes elas introduzem novos caminhos para falhas catastróficas em grande escala. Não é incomum que essas novas catástrofes raras tenham impacto ainda maior do que aquelas eliminadas pela nova tecnologia. Essas novas formas de falha são difíceis de ver antes do fato; a atenção é dirigida principalmente às características benéficas supostas das mudanças. Porque esses acidentes novos, de alta consequência ocorrem a uma baixa taxa, múltiplas mudanças no sistema podem ocorrer antes de um acidente, tornando difícil ver a contribuição da tecnologia para o fracasso.

É justamente por causa desses pontos que GMUDs devem ser abolidas e a solução para não impedir a evolução de sistemas enquanto se mantém a estabilidade exigida é o uso de técnicas como Continuous Deployment, Blue/Green e Canary.

Como não podemos impedir mudanças, dado que freezings causam mais problemas do que resolvem, porque não evoluir os processos de forma inteligente? Mais um acerto de DevOps.

Visões de ‘causa’ limitam a eficácia das defesas contra eventos futuros.

Remédios pós-acidente para “erro humano” geralmente são baseados em obstruir atividades que podem “causar” acidentes. Essas medidas de final de cadeia fazem pouco para reduzir a probabilidade de futuros acidentes. Na verdade, a probabilidade de um acidente idêntico já é extraordinariamente baixa porque o padrão de falhas latentes muda constantemente. Em vez de aumentar a segurança, os remédios pós-acidente geralmente aumentam o acoplamento e a complexidade do sistema. Isso aumenta o número potencial de falhas latentes e também torna a detecção e bloqueio de trajetórias de acidente mais difícil.

Nesse ponto eu concordo muito.

Muitas vezes, a solução da gestão para falhas é adicionar processos e mais processos, na vã esperança que isso impeça problemas similares no futuro. Porém, como a natureza das falhas está sempre mudando, pode ser que aquela situação nunca mais aconteça, então, não vale muito se preparar para aquele cenário em específico. Em uma linguagem visual, a probabilidade de coisas ruins acontecerem podem ser representadas assim:

matriz de probabilidade vs resultados em casos de falhas

Vou contar um caso real que aconteceu comigo: certa vez, ocorreu um incidente que parou todo o faturamento de uma determinada filial por causa de um problema de cadastro no horário de abertura. Isso quebrou outros sistemas de forma imprevísivel (cenário típico de sistemas distribuídos). Porém, ao invés de adicionarmos “checklists” de checagem ou algum processo corporativo hiper-complexo, a solução aplicada no meu escopo foi adicionar um monitor para disparar um alerta em caso de problemas iguais. Sabendo disso, o tempo de resolução caiu de 2–3 horas (incidente original) para poucos minutos.

Geralmente, criar mais processos mais atrapalha do que ajuda. É por isso que ninguém consegue trabalhar direito em empresas mais antigas. A quantidade de processos que surgiram ao longo do tempo para tratar falhas pontuais a muito tempo esquecidas fazem as pessoas gastarem mais tempo gerenciando processo do que fazendo trabalho relevante.

A segurança é uma característica dos sistemas e não de seus componentes.

A segurança é uma propriedade emergente dos sistemas; ela não reside em uma pessoa, dispositivo ou departamento de uma organização ou sistema. A segurança não pode ser comprada ou fabricada; não é uma característica separada dos outros componentes do sistema. Isso significa que a segurança não pode ser manipulada como uma matéria-prima ou material bruto. O estado de segurança em qualquer sistema é sempre dinâmico; a mudança sistêmica contínua garante que o perigo e sua gestão estejam constantemente mudando.

Aqui vale uma metáfora usando hardware: você pode usar discos rígidos baratos ruins, desde que eles estejam operando em um modo de redundância, seu storage não ficará fora do ar em caso de falha nos discos.

É por isso que sistemas bancários são relativamente seguros. Requer mais que uma pessoa má-intencionada, uso de tecnologias antigas (no banco vermelho, ainda se usa DOS e Java 6) ou falhas conhecidas para fazer o seu dinheiro sumir.

As pessoas continuamente criam segurança.

Operações sem falhas são o resultado das atividades de pessoas que trabalham para manter o sistema dentro dos limites de desempenho toleráveis. Essas atividades são, em sua maioria, parte das operações normais e superficialmente diretas. Mas porque as operações do sistema nunca são livres de problemas, as adaptações dos praticantes humanos às condições mutáveis realmente criam segurança de momento a momento. Essas adaptações frequentemente se resumem à seleção de uma rotina bem ensaiada de um conjunto de respostas disponíveis; às vezes, no entanto, as adaptações são combinações novas ou criações de abordagens novas.

As pessoas que realmente merecem um aumento são as daquele time de tecnologia em que os sistemas nunca dão problemas e não aquelas que vivem apagando incêndios. Justamente são essas (as estáveis) que descobrem formas de manter o sistema funcionado apesar de todo o caos instalado.

Operações sem falhas exigem experiência com falhas.

Reconhecer o perigo e manipular com sucesso as operações do sistema para permanecer dentro dos limites de desempenho toleráveis requer contato íntimo com a falha. Um desempenho do sistema mais robusto é provável em sistemas onde os operadores podem discernir a “borda do envelope”. Aqui é onde o desempenho do sistema começa a se deteriorar, torna-se difícil de prever ou não pode ser prontamente recuperado. Em sistemas intrinsecamente perigosos, espera-se que os operadores encontrem e apreciem os perigos de maneiras que levem a um desempenho geral desejável. A segurança melhorada depende de fornecer aos operadores visões calibradas dos perigos. Também depende de fornecer calibração sobre como suas ações movem o desempenho do sistema em direção ou longe da borda do envelope.

Um termo mais moderno para “borda do envelope” talvez seja os percentis que usamos ao analisar métricas de performance (p75, p90, p99, etc).

Além disso, qual a mensagem aqui: ao invés de evitar a falha, gere-a continuamente para aprender os limites do ecossistema e como lidar melhor com eles. Para tal, consigo citar duas práticas: Chaos Engineering (que deliberamente injeta falhas) e Constant Work Pattern (que faz o sistema atuar em 100% o tempo todo, através do uso de Dummy Transactions). Em ambos os casos, times que aplicam isso se mantém mais próximos a falha e consequentemente, são mais resilientes de uma maneira geral.

Com isso, encerramos por aqui a análise do artigo.

Espero que esse texto tenha sido útil para você de alguma forma.

Até!

Você gostou do conteúdo e gostaria de fazer mentoria comigo? Clique aqui e descubra como.

--

--