Capítulo 3 – Abraçando o Risco

Capítulo 3 – Abraçando o Risco

Escrito por Marc Alvidrez
Editado por Kavita Guliani

Você pode esperar que o Google tente construir serviços 100% confiáveis – aqueles que nunca falham. Acontece que depois de um certo ponto, porém, aumentar a confiabilidade acaba sendo muito pior para um serviço (e seus usuários). A razão para isso é que a confiabilidade extrema tem um custo: maximizar a estabilidade limita a rapidez com que novos recursos podem ser desenvolvidos e os produtos podem ser entregues aos usuários, e aumenta drasticamente seu custo, o que, por sua vez, reduz o número de recursos que uma equipe pode oferecer.

Além disso, os usuários normalmente não percebem a diferença entre alta confiabilidade e extrema confiabilidade em um serviço, porque a experiência do usuário é dominada por componentes menos confiáveis, como a rede celular ou o dispositivo com o qual estão trabalhando. Em resumo, um usuário de um smartphone 99% confiável simplesmente não pode dizer a diferença entre 99,99% e 99,999% de confiabilidade de um serviço! Com isso em mente, em vez de simplesmente maximizar o tempo de atividade, o Site Reliability Engineering busca equilibrar o risco de indisponibilidade com os objetivos de inovação rápida e operações de serviço eficientes, de modo que a felicidade geral dos usuários – com recursos, serviço e desempenho – seja otimizada.

Gestão de Risco

Sistemas não confiáveis podem corroer rapidamente a confiança dos usuários, portanto, queremos reduzir a chance de falha do sistema. No entanto, a experiência mostra que, à medida que construímos sistemas, o custo não aumenta linearmente na proporção em que aumenta a confiabilidade – na verdade, uma melhoria incremental na confiabilidade pode custar cerca de 100 vezes mais do que o incremento anterior. O custo tem duas dimensões:

O custo de recursos redundantes de máquina/computação

É o custo associado a equipamentos redundantes que, por exemplo, nos permite desligar os sistemas para manutenção imprevista ou de rotina; ou ainda nos dá espaço para armazenar blocos de paridade de código que fornecem uma garantia mínima de durabilidade dos dados.

O custo de oportunidade

É o custo suportado por uma organização quando ela aloca recursos de engenharia para construir sistemas ou recursos que diminuem o risco, em vez de recursos que são diretamente visíveis ou utilizáveis pelos usuários finais. Esses engenheiros não trabalham mais em novos recursos e produtos para usuários finais.

No SRE, gerenciamos a confiabilidade do serviço em grande parte gerenciando o risco. Conceitualizamos o risco como um continuum. Damos igual importância a descobrir como criar maior confiabilidade nos sistemas do Google e a identificar o nível apropriado de tolerância para os serviços que executamos. Isso nos permite realizar uma análise de custo/benefício para determinar, por exemplo, onde no continuum de risco (não linear) devemos colocar Pesquisa, Anúncios, Gmail ou Fotos. Nosso objetivo é alinhar explicitamente o risco assumido por um determinado serviço com o risco que o negócio está disposto a assumir. Nós nos esforçamos para tornar um serviço confiável o suficiente, mas não mais confiável do que o necessário. Ou seja, quando estabelecemos uma meta de disponibilidade de 99,99%, queremos superá-la, mas não muito: isso desperdiçaria oportunidades de agregar funcionalidades ao sistema, sanear débitos técnicos ou reduzir seus custos operacionais. De certa forma, vemos a meta de disponibilidade como mínima e máxima. A principal vantagem desse enquadramento é que ele desbloqueia a tomada de riscos de forma explícita e mas também cuidadosa.

Medindo o risco do serviço

Como prática padrão no Google, geralmente somos mais bem atendidos identificando uma métrica objetiva para representar a propriedade de um sistema que desejamos otimizar. Ao definir uma meta, podemos avaliar nosso desempenho atual e rastrear melhorias ou degradações ao longo do tempo. Para o risco do serviço, não está imediatamente claro como reduzir todos os fatores potenciais em uma única métrica. As falhas de serviço podem ter muitos efeitos potenciais, incluindo insatisfação do usuário, prejuízo ou perda de confiança; perda de receita direta ou indireta; impacto na marca ou na reputação; e cobertura indesejável da imprensa. Claramente, alguns desses fatores são muito difíceis de medir. Para tornar esse problema tratável e consistente em muitos tipos de sistemas que executamos, nos concentramos no tempo de inatividade não planejado.

Para a maioria dos serviços, a forma mais direta de representar a tolerância ao risco é em termos do nível aceitável de tempo de inatividade não planejado. O tempo de inatividade não planejado é capturado pelo nível de disponibilidade de serviço desejado, geralmente expresso em termos do número de “noves” que gostaríamos de fornecer: disponibilidade de 99,9%, 99,99% ou 99,999%. Cada nove adicional corresponde a uma melhoria da ordem de magnitude em direção a 100% de disponibilidade. Para sistemas de serviço, essa métrica é tradicionalmente calculada com base na proporção do tempo de atividade do sistema.

Time-based availability:

availability = uptime / (uptime+downtime)

Usando essa fórmula durante o período de um ano, podemos calcular o número aceitável de minutos de inatividade para atingir um determinado número de noves de disponibilidade. Por exemplo, um sistema com uma meta de disponibilidade de 99,99% pode ficar inativo por até 52,56 minutos em um ano e permanecer dentro de sua meta de disponibilidade; consulte a Availability Table para ver a tabela.

No Google, no entanto, uma métrica de disponibilidade com base no tempo geralmente não é significativa, porque estamos trabalhando com serviços distribuídos globalmente. Nossa abordagem ao isolamento de falhas torna muito provável que estejamos atendendo a pelo menos um subconjunto de tráfego para um determinado serviço em algum lugar do mundo a qualquer momento (ou seja, estamos pelo menos parcialmente “ativos” o tempo todo). Portanto, em vez de usar métricas em torno do tempo de atividade, definimos a disponibilidade em termos da taxa de sucesso da solicitação. A disponibilidade agregada mostra como essa métrica baseada no rendimento é calculada em uma janela contínua (ou seja, a proporção de solicitações bem-sucedidas em uma janela de um dia).

Disponibilidade agregada:

availability = successful requests / total requests

Por exemplo, um sistema que atende 2,5 milhões de solicitações em um dia com uma meta de disponibilidade diária de 99,99% pode atender a até 250 erros e ainda atingir sua meta naquele dia específico.

Em um aplicativo típico, nem todas as solicitações são iguais: a falha na solicitação de inscrição de um novo usuário é diferente da falha em uma pesquisa de solicitação de novo e-mail em segundo plano. Em muitos casos, no entanto, a disponibilidade calculada como a taxa de sucesso da solicitação sobre todas as solicitações é uma aproximação razoável do tempo de inatividade não planejado, visto da perspectiva do usuário final.

Quantificar o tempo de inatividade não planejado como uma taxa de sucesso na solicitação também torna essa métrica de disponibilidade mais acessível para uso em sistemas que normalmente não atendem diretamente aos usuários finais. A maioria dos sistemas não operacionais (por exemplo: lote, pipeline, armazenamento e sistemas transacionais) tem uma noção bem definida de unidades de trabalho bem-sucedidas e malsucedidas. De fato, embora os sistemas discutidos neste capítulo sejam principalmente sistemas de atendimento ao consumidor e à infraestrutura, muitos dos mesmos princípios também se aplicam a outros sistemas com modificação mínima.

