Pular para o conteúdo

Papers

Canarying Releases (Site Reliability Engineering Workbook)

Alec Warner, Štěpán Davidovič, Alex Hidalgo, Betsy Beyer, Kyle Smith, Matt Duftler · Google SRE Workbook (O'Reilly), cap. 16, 2018

O problema: na experiência do Google, a maioria dos incidentes vem de pushes, e testes não pegam tudo

O capítulo define release engineering como o conjunto de processos e artefatos que levam código de um repositório até um sistema em produção, e lista princípios como builds reproduzíveis e automatizados, testes automatizados, deploys feitos por máquinas e mudanças pequenas e autocontidas. Automatizar releases permite lançar com mais frequência; em software com taxa de mudança não trivial, cada artefato passa a carregar menos mudanças, e fica mais barato e fácil reverter um deles quando há um bug. Os autores tratam velocidade de entrega e confiabilidade como metas que costumam ser vistas como opostas, mas dizem que dá para entregar o mais rápido possível cumprindo as metas de confiabilidade do produto, usando SLOs e error budgets para medir o impacto dos releases. O ponto de partida é uma observação da experiência do Google: a maioria dos incidentes é desencadeada por pushes de binário ou de configuração. Mesmo com pipeline totalmente automatizado, o ambiente de teste não é idêntico à produção e os testes provavelmente não cobrem todos os cenários, então alguns defeitos só aparecem com tráfego real. Se o release vai para todo lugar instantaneamente, o defeito também vai. Uma alternativa mais segura é o canary: expor inicialmente só parte do tráfego de produção à nova versão, para detectar defeitos o mais cedo possível com o menor impacto possível no serviço.

A definição: canary, controle e o custo medido em error budget

O capítulo define canarying como um deploy parcial e limitado no tempo de uma mudança em um serviço, junto com sua avaliação, que ajuda a decidir se o rollout deve prosseguir. A parte do serviço que recebe a mudança é o canary; o restante é o controle. Em geral o canary afeta um subconjunto de produção bem menor que o controle, e o comportamento do canary é comparado com o do controle; por isso o processo é descrito como efetivamente um teste A/B. Os autores listam três requisitos: um método para implantar a mudança em um subconjunto da população do serviço, um processo de avaliação que diga se a mudança é boa ou ruim, e a integração dessas avaliações ao processo de release. O valor do processo aparece quando ele detecta releases ruins com alta confiança e identifica os bons sem falsos positivos. No exemplo do capítulo, uma aplicação simula falha em 20% das requisições. Com deploy global, o serviço arrisca 20% de erro; com um canary de 5% da população, o erro geral fica em 1%. O impacto no error budget é proporcional ao tráfego exposto ao defeito, e os autores assumem que detecção e rollback levam tempo parecido nos dois casos. Eles avisam que é um modelo simples, que assume carga uniforme e falha de 100% no pior caso, e recomendam o modelo mais simples que atenda aos objetivos técnicos e de negócio.

Escolha da população e da duração do canary

Segundo o capítulo, não é preciso uma população enorme de canary para detectar condições críticas básicas, mas um canary representativo exige decisões em várias dimensões. Tamanho e duração: o canary deve ser grande o bastante e durar o suficiente para representar o deploy como um todo; encerrar após poucas requisições não dá sinal útil quando as consultas são diversas, e quanto maior a taxa de processamento, menos tempo se precisa para ter uma amostra representativa. Volume de tráfego: em geral, quanto mais homogêneas as requisições, menos tráfego é necessário. Horário: defeitos de desempenho costumam aparecer só sob carga alta, então um deploy fora do pico provavelmente não os revelaria. Métricas: sucesso de consulta é avaliável rápido, mas outras, como profundidade de fila, podem pedir mais tempo ou mais população. A duração também depende da cadência: quem faz release diário não pode deixar um canary por uma semana se roda um canary por vez, quem faz deploy semanal tem tempo para canaries bem longos, e quem faz deploy contínuo precisa de canaries bem mais curtos. Os autores recomendam fortemente um canary por vez, porque canaries simultâneos aumentam o esforço mental e, se se sobrepuserem, o risco de contaminação de sinal. Eles dizem que esses requisitos podem entrar em conflito, e que, com histórico de canaries passados, dá para escolher parâmetros pela taxa típica de falhas de avaliação em vez de cenários hipotéticos de pior caso.

Métricas, falsos positivos e falsos negativos

O capítulo diz que uma única métrica, como a taxa de sucesso, não basta: latência dez vezes maior ou uso de memória dez vezes maior também podem indicar problema. Uma boa métrica deve indicar problemas reais; os autores sugerem partir dos SLIs, já que bons SLIs costumam ter forte relação com a saúde do serviço e que já podem estar sendo medidos para os SLOs. O critério de comportamento aceitável precisa ser calibrado: se for rígido demais, surgem falsos positivos, isto é, o canary é tido como ruim sem ser; se for frouxo demais, aumenta a chance de um canary ruim passar sem detecção. Escolher esse critério corretamente pode ser caro, leva tempo e exige análise, e ele deve ser reavaliado conforme o serviço evolui. Métricas ruidosas, como uso de CPU no exemplo, podem levar operadores a ignorar ou desligar o processo. A recomendação é ordenar métricas por quão bem refletem problemas percebidos pelo usuário e usar poucas, talvez no máximo uma dúzia. As métricas também devem ser atribuíveis à mudança e não a fatores externos, como máquinas sobrecarregadas, por isso se prefere, por exemplo, tempo de CPU gasto servindo a requisição a CPU da máquina inteira. Comparar antes e depois no mesmo sistema é arriscado, porque o tempo em si muda as métricas (dia útil versus fim de semana). Por fim, métricas que não têm as propriedades ideais ainda podem ser úteis se introduzidas por um canary gradual em estágios: um primeiro estágio pequeno, para minimizar o impacto enquanto não há confiança no release, com as métricas mais claras, como crashes e falhas de requisição, e estágios seguintes maiores.

Integração ao release, rollback e conceitos relacionados

O capítulo mostra que o canary só funciona se a avaliação estiver ligada ao processo de release: se a taxa de erro do canary se afastar demais da do controle, o deploy é considerado ruim e a resposta é pausar e reverter, ou chamar uma pessoa para investigar; se as taxas forem parecidas, o rollout segue normalmente. Isso exige monitoramento que separe canary e controle: no exemplo, o erro de 1% no agregado pode ser indistinguível de outras fontes de erro, enquanto o detalhamento por versão mostra claramente os erros do candidato. Também é preciso cuidado com janelas de agregação: usar uma métrica de erros por hora para avaliar um canary de 30 minutos produz sinal confuso, e os intervalos das métricas devem ser iguais ou menores que a duração do canary. Como, por razões práticas, canary e controle podem compartilhar backends e outras dependências, um resultado ruim não significa necessariamente que o canary seja o culpado, e o canary ruim pode afetar o controle; por isso convém usar também medidas absolutas, como os SLOs. Sobre conceitos próximos, o texto descreve blue/green como duas instâncias, em que o rollback é a simples reversão da mudança no roteador, ao custo de o dobro de recursos, e que equivale a um canary antes/depois; dividindo o tráfego entre as duas, ele se aproxima de um canary A/B. Carga artificial e traffic teeing são parecidas com canarying e podem ser usadas como tal, mas não são estritamente canaries pela definição do capítulo; continuam sendo abordagens viáveis para achar defeitos, com ressalvas.

Veja as ideias em ação

Pratique na escola de System Design os desenhos que usam este paper.