Por exemplo, um processo em lote que extrai, transforma e insere o conteúdo de um de nossos bancos de dados de clientes em um data warehouse para permitir análises posteriores pode ser configurado para ser executado periodicamente. Usando uma taxa de sucesso de solicitação definida em termos de registros processados com e sem sucesso, podemos calcular uma métrica de disponibilidade útil, apesar do fato de o sistema em lote não funcionar constantemente.

Na maioria das vezes, definimos metas de disponibilidade trimestrais para um serviço e rastreamos nosso desempenho em relação a essas metas semanalmente ou mesmo diariamente. Essa estratégia nos permite gerenciar o serviço com um objetivo de disponibilidade de alto nível, procurando, rastreando e corrigindo desvios significativos à medida que inevitavelmente surgirem. Veja Service Level Objectives para mais detalhes.

Tolerância a risco dos serviços

O que significa identificar a tolerância ao risco de um serviço? Em um ambiente formal ou no caso de sistemas críticos para a segurança, a tolerância ao risco dos serviços é normalmente construída diretamente no produto básico ou na definição do serviço. No Google, a tolerância ao risco dos serviços tende a ser definida com menos clareza.

Para identificar a tolerância ao risco de um serviço, os SREs devem trabalhar com os proprietários do produto para transformar um conjunto de metas de negócios em objetivos explícitos para os quais podemos projetar. Nesse caso, as metas de negócios que nos preocupam têm um impacto direto no desempenho e na confiabilidade do serviço oferecido. Na prática, essa tradução é mais fácil de falar do que fazer. Embora os serviços ao consumidor muitas vezes tenham proprietários de produtos claros, é incomum que serviços de infraestrutura (por exemplo, sistemas de armazenamento ou uma camada de cache HTTP de uso geral) tenham uma estrutura semelhante de propriedade do produto. Discutiremos os casos do consumidor e da infraestrutura mais adiante.

Identificando a tolerância ao risco de serviços ao consumidor

Nossos serviços ao consumidor costumam ter uma equipe de produto que atua como o proprietário do negócio para um aplicativo. Por exemplo: Pesquisa, Google Maps e Google Docs, cada um tem seus próprios gerentes de produto. Esses gerentes de produto são encarregados de compreender os usuários e os negócios e de moldar o produto para o sucesso no mercado. Quando existe uma equipe de produto, essa equipe geralmente é o melhor recurso para discutir os requisitos de confiabilidade de um serviço. Na ausência de uma equipe de produto dedicada, os engenheiros que constroem o sistema muitas vezes desempenham essa função, consciente ou inconscientemente.

Há muitos fatores a serem considerados ao avaliar a tolerância ao risco dos serviços, como por exemplo:

  • Qual é o nível de disponibilidade necessário?
  • Diferentes tipos de falhas têm efeitos diferentes no serviço?
  • Como podemos usar o custo para ajudar a localizar um serviço no continuum de risco?
  • Quais outras métricas de serviço são importantes para levar em consideração?

Nível de disponibilidade desejado

O nível de disponibilidade desejado para um determinado serviço do Google geralmente depende da função que ele fornece e de como o serviço está posicionado no mercado. A lista a seguir inclui questões a serem consideradas:

  • Qual nível de serviço os usuários esperam?
  • Este serviço está diretamente vinculado à receita (seja nossa receita ou receita de nossos clientes)?
  • Este é um serviço pago ou gratuito?
  • Se houver concorrentes no mercado, que nível de serviço esses concorrentes oferecem?
  • Este serviço é dirigido a consumidores ou a empresas?

Considere os requisitos do Google Apps for Work. A maioria dos usuários são corporativos, alguns grandes e outros pequenos. Essas empresas dependem dos serviços do Google Apps for Work (por exemplo, Gmail, Agenda, Drive, Docs) para fornecer ferramentas que permitem que seus funcionários realizem seu trabalho diário. Dito de outra forma, uma interrupção de um serviço do Google Apps for Work é uma interrupção não apenas do Google, mas também de todas as empresas que dependem criticamente de nós. Para um serviço típico do Google Apps for Work, podemos definir uma meta de disponibilidade externa trimestral de 99,9% e apoiar essa meta com outra de disponibilidade interna mais forte e um contrato que estipula penalidades se deixarmos de entregar ao destino externo.

O YouTube oferece um conjunto contrastante de considerações. Quando o Google adquiriu o YouTube, tivemos que decidir sobre a meta de disponibilidade apropriada para o site. Em 2006, o YouTube estava focado nos consumidores e estava em uma fase muito diferente de seu ciclo de vida de negócios do Google na época. Embora o YouTube já tivesse um ótimo produto, ele ainda estava mudando e crescendo rapidamente. Definimos uma meta de disponibilidade mais baixa para o YouTube do que para nossos produtos empresariais porque o desenvolvimento rápido de recursos era mais importante naquele momento.

Tipos de falhas

A forma esperada de falhas para um determinado serviço é outra consideração importante. Quão resiliente é nosso negócio em relação ao tempo de inatividade do serviço? O que é pior para o serviço: uma taxa baixa e constante de falhas ou uma interrupção ocasional de todo o site? Ambos os tipos de falhas podem resultar no mesmo número absoluto de erros, mas podem ter impactos muito diferentes nos negócios.

Um exemplo ilustrativo da diferença entre interrupções totais e parciais surge naturalmente em sistemas que fornecem informações privadas. Considere um aplicativo de gerenciamento de contato e a diferença entre as falhas intermitentes que fazem com que as imagens do perfil falhem ao renderizar e um caso de falha que resulta na exibição dos contatos privados de um usuário para outro usuário. O primeiro caso é claramente uma experiência do usuário ruim, e os SREs funcionariam para remediar o problema rapidamente. No segundo caso, entretanto, o risco de expor dados privados poderia facilmente minar a confiança do usuário básico de uma maneira significativa. Como resultado, desligar totalmente o serviço seria apropriado durante a depuração e a fase de limpeza potencial para o segundo caso.

Na outra ponta dos serviços oferecidos pelo Google, às vezes é aceitável ter interrupções regulares durante as janelas de manutenção. Há alguns anos, o Ads Frontend costumava ser um desses serviços. É usado por anunciantes e editores de sites para definir, configurar, executar e monitorar suas campanhas publicitárias. Como a maior parte desse trabalho ocorre durante o horário comercial normal, determinamos que interrupções ocasionais, regulares e programadas na forma de janelas de manutenção seriam aceitáveis e contamos essas interrupções programadas como tempo de inatividade planejado, não tempo de inatividade não planejado.

Custo

O custo costuma ser o fator-chave para determinar a meta de disponibilidade apropriada para um serviço. Os anúncios estão em uma posição particularmente boa para fazer essa troca, pois os sucessos e falhas de solicitações podem ser traduzidos diretamente em receita ganha ou perdida. Ao determinar a meta de disponibilidade para cada serviço, fazemos perguntas como:

  • Se tivéssemos de construir e operar esses sistemas com mais nove de disponibilidade, qual seria nosso aumento incremental na receita?
  • Essa receita adicional compensa o custo de atingir esse nível de confiabilidade?

Para tornar esta equação de troca mais concreta, considere o seguinte custo/benefício para um serviço de exemplo onde cada solicitação tem o mesmo valor:

  • Melhoria proposta na meta de disponibilidade: 99,9% → 99,99%
  • Aumento proposto na disponibilidade: 0,09%
  • Receita do serviço: $1M
  • Valor da disponibilidade aprimorada: $1M * 0,0009 = $ 900

Nesse caso, se o custo de aumentar a disponibilidade em um nove for menor que $900, o investimento vale a pena. Se o custo for maior que $900, os custos excederão o aumento projetado na receita.

Pode ser mais difícil definir essas metas quando não temos uma função de tradução simples entre confiabilidade e receita. Uma estratégia útil pode ser considerar a taxa de erro de plano de fundo dos ISPs na Internet. Se as falhas estão sendo medidas da perspectiva do usuário final e é possível conduzir a taxa de erro para o serviço abaixo da taxa de erro de fundo, esses erros cairão no ruído para a conexão de Internet de um determinado usuário. Embora existam diferenças significativas entre ISPs e protocolos (por exemplo, TCP versus UDP, IPv4 versus IPv6), medimos a taxa de erro de fundo típica para ISPs caindo entre 0,01% e 1%.

Outras métricas de serviço

Examinar a tolerância ao risco dos serviços em relação às métricas além da disponibilidade costuma ser proveitoso. Entender quais métricas são importantes e quais não são importantes nos fornece graus de liberdade ao tentar assumir riscos ponderados.

A latência do serviço para nossos sistemas de anúncios fornece um exemplo ilustrativo. Quando o Google lançou a Pesquisa na Web pela primeira vez, um dos principais recursos diferenciadores do serviço era a velocidade. Quando introduzimos o AdWords, que exibe anúncios ao lado dos resultados de pesquisa, um dos principais requisitos do sistema era que os anúncios não retardassem a experiência de pesquisa. Esse requisito impulsionou as metas de engenharia em cada geração de sistemas AdWords e é tratado como invariável.

AdSense, o sistema de anúncios do Google que veicula anúncios contextuais em resposta a solicitações de código JavaScript que os editores inserem em seus sites, tem uma meta de latência muito diferente. A meta de latência do AdSense é evitar a desaceleração da renderização da página de terceiros ao inserir anúncios contextuais. A meta de latência específica, então, depende da velocidade com que a página de um determinado editor é renderizada. Isso significa que os anúncios do AdSense geralmente podem ser veiculados centenas de milissegundos mais lentamente do que os anúncios do AdWords.

Esse requisito de latência de serviço mais flexível nos permitiu fazer muitas compensações inteligentes no provisionamento (ou seja, determinar a quantidade e os locais dos recursos de serviço que usamos), o que nos economiza custos substanciais em relação ao provisionamento ingênuo. Em outras palavras, dada a relativa insensibilidade do serviço AdSense a mudanças moderadas no desempenho de latência, podemos consolidar a veiculação em menos localizações geográficas, reduzindo nossa sobrecarga operacional.

Identificando a tolerância ao risco de serviços de infraestrutura

Os requisitos para construir e executar componentes de infraestrutura diferem dos requisitos para produtos de consumo de várias maneiras. Uma diferença fundamental é que, por definição, os componentes da infraestrutura têm vários clientes, geralmente com necessidades variadas.

Nível de disponibilidade alvo

Considere o Bigtable, um sistema de armazenamento distribuído em grande escala para dados estruturados. Alguns serviços ao consumidor fornecem dados diretamente do Bigtable no caminho de uma solicitação do usuário. Esses serviços precisam de baixa latência e alta confiabilidade. Outras equipes usam o Bigtable como um repositório de dados que usam para realizar análises offline (por exemplo, MapReduce) regularmente. Essas equipes tendem a se preocupar mais com o rendimento do que com a confiabilidade. A tolerância ao risco para esses dois casos de uso é bastante distinta.

Uma abordagem para atender às necessidades de ambos os casos de uso é projetar todos os serviços de infraestrutura para serem ultraconfiáveis. Dado o fato de que esses serviços de infraestrutura também tendem a agregar grandes quantidades de recursos, essa abordagem costuma ser muito cara na prática. Para entender as diferentes necessidades dos diferentes tipos de usuários, você pode observar o estado desejado da fila de solicitações para cada tipo de usuário do Bigtable.

Tipos de falhas

O usuário de baixa latência deseja que as filas de solicitações do Bigtable estejam (quase sempre) vazias para que o sistema possa processar cada solicitação pendente imediatamente após a chegada. (Na verdade, o enfileiramento ineficiente costuma ser uma causa de latência de cauda alta). O usuário preocupado com a análise offline está mais interessado no rendimento do sistema, de modo que deseja que as filas de solicitação nunca fiquem vazias. Para otimizar a taxa de transferência, o sistema Bigtable nunca deve ficar inativo enquanto aguarda sua próxima solicitação.

Como você pode ver, o sucesso e o fracasso são antitéticos para esses conjuntos de usuários. O sucesso do usuário de baixa latência é o fracasso do usuário preocupado com a análise offline.

Custo

Uma maneira de satisfazer essas restrições concorrentes de maneira econômica é particionar a infraestrutura e oferecê-la em vários níveis independentes de serviço. No exemplo Bigtable, podemos construir dois tipos de clusters: clusters de baixa latência e clusters de rendimento. Os clusters de baixa latência são projetados para serem operados e usados por serviços que precisam de baixa latência e alta confiabilidade. Para garantir comprimentos de fila curtos e satisfazer requisitos de isolamento de cliente mais rigorosos, o sistema Bigtable pode ser provisionado com uma quantidade substancial de capacidade de folga para contenção reduzida e redundância aumentada. Os clusters de rendimento, por outro lado, podem ser provisionados para rodar muito quente e com menos redundância, otimizando o rendimento sobre a latência. Na prática, somos capazes de satisfazer essas necessidades relaxadas a um custo muito menor, talvez de 10% a 50% do custo de um cluster de baixa latência. Dada a escala maciça do Bigtable, essa economia de custo se torna significativa muito rapidamente.

A principal estratégia com relação à infraestrutura é fornecer serviços com níveis de serviço explicitamente delineados, permitindo que os clientes façam as compensações corretas de risco e custo ao construir seus sistemas. Com níveis de serviço explicitamente delineados, os provedores de infraestrutura podem externalizar efetivamente a diferença no custo necessário para fornecer serviço em um determinado nível aos clientes. Expor o custo dessa forma motiva os clientes a escolherem o nível de serviço com o menor custo que ainda atenda às suas necessidades. Por exemplo, o Google+ pode decidir colocar dados essenciais para garantir a privacidade do usuário em um armazenamento de dados globalmente consistente e de alta disponibilidade (por exemplo, um sistema semelhante a SQL replicado globalmente como o Spanner), enquanto coloca dados opcionais (dados que não são críticos, mas que aprimoram a experiência do usuário) em um armazenamento de dados mais barato, menos confiável, menos atualizado e eventualmente consistente (por exemplo, um armazenamento NoSQL com replicação de melhor esforço como o Bigtable).

Observe que podemos executar várias classes de serviços usando hardware e software idênticos. Podemos fornecer garantias de serviço muito diferentes ajustando uma variedade de características de serviço, como as quantidades de recursos, o grau de redundância, as restrições de provisionamento geográfico e, criticamente, a configuração do software de infraestrutura.

Exemplo: infraestrutura de frontend

Para demonstrar que esses princípios de avaliação de tolerância ao risco não se aplicam apenas à infraestrutura de armazenamento, vamos examinar outra grande classe de serviço: a infraestrutura de frontend do Google. A infraestrutura de frontend consiste em proxy reverso e sistemas de balanceamento de carga executados próximos à borda de nossa rede. Estes são os sistemas que, entre outras coisas, servem como um ponto de extremidade (endpoint) das conexões dos usuários finais (por exemplo, encerram o TCP do navegador do usuário). Devido à sua função crítica, projetamos esses sistemas para fornecer um nível extremamente alto de confiabilidade. Embora os serviços ao consumidor muitas vezes possam limitar a visibilidade da falta de confiabilidade nos backends, esses sistemas de infraestrutura não têm tanta sorte. Se uma solicitação nunca chegar ao servidor frontend do serviço de aplicativo, ela será perdida.

Até aqui, exploramos as maneiras de identificar a tolerância ao risco de serviços de consumo e de infraestrutura. Agora, vamos discutir o uso desse nível de tolerância para gerenciar a falta de confiabilidade via error budgets (orçamento de erro).


Motivação para Error Budgets

Escrito por Mark Roth
Editado por Carmela Quinito

Outros capítulos deste livro discutem como as tensões podem surgir entre as equipes de desenvolvimento de produto e as equipes de SRE, visto que geralmente são avaliadas em métricas diferentes. O desempenho do desenvolvimento do produto é amplamente avaliado pela velocidade do mesmo, o que cria um incentivo para enviar um novo código o mais rápido possível. Enquanto isso, o desempenho do SRE é (sem surpresa) avaliado com base na confiabilidade de um serviço, o que implica um incentivo para resistir a uma alta taxa de mudança. A assimetria de informação entre as duas equipes amplifica ainda mais essa tensão inerente. Os desenvolvedores de produto têm mais visibilidade sobre o tempo e esforço envolvidos na escrita e liberação de seu código, enquanto os SREs têm mais visibilidade sobre a confiabilidade do serviço (e o estado de produção em geral).

Essas tensões geralmente se refletem em opiniões diferentes sobre o nível de esforço que deve ser colocado nas práticas de engenharia. A lista a seguir apresenta algumas tensões típicas:

Tolerância a falhas de software

Até que ponto tornamos o software resistente a eventos inesperados? No mínimo, temos um produto quebradiço e inutilizável; no máximo, temos um produto que ninguém quer usar (mas que funciona de maneira muito estável).

Testando

Novamente, não há testes suficientes e você tem interrupções embaraçosas, vazamentos de dados de privacidade ou uma série de outros eventos dignos de nota. Muitos testes e você pode perder seu mercado.

Frequência push

Todo push é arriscado. Quanto devemos trabalhar para reduzir esse risco x passar para outro trabalho?

Duração e tamanho do canary

É uma prática recomendada testar uma nova versão em algum pequeno subconjunto de uma carga de trabalho típica, uma prática geralmente chamada canarying. Quanto tempo aguardamos e qual deve ser o tamanho do canary?

Normalmente, as equipes preexistentes elaboraram algum tipo de equilíbrio informal entre elas quanto ao limite de risco/esforço que devem ser empregados. Infelizmente, raramente se pode provar que esse equilíbrio é ideal, ao invés de apenas uma função das habilidades de negociação dos engenheiros envolvidos. Nem devem essas decisões ser motivadas por política, medo ou esperança. (Na verdade, o lema não oficial do Google SRE é “Esperança não é uma estratégia”). Em vez disso, nosso objetivo é definir uma métrica objetiva, acordada por ambos os lados, que pode ser usada para orientar as negociações de forma reproduzível. Quanto mais baseada em dados a decisão puder ser, melhor.

Formando seu error budget

A fim de basear essas decisões em dados objetivos, as duas equipes definem em conjunto um error budgets trimestral com base no objetivo de nível de serviço, ou SLO de serviço (consulte o capítulo 4). O error budget fornece uma métrica clara e objetiva que determina o nível de confiabilidade de um serviço em um único trimestre. Essa métrica remove a política das negociações entre os SREs e os desenvolvedores de produto ao decidir quanto risco permitir.

Nossa prática é então a seguinte:

  • O Gerenciamento de Produtos define um SLO, que define uma expectativa de quanto tempo de atividade o serviço deve ter por trimestre
  • O tempo de atividade real é medido por um terceiro neutro: nosso sistema de monitoramento
  • A diferença entre esses dois números é o “orçamento” de quanta “falta de confiabilidade” resta para o trimestre
  • Contanto que o tempo de atividade medido esteja acima do SLO – em outras palavras, enquanto houver orçamento de erro restante – novos lançamentos podem ser enviados.

Por exemplo, imagine que o SLO de um serviço deve atender com êxito 99,999% de todas as consultas por trimestre. Isso significa que o error budgets do serviço é uma taxa de falha de 0,001% para um determinado trimestre. Se um problema fizer com que falhemos 0,0002% das consultas esperadas para o trimestre, o problema gasta 20% do error budgets trimestral do serviço.

Benefícios

O principal benefício de um error budget é que ele fornece um incentivo comum que permite que o desenvolvimento de produto e o SRE se concentrem em encontrar o equilíbrio certo entre inovação e confiabilidade.

Muitos produtos usam este loop de controle para gerenciar a velocidade de liberação: desde que os SLOs do sistema sejam atendidos, as liberações podem continuar. Se as violações de SLO ocorrerem com frequência suficiente para gastar o error budgets, as versões serão temporariamente interrompidas enquanto recursos adicionais são investidos no teste e desenvolvimento do sistema para torná-lo mais resiliente, melhorar seu desempenho e assim por diante. Abordagens mais sutis e eficazes estão disponíveis do que esta técnica simples de ligar/desligar (conhecido como controle “bang/bang“): por exemplo, desacelerar as liberações ou revertê-las quando o orçamento para erros de violação de SLO estiver perto de ser usado.

Por exemplo, se o desenvolvimento do produto quiser economizar nos testes ou aumentar a velocidade de envio e o SRE for resistente, o error budgets orientará a decisão. Quando o orçamento é grande, os desenvolvedores de produtos podem correr mais riscos. Quando o orçamento está quase esgotado, os próprios desenvolvedores de produto pressionam por mais testes ou velocidade de envio mais lenta, já que não querem correr o risco de esgotar o orçamento e atrasar o lançamento. Com efeito, a equipe de desenvolvimento de produto torna-se autopoliciadora. Eles conhecem o orçamento e podem administrar seus próprios riscos. (Obviamente, esse resultado depende de uma equipe de SRE com autoridade para realmente interromper os lançamentos se o SLO for quebrado).

O que acontecerá se uma interrupção da rede ou falha do datacenter reduzir o SLO medido? Esses eventos também corroem o error budgets. Como resultado, o número de novos pushes pode ser reduzido para o restante do trimestre. Toda a equipe apoia essa redução porque todos compartilham a responsabilidade pelo tempo de atividade.

O orçamento também ajuda a destacar alguns dos custos de metas de confiabilidade excessivamente altas, em termos de inflexibilidade e inovação lenta. Se a equipe está tendo problemas para lançar novos recursos, eles podem optar por afrouxar o SLO (aumentando assim o error budgets) a fim de impulsionar a inovação.

Pontos principais

  • O gerenciamento da confiabilidade do serviço envolve principalmente o gerenciamento de riscos, e o gerenciamento de riscos pode ser caro
  • 100% provavelmente nunca é a meta certa de confiabilidade: não apenas é impossível de alcançar, mas normalmente é mais confiável do que os usuários de um serviço desejam ou percebem. Combine o perfil do serviço com o risco que a empresa está disposta a correr
  • Um error budgets alinha os incentivos e enfatiza a propriedade conjunta entre SRE e o desenvolvimento do produto. Os error budgets tornam mais fácil decidir a taxa de lançamentos e neutralizar efetivamente as discussões sobre interrupções com as partes interessadas, e permite ainda que várias equipes cheguem à mesma conclusão sobre o risco de produção sem rancor. 

Capítulo 3 – Abraçando o Risco

Capítulo 3 – Abraçando o Risco

Escrito por Marc Alvidrez
Editado por Kavita Guliani

Você pode esperar que o Google tente construir serviços 100% confiáveis – aqueles que nunca falham. Acontece que depois de um certo ponto, porém, aumentar a confiabilidade acaba sendo muito pior para um serviço (e seus usuários). A razão para isso é que a confiabilidade extrema tem um custo: maximizar a estabilidade limita a rapidez com que novos recursos podem ser desenvolvidos e os produtos podem ser entregues aos usuários, e aumenta drasticamente seu custo, o que, por sua vez, reduz o número de recursos que uma equipe pode oferecer.

Além disso, os usuários normalmente não percebem a diferença entre alta confiabilidade e extrema confiabilidade em um serviço, porque a experiência do usuário é dominada por componentes menos confiáveis, como a rede celular ou o dispositivo com o qual estão trabalhando. Em resumo, um usuário de um smartphone 99% confiável simplesmente não pode dizer a diferença entre 99,99% e 99,999% de confiabilidade de um serviço! Com isso em mente, em vez de simplesmente maximizar o tempo de atividade, o Site Reliability Engineering busca equilibrar o risco de indisponibilidade com os objetivos de inovação rápida e operações de serviço eficientes, de modo que a felicidade geral dos usuários – com recursos, serviço e desempenho – seja otimizada.

Gestão de Risco

Sistemas não confiáveis podem corroer rapidamente a confiança dos usuários, portanto, queremos reduzir a chance de falha do sistema. No entanto, a experiência mostra que, à medida que construímos sistemas, o custo não aumenta linearmente na proporção em que aumenta a confiabilidade – na verdade, uma melhoria incremental na confiabilidade pode custar cerca de 100 vezes mais do que o incremento anterior. O custo tem duas dimensões:

O custo de recursos redundantes de máquina/computação

É o custo associado a equipamentos redundantes que, por exemplo, nos permite desligar os sistemas para manutenção imprevista ou de rotina; ou ainda nos dá espaço para armazenar blocos de paridade de código que fornecem uma garantia mínima de durabilidade dos dados.

O custo de oportunidade

É o custo suportado por uma organização quando ela aloca recursos de engenharia para construir sistemas ou recursos que diminuem o risco, em vez de recursos que são diretamente visíveis ou utilizáveis pelos usuários finais. Esses engenheiros não trabalham mais em novos recursos e produtos para usuários finais.

No SRE, gerenciamos a confiabilidade do serviço em grande parte gerenciando o risco. Conceitualizamos o risco como um continuum. Damos igual importância a descobrir como criar maior confiabilidade nos sistemas do Google e a identificar o nível apropriado de tolerância para os serviços que executamos. Isso nos permite realizar uma análise de custo/benefício para determinar, por exemplo, onde no continuum de risco (não linear) devemos colocar Pesquisa, Anúncios, Gmail ou Fotos. Nosso objetivo é alinhar explicitamente o risco assumido por um determinado serviço com o risco que o negócio está disposto a assumir. Nós nos esforçamos para tornar um serviço confiável o suficiente, mas não mais confiável do que o necessário. Ou seja, quando estabelecemos uma meta de disponibilidade de 99,99%, queremos superá-la, mas não muito: isso desperdiçaria oportunidades de agregar funcionalidades ao sistema, sanear débitos técnicos ou reduzir seus custos operacionais. De certa forma, vemos a meta de disponibilidade como mínima e máxima. A principal vantagem desse enquadramento é que ele desbloqueia a tomada de riscos de forma explícita e mas também cuidadosa.

Medindo o risco do serviço

Como prática padrão no Google, geralmente somos mais bem atendidos identificando uma métrica objetiva para representar a propriedade de um sistema que desejamos otimizar. Ao definir uma meta, podemos avaliar nosso desempenho atual e rastrear melhorias ou degradações ao longo do tempo. Para o risco do serviço, não está imediatamente claro como reduzir todos os fatores potenciais em uma única métrica. As falhas de serviço podem ter muitos efeitos potenciais, incluindo insatisfação do usuário, prejuízo ou perda de confiança; perda de receita direta ou indireta; impacto na marca ou na reputação; e cobertura indesejável da imprensa. Claramente, alguns desses fatores são muito difíceis de medir. Para tornar esse problema tratável e consistente em muitos tipos de sistemas que executamos, nos concentramos no tempo de inatividade não planejado.

Para a maioria dos serviços, a forma mais direta de representar a tolerância ao risco é em termos do nível aceitável de tempo de inatividade não planejado. O tempo de inatividade não planejado é capturado pelo nível de disponibilidade de serviço desejado, geralmente expresso em termos do número de “noves” que gostaríamos de fornecer: disponibilidade de 99,9%, 99,99% ou 99,999%. Cada nove adicional corresponde a uma melhoria da ordem de magnitude em direção a 100% de disponibilidade. Para sistemas de serviço, essa métrica é tradicionalmente calculada com base na proporção do tempo de atividade do sistema.

Time-based availability:

availability = uptime / (uptime+downtime)

Usando essa fórmula durante o período de um ano, podemos calcular o número aceitável de minutos de inatividade para atingir um determinado número de noves de disponibilidade. Por exemplo, um sistema com uma meta de disponibilidade de 99,99% pode ficar inativo por até 52,56 minutos em um ano e permanecer dentro de sua meta de disponibilidade; consulte a Availability Table para ver a tabela.

No Google, no entanto, uma métrica de disponibilidade com base no tempo geralmente não é significativa, porque estamos trabalhando com serviços distribuídos globalmente. Nossa abordagem ao isolamento de falhas torna muito provável que estejamos atendendo a pelo menos um subconjunto de tráfego para um determinado serviço em algum lugar do mundo a qualquer momento (ou seja, estamos pelo menos parcialmente “ativos” o tempo todo). Portanto, em vez de usar métricas em torno do tempo de atividade, definimos a disponibilidade em termos da taxa de sucesso da solicitação. A disponibilidade agregada mostra como essa métrica baseada no rendimento é calculada em uma janela contínua (ou seja, a proporção de solicitações bem-sucedidas em uma janela de um dia).

Disponibilidade agregada:

availability = successful requests / total requests

Por exemplo, um sistema que atende 2,5 milhões de solicitações em um dia com uma meta de disponibilidade diária de 99,99% pode atender a até 250 erros e ainda atingir sua meta naquele dia específico.

Em um aplicativo típico, nem todas as solicitações são iguais: a falha na solicitação de inscrição de um novo usuário é diferente da falha em uma pesquisa de solicitação de novo e-mail em segundo plano. Em muitos casos, no entanto, a disponibilidade calculada como a taxa de sucesso da solicitação sobre todas as solicitações é uma aproximação razoável do tempo de inatividade não planejado, visto da perspectiva do usuário final.

Quantificar o tempo de inatividade não planejado como uma taxa de sucesso na solicitação também torna essa métrica de disponibilidade mais acessível para uso em sistemas que normalmente não atendem diretamente aos usuários finais. A maioria dos sistemas não operacionais (por exemplo: lote, pipeline, armazenamento e sistemas transacionais) tem uma noção bem definida de unidades de trabalho bem-sucedidas e malsucedidas. De fato, embora os sistemas discutidos neste capítulo sejam principalmente sistemas de atendimento ao consumidor e à infraestrutura, muitos dos mesmos princípios também se aplicam a outros sistemas com modificação mínima.

Por exemplo, um processo em lote que extrai, transforma e insere o conteúdo de um de nossos bancos de dados de clientes em um data warehouse para permitir análises posteriores pode ser configurado para ser executado periodicamente. Usando uma taxa de sucesso de solicitação definida em termos de registros processados com e sem sucesso, podemos calcular uma métrica de disponibilidade útil, apesar do fato de o sistema em lote não funcionar constantemente.

Na maioria das vezes, definimos metas de disponibilidade trimestrais para um serviço e rastreamos nosso desempenho em relação a essas metas semanalmente ou mesmo diariamente. Essa estratégia nos permite gerenciar o serviço com um objetivo de disponibilidade de alto nível, procurando, rastreando e corrigindo desvios significativos à medida que inevitavelmente surgirem. Veja Service Level Objectives para mais detalhes.

Tolerância a risco dos serviços

O que significa identificar a tolerância ao risco de um serviço? Em um ambiente formal ou no caso de sistemas críticos para a segurança, a tolerância ao risco dos serviços é normalmente construída diretamente no produto básico ou na definição do serviço. No Google, a tolerância ao risco dos serviços tende a ser definida com menos clareza.

Para identificar a tolerância ao risco de um serviço, os SREs devem trabalhar com os proprietários do produto para transformar um conjunto de metas de negócios em objetivos explícitos para os quais podemos projetar. Nesse caso, as metas de negócios que nos preocupam têm um impacto direto no desempenho e na confiabilidade do serviço oferecido. Na prática, essa tradução é mais fácil de falar do que fazer. Embora os serviços ao consumidor muitas vezes tenham proprietários de produtos claros, é incomum que serviços de infraestrutura (por exemplo, sistemas de armazenamento ou uma camada de cache HTTP de uso geral) tenham uma estrutura semelhante de propriedade do produto. Discutiremos os casos do consumidor e da infraestrutura mais adiante.

Identificando a tolerância ao risco de serviços ao consumidor

Nossos serviços ao consumidor costumam ter uma equipe de produto que atua como o proprietário do negócio para um aplicativo. Por exemplo: Pesquisa, Google Maps e Google Docs, cada um tem seus próprios gerentes de produto. Esses gerentes de produto são encarregados de compreender os usuários e os negócios e de moldar o produto para o sucesso no mercado. Quando existe uma equipe de produto, essa equipe geralmente é o melhor recurso para discutir os requisitos de confiabilidade de um serviço. Na ausência de uma equipe de produto dedicada, os engenheiros que constroem o sistema muitas vezes desempenham essa função, consciente ou inconscientemente.

Há muitos fatores a serem considerados ao avaliar a tolerância ao risco dos serviços, como por exemplo:

  • Qual é o nível de disponibilidade necessário?
  • Diferentes tipos de falhas têm efeitos diferentes no serviço?
  • Como podemos usar o custo para ajudar a localizar um serviço no continuum de risco?
  • Quais outras métricas de serviço são importantes para levar em consideração?

Nível de disponibilidade desejado

O nível de disponibilidade desejado para um determinado serviço do Google geralmente depende da função que ele fornece e de como o serviço está posicionado no mercado. A lista a seguir inclui questões a serem consideradas:

  • Qual nível de serviço os usuários esperam?
  • Este serviço está diretamente vinculado à receita (seja nossa receita ou receita de nossos clientes)?
  • Este é um serviço pago ou gratuito?
  • Se houver concorrentes no mercado, que nível de serviço esses concorrentes oferecem?
  • Este serviço é dirigido a consumidores ou a empresas?

Considere os requisitos do Google Apps for Work. A maioria dos usuários são corporativos, alguns grandes e outros pequenos. Essas empresas dependem dos serviços do Google Apps for Work (por exemplo, Gmail, Agenda, Drive, Docs) para fornecer ferramentas que permitem que seus funcionários realizem seu trabalho diário. Dito de outra forma, uma interrupção de um serviço do Google Apps for Work é uma interrupção não apenas do Google, mas também de todas as empresas que dependem criticamente de nós. Para um serviço típico do Google Apps for Work, podemos definir uma meta de disponibilidade externa trimestral de 99,9% e apoiar essa meta com outra de disponibilidade interna mais forte e um contrato que estipula penalidades se deixarmos de entregar ao destino externo.

O YouTube oferece um conjunto contrastante de considerações. Quando o Google adquiriu o YouTube, tivemos que decidir sobre a meta de disponibilidade apropriada para o site. Em 2006, o YouTube estava focado nos consumidores e estava em uma fase muito diferente de seu ciclo de vida de negócios do Google na época. Embora o YouTube já tivesse um ótimo produto, ele ainda estava mudando e crescendo rapidamente. Definimos uma meta de disponibilidade mais baixa para o YouTube do que para nossos produtos empresariais porque o desenvolvimento rápido de recursos era mais importante naquele momento.

Tipos de falhas

A forma esperada de falhas para um determinado serviço é outra consideração importante. Quão resiliente é nosso negócio em relação ao tempo de inatividade do serviço? O que é pior para o serviço: uma taxa baixa e constante de falhas ou uma interrupção ocasional de todo o site? Ambos os tipos de falhas podem resultar no mesmo número absoluto de erros, mas podem ter impactos muito diferentes nos negócios.

Um exemplo ilustrativo da diferença entre interrupções totais e parciais surge naturalmente em sistemas que fornecem informações privadas. Considere um aplicativo de gerenciamento de contato e a diferença entre as falhas intermitentes que fazem com que as imagens do perfil falhem ao renderizar e um caso de falha que resulta na exibição dos contatos privados de um usuário para outro usuário. O primeiro caso é claramente uma experiência do usuário ruim, e os SREs funcionariam para remediar o problema rapidamente. No segundo caso, entretanto, o risco de expor dados privados poderia facilmente minar a confiança do usuário básico de uma maneira significativa. Como resultado, desligar totalmente o serviço seria apropriado durante a depuração e a fase de limpeza potencial para o segundo caso.

Na outra ponta dos serviços oferecidos pelo Google, às vezes é aceitável ter interrupções regulares durante as janelas de manutenção. Há alguns anos, o Ads Frontend costumava ser um desses serviços. É usado por anunciantes e editores de sites para definir, configurar, executar e monitorar suas campanhas publicitárias. Como a maior parte desse trabalho ocorre durante o horário comercial normal, determinamos que interrupções ocasionais, regulares e programadas na forma de janelas de manutenção seriam aceitáveis e contamos essas interrupções programadas como tempo de inatividade planejado, não tempo de inatividade não planejado.

Custo

O custo costuma ser o fator-chave para determinar a meta de disponibilidade apropriada para um serviço. Os anúncios estão em uma posição particularmente boa para fazer essa troca, pois os sucessos e falhas de solicitações podem ser traduzidos diretamente em receita ganha ou perdida. Ao determinar a meta de disponibilidade para cada serviço, fazemos perguntas como:

  • Se tivéssemos de construir e operar esses sistemas com mais nove de disponibilidade, qual seria nosso aumento incremental na receita?
  • Essa receita adicional compensa o custo de atingir esse nível de confiabilidade?

Para tornar esta equação de troca mais concreta, considere o seguinte custo/benefício para um serviço de exemplo onde cada solicitação tem o mesmo valor:

  • Melhoria proposta na meta de disponibilidade: 99,9% → 99,99%
  • Aumento proposto na disponibilidade: 0,09%
  • Receita do serviço: $1M
  • Valor da disponibilidade aprimorada: $1M * 0,0009 = $ 900

Nesse caso, se o custo de aumentar a disponibilidade em um nove for menor que $900, o investimento vale a pena. Se o custo for maior que $900, os custos excederão o aumento projetado na receita.

Pode ser mais difícil definir essas metas quando não temos uma função de tradução simples entre confiabilidade e receita. Uma estratégia útil pode ser considerar a taxa de erro de plano de fundo dos ISPs na Internet. Se as falhas estão sendo medidas da perspectiva do usuário final e é possível conduzir a taxa de erro para o serviço abaixo da taxa de erro de fundo, esses erros cairão no ruído para a conexão de Internet de um determinado usuário. Embora existam diferenças significativas entre ISPs e protocolos (por exemplo, TCP versus UDP, IPv4 versus IPv6), medimos a taxa de erro de fundo típica para ISPs caindo entre 0,01% e 1%.

Outras métricas de serviço

Examinar a tolerância ao risco dos serviços em relação às métricas além da disponibilidade costuma ser proveitoso. Entender quais métricas são importantes e quais não são importantes nos fornece graus de liberdade ao tentar assumir riscos ponderados.

A latência do serviço para nossos sistemas de anúncios fornece um exemplo ilustrativo. Quando o Google lançou a Pesquisa na Web pela primeira vez, um dos principais recursos diferenciadores do serviço era a velocidade. Quando introduzimos o AdWords, que exibe anúncios ao lado dos resultados de pesquisa, um dos principais requisitos do sistema era que os anúncios não retardassem a experiência de pesquisa. Esse requisito impulsionou as metas de engenharia em cada geração de sistemas AdWords e é tratado como invariável.

AdSense, o sistema de anúncios do Google que veicula anúncios contextuais em resposta a solicitações de código JavaScript que os editores inserem em seus sites, tem uma meta de latência muito diferente. A meta de latência do AdSense é evitar a desaceleração da renderização da página de terceiros ao inserir anúncios contextuais. A meta de latência específica, então, depende da velocidade com que a página de um determinado editor é renderizada. Isso significa que os anúncios do AdSense geralmente podem ser veiculados centenas de milissegundos mais lentamente do que os anúncios do AdWords.

Esse requisito de latência de serviço mais flexível nos permitiu fazer muitas compensações inteligentes no provisionamento (ou seja, determinar a quantidade e os locais dos recursos de serviço que usamos), o que nos economiza custos substanciais em relação ao provisionamento ingênuo. Em outras palavras, dada a relativa insensibilidade do serviço AdSense a mudanças moderadas no desempenho de latência, podemos consolidar a veiculação em menos localizações geográficas, reduzindo nossa sobrecarga operacional.

Identificando a tolerância ao risco de serviços de infraestrutura

Os requisitos para construir e executar componentes de infraestrutura diferem dos requisitos para produtos de consumo de várias maneiras. Uma diferença fundamental é que, por definição, os componentes da infraestrutura têm vários clientes, geralmente com necessidades variadas.

Nível de disponibilidade alvo

Considere o Bigtable, um sistema de armazenamento distribuído em grande escala para dados estruturados. Alguns serviços ao consumidor fornecem dados diretamente do Bigtable no caminho de uma solicitação do usuário. Esses serviços precisam de baixa latência e alta confiabilidade. Outras equipes usam o Bigtable como um repositório de dados que usam para realizar análises offline (por exemplo, MapReduce) regularmente. Essas equipes tendem a se preocupar mais com o rendimento do que com a confiabilidade. A tolerância ao risco para esses dois casos de uso é bastante distinta.

Uma abordagem para atender às necessidades de ambos os casos de uso é projetar todos os serviços de infraestrutura para serem ultraconfiáveis. Dado o fato de que esses serviços de infraestrutura também tendem a agregar grandes quantidades de recursos, essa abordagem costuma ser muito cara na prática. Para entender as diferentes necessidades dos diferentes tipos de usuários, você pode observar o estado desejado da fila de solicitações para cada tipo de usuário do Bigtable.

Tipos de falhas

O usuário de baixa latência deseja que as filas de solicitações do Bigtable estejam (quase sempre) vazias para que o sistema possa processar cada solicitação pendente imediatamente após a chegada. (Na verdade, o enfileiramento ineficiente costuma ser uma causa de latência de cauda alta). O usuário preocupado com a análise offline está mais interessado no rendimento do sistema, de modo que deseja que as filas de solicitação nunca fiquem vazias. Para otimizar a taxa de transferência, o sistema Bigtable nunca deve ficar inativo enquanto aguarda sua próxima solicitação.

Como você pode ver, o sucesso e o fracasso são antitéticos para esses conjuntos de usuários. O sucesso do usuário de baixa latência é o fracasso do usuário preocupado com a análise offline.

Custo

Uma maneira de satisfazer essas restrições concorrentes de maneira econômica é particionar a infraestrutura e oferecê-la em vários níveis independentes de serviço. No exemplo Bigtable, podemos construir dois tipos de clusters: clusters de baixa latência e clusters de rendimento. Os clusters de baixa latência são projetados para serem operados e usados por serviços que precisam de baixa latência e alta confiabilidade. Para garantir comprimentos de fila curtos e satisfazer requisitos de isolamento de cliente mais rigorosos, o sistema Bigtable pode ser provisionado com uma quantidade substancial de capacidade de folga para contenção reduzida e redundância aumentada. Os clusters de rendimento, por outro lado, podem ser provisionados para rodar muito quente e com menos redundância, otimizando o rendimento sobre a latência. Na prática, somos capazes de satisfazer essas necessidades relaxadas a um custo muito menor, talvez de 10% a 50% do custo de um cluster de baixa latência. Dada a escala maciça do Bigtable, essa economia de custo se torna significativa muito rapidamente.

A principal estratégia com relação à infraestrutura é fornecer serviços com níveis de serviço explicitamente delineados, permitindo que os clientes façam as compensações corretas de risco e custo ao construir seus sistemas. Com níveis de serviço explicitamente delineados, os provedores de infraestrutura podem externalizar efetivamente a diferença no custo necessário para fornecer serviço em um determinado nível aos clientes. Expor o custo dessa forma motiva os clientes a escolherem o nível de serviço com o menor custo que ainda atenda às suas necessidades. Por exemplo, o Google+ pode decidir colocar dados essenciais para garantir a privacidade do usuário em um armazenamento de dados globalmente consistente e de alta disponibilidade (por exemplo, um sistema semelhante a SQL replicado globalmente como o Spanner), enquanto coloca dados opcionais (dados que não são críticos, mas que aprimoram a experiência do usuário) em um armazenamento de dados mais barato, menos confiável, menos atualizado e eventualmente consistente (por exemplo, um armazenamento NoSQL com replicação de melhor esforço como o Bigtable).

Observe que podemos executar várias classes de serviços usando hardware e software idênticos. Podemos fornecer garantias de serviço muito diferentes ajustando uma variedade de características de serviço, como as quantidades de recursos, o grau de redundância, as restrições de provisionamento geográfico e, criticamente, a configuração do software de infraestrutura.

Exemplo: infraestrutura de frontend

Para demonstrar que esses princípios de avaliação de tolerância ao risco não se aplicam apenas à infraestrutura de armazenamento, vamos examinar outra grande classe de serviço: a infraestrutura de frontend do Google. A infraestrutura de frontend consiste em proxy reverso e sistemas de balanceamento de carga executados próximos à borda de nossa rede. Estes são os sistemas que, entre outras coisas, servem como um ponto de extremidade (endpoint) das conexões dos usuários finais (por exemplo, encerram o TCP do navegador do usuário). Devido à sua função crítica, projetamos esses sistemas para fornecer um nível extremamente alto de confiabilidade. Embora os serviços ao consumidor muitas vezes possam limitar a visibilidade da falta de confiabilidade nos backends, esses sistemas de infraestrutura não têm tanta sorte. Se uma solicitação nunca chegar ao servidor frontend do serviço de aplicativo, ela será perdida.

Até aqui, exploramos as maneiras de identificar a tolerância ao risco de serviços de consumo e de infraestrutura. Agora, vamos discutir o uso desse nível de tolerância para gerenciar a falta de confiabilidade via error budgets (orçamento de erro).


Motivação para Error Budgets

Escrito por Mark Roth
Editado por Carmela Quinito

Outros capítulos deste livro discutem como as tensões podem surgir entre as equipes de desenvolvimento de produto e as equipes de SRE, visto que geralmente são avaliadas em métricas diferentes. O desempenho do desenvolvimento do produto é amplamente avaliado pela velocidade do mesmo, o que cria um incentivo para enviar um novo código o mais rápido possível. Enquanto isso, o desempenho do SRE é (sem surpresa) avaliado com base na confiabilidade de um serviço, o que implica um incentivo para resistir a uma alta taxa de mudança. A assimetria de informação entre as duas equipes amplifica ainda mais essa tensão inerente. Os desenvolvedores de produto têm mais visibilidade sobre o tempo e esforço envolvidos na escrita e liberação de seu código, enquanto os SREs têm mais visibilidade sobre a confiabilidade do serviço (e o estado de produção em geral).

Essas tensões geralmente se refletem em opiniões diferentes sobre o nível de esforço que deve ser colocado nas práticas de engenharia. A lista a seguir apresenta algumas tensões típicas:

Tolerância a falhas de software

Até que ponto tornamos o software resistente a eventos inesperados? No mínimo, temos um produto quebradiço e inutilizável; no máximo, temos um produto que ninguém quer usar (mas que funciona de maneira muito estável).

Testando

Novamente, não há testes suficientes e você tem interrupções embaraçosas, vazamentos de dados de privacidade ou uma série de outros eventos dignos de nota. Muitos testes e você pode perder seu mercado.

Frequência push

Todo push é arriscado. Quanto devemos trabalhar para reduzir esse risco x passar para outro trabalho?

Duração e tamanho do canary

É uma prática recomendada testar uma nova versão em algum pequeno subconjunto de uma carga de trabalho típica, uma prática geralmente chamada canarying. Quanto tempo aguardamos e qual deve ser o tamanho do canary?

Normalmente, as equipes preexistentes elaboraram algum tipo de equilíbrio informal entre elas quanto ao limite de risco/esforço que devem ser empregados. Infelizmente, raramente se pode provar que esse equilíbrio é ideal, ao invés de apenas uma função das habilidades de negociação dos engenheiros envolvidos. Nem devem essas decisões ser motivadas por política, medo ou esperança. (Na verdade, o lema não oficial do Google SRE é “Esperança não é uma estratégia”). Em vez disso, nosso objetivo é definir uma métrica objetiva, acordada por ambos os lados, que pode ser usada para orientar as negociações de forma reproduzível. Quanto mais baseada em dados a decisão puder ser, melhor.

Formando seu error budget

A fim de basear essas decisões em dados objetivos, as duas equipes definem em conjunto um error budgets trimestral com base no objetivo de nível de serviço, ou SLO de serviço (consulte o capítulo 4). O error budget fornece uma métrica clara e objetiva que determina o nível de confiabilidade de um serviço em um único trimestre. Essa métrica remove a política das negociações entre os SREs e os desenvolvedores de produto ao decidir quanto risco permitir.

Nossa prática é então a seguinte:

  • O Gerenciamento de Produtos define um SLO, que define uma expectativa de quanto tempo de atividade o serviço deve ter por trimestre
  • O tempo de atividade real é medido por um terceiro neutro: nosso sistema de monitoramento
  • A diferença entre esses dois números é o “orçamento” de quanta “falta de confiabilidade” resta para o trimestre
  • Contanto que o tempo de atividade medido esteja acima do SLO – em outras palavras, enquanto houver orçamento de erro restante – novos lançamentos podem ser enviados.

Por exemplo, imagine que o SLO de um serviço deve atender com êxito 99,999% de todas as consultas por trimestre. Isso significa que o error budgets do serviço é uma taxa de falha de 0,001% para um determinado trimestre. Se um problema fizer com que falhemos 0,0002% das consultas esperadas para o trimestre, o problema gasta 20% do error budgets trimestral do serviço.

Benefícios

O principal benefício de um error budget é que ele fornece um incentivo comum que permite que o desenvolvimento de produto e o SRE se concentrem em encontrar o equilíbrio certo entre inovação e confiabilidade.

Muitos produtos usam este loop de controle para gerenciar a velocidade de liberação: desde que os SLOs do sistema sejam atendidos, as liberações podem continuar. Se as violações de SLO ocorrerem com frequência suficiente para gastar o error budgets, as versões serão temporariamente interrompidas enquanto recursos adicionais são investidos no teste e desenvolvimento do sistema para torná-lo mais resiliente, melhorar seu desempenho e assim por diante. Abordagens mais sutis e eficazes estão disponíveis do que esta técnica simples de ligar/desligar (conhecido como controle “bang/bang“): por exemplo, desacelerar as liberações ou revertê-las quando o orçamento para erros de violação de SLO estiver perto de ser usado.

Por exemplo, se o desenvolvimento do produto quiser economizar nos testes ou aumentar a velocidade de envio e o SRE for resistente, o error budgets orientará a decisão. Quando o orçamento é grande, os desenvolvedores de produtos podem correr mais riscos. Quando o orçamento está quase esgotado, os próprios desenvolvedores de produto pressionam por mais testes ou velocidade de envio mais lenta, já que não querem correr o risco de esgotar o orçamento e atrasar o lançamento. Com efeito, a equipe de desenvolvimento de produto torna-se autopoliciadora. Eles conhecem o orçamento e podem administrar seus próprios riscos. (Obviamente, esse resultado depende de uma equipe de SRE com autoridade para realmente interromper os lançamentos se o SLO for quebrado).

O que acontecerá se uma interrupção da rede ou falha do datacenter reduzir o SLO medido? Esses eventos também corroem o error budgets. Como resultado, o número de novos pushes pode ser reduzido para o restante do trimestre. Toda a equipe apoia essa redução porque todos compartilham a responsabilidade pelo tempo de atividade.

O orçamento também ajuda a destacar alguns dos custos de metas de confiabilidade excessivamente altas, em termos de inflexibilidade e inovação lenta. Se a equipe está tendo problemas para lançar novos recursos, eles podem optar por afrouxar o SLO (aumentando assim o error budgets) a fim de impulsionar a inovação.

Pontos principais

  • O gerenciamento da confiabilidade do serviço envolve principalmente o gerenciamento de riscos, e o gerenciamento de riscos pode ser caro
  • 100% provavelmente nunca é a meta certa de confiabilidade: não apenas é impossível de alcançar, mas normalmente é mais confiável do que os usuários de um serviço desejam ou percebem. Combine o perfil do serviço com o risco que a empresa está disposta a correr
  • Um error budgets alinha os incentivos e enfatiza a propriedade conjunta entre SRE e o desenvolvimento do produto. Os error budgets tornam mais fácil decidir a taxa de lançamentos e neutralizar efetivamente as discussões sobre interrupções com as partes interessadas, e permite ainda que várias equipes cheguem à mesma conclusão sobre o risco de produção sem rancor. 

Experimente agora, grátis!