Capítulo 18 – Engenharia de Software em SRE

Engenharia de Software em SRE

Escrito por Dave Helstroom e Trisha Weir com Evan Leonard e Kurt Delimon
Editado por Kavita Guliani

Peça a alguém para nomear um esforço de engenharia de software do Google e eles provavelmente listarão um produto voltado para o consumidor, como Gmail ou Maps; alguns podem até mencionar infraestrutura subjacente, como Bigtable ou Colossus. Mas, na verdade, existe uma enorme quantidade de engenharia de software nos bastidores que os consumidores nunca veem. Vários desses produtos são desenvolvidos no SRE.

O ambiente de produção do Google é, sob alguns aspectos, uma das máquinas mais complexas que a humanidade já construiu. Os SREs têm experiência em primeira mão com as complexidades da produção, tornando-as especialmente adequadas para desenvolver as ferramentas apropriadas para resolver problemas internos e casos de uso relacionados à manutenção da produção em execução. A maioria dessas ferramentas está relacionada à diretriz geral de manter o tempo de atividade e manter a latência baixa, mas assume muitas formas: os exemplos incluem mecanismos binários de rollout, monitoramento ou um ambiente de desenvolvimento baseado em composição dinâmica de servidor. No geral, essas ferramentas desenvolvidas por SRE são projetos de engenharia de software completos, distintos de soluções pontuais e hacks rápidos, e os SREs que as desenvolvem adotaram uma mentalidade baseada em produto que leva em conta tanto clientes internos como um roadmap para planos futuros.

Por que a engenharia de software em SRE é importante?

De muitas maneiras, a vasta escala de produção do Google exigiu o desenvolvimento de software interno, porque poucas ferramentas de terceiros são projetadas em escala suficiente para as necessidades do Google. A história de projetos de software bem-sucedidos da empresa nos levou a apreciar os benefícios de desenvolver diretamente no SRE.

Os SREs estão em uma posição única para desenvolver software interno de forma eficaz por uma série de razões:

  • A amplitude e a profundidade do conhecimento de produção específico do Google dentro da organização SRE permite que seus engenheiros projetem e criem software com as considerações apropriadas para dimensões como escalabilidade, degradação normal durante a falha e a capacidade de interagir facilmente com outra infraestrutura ou ferramentas.

  • Como os SREs estão incorporados ao assunto, eles entendem facilmente as necessidades e os requisitos da ferramenta que está sendo desenvolvida.

  • Um relacionamento direto com o usuário pretendido – outros SREs – resulta em feedback franco e de alto sinal por parte do usuário. Liberar uma ferramenta para um público interno com alta familiaridade com o espaço do problema significa que uma equipe de desenvolvimento pode fazer o lançamento e iterar mais rapidamente. Os usuários internos são geralmente mais compreensivos quando se trata de UI mínima e outros problemas do produto alfa.

 

De um ponto de vista puramente pragmático, o Google claramente se beneficia por ter engenheiros com experiência em desenvolvimento de software em SRE. Ao deliberar o projeto, a taxa de crescimento dos serviços suportados pelo SRE excede a taxa de crescimento da organização SRE; um dos princípios orientadores do SRE é que “o tamanho da equipe não deve ser escalonado diretamente com o crescimento do serviço”. Alcançar o crescimento linear da equipe em face do crescimento exponencial do serviço requer um trabalho perpétuo de automação e esforços para otimizar ferramentas, processos e outros aspectos de um serviço que introduzem ineficiência na operação diária de produção. Faz muito sentido ter pessoas com experiência direta na execução de sistemas de produção e no desenvolvimento de ferramentas que contribuirão para as metas de tempo de atividade e latência.

Por outro lado, os SREs individuais, bem como a organização SRE mais ampla, também se beneficiam do desenvolvimento de software orientado por SRE.

Projetos de desenvolvimento de software totalmente desenvolvidos dentro do SRE fornecem oportunidades de desenvolvimento de carreira para SREs, bem como uma saída para engenheiros que não querem que suas habilidades de codificação enferrujem. O trabalho de projeto de longo prazo fornece o equilíbrio necessário para interrupções e trabalho de plantão e pode fornecer satisfação no trabalho para engenheiros que desejam que suas carreiras mantenham um equilíbrio entre a engenharia de software e a engenharia de sistemas.

Além do projeto de ferramentas de automação e outros esforços para reduzir a carga de trabalho para engenheiros em SRE, os projetos de desenvolvimento de software podem beneficiar ainda mais a organização SRE, atraindo e ajudando a reter engenheiros com uma ampla variedade de habilidades. A conveniência da diversidade da equipe é duplamente verdadeira para SRE, onde uma variedade de experiências e abordagens de resolução de problemas podem ajudar a prevenir pontos cegos. Para isso, o Google sempre se esforça para formar suas equipes de SRE com uma combinação de engenheiros com experiência tradicional em desenvolvimento de software e engenheiros com experiência em engenharia de sistemas.

Estudo de caso Auxon: histórico de projeto e espaço do problema

Este estudo de caso examina o Auxon, uma ferramenta poderosa desenvolvida no SRE para automatizar o planejamento de capacidade para serviços executados em produção no Google. Para entender melhor como o Auxon foi concebido e os problemas que ele aborda, primeiro examinaremos o espaço do problema associado ao planejamento da capacidade e as dificuldades que as abordagens tradicionais para essa tarefa apresentam para os serviços do Google e na indústria como um todo. Para obter mais contexto sobre como o Google usa os termos serviço e cluster, consulte “O ambiente de produção no Google, sob o ponto de vista do SRE”.

Planejamento de Capacidade Tradicional

Existem inúmeras táticas para o planejamento de capacidade de recursos de computação, mas a maioria dessas abordagens se resumem a um ciclo que pode ser aproximado da seguinte forma:

1) Coletar previsões de demanda.

Quantos recursos são necessários? Quando e onde esses recursos são necessários?

  • Usa os melhores dados que temos disponíveis hoje para planejar o futuro
  • Normalmente cobre de vários trimestres a anos

2) Elaborar planos de construção e alocação.

Dada essa perspectiva projetada, qual é a melhor maneira de atender a essa demanda com oferta adicional de recursos? Quanta oferta e em quais locais?

3) Revise e assine o plano.

A previsão é razoável? O plano está de acordo com as considerações orçamentárias, de nível de produto e técnicas?

4) Implementar e configurar recursos.

Uma vez que os recursos finalmente chegam (potencialmente em fases ao longo de algum período de tempo definido), quais serviços podem usar os recursos? Como posso tornar os recursos de nível inferior (CPU, disco, etc.) úteis para os serviços?

É importante ressaltar que o planejamento da capacidade é um ciclo sem fim: as premissas mudam, as implantações escorregam e os orçamentos são cortados, resultando em revisão após revisão do planejamento. E cada revisão tem efeitos compensatórios que devem se propagar por todos os planos de todos os trimestres subsequentes. Por exemplo, um déficit neste trimestre deve ser compensado em trimestres futuros. O planejamento de capacidade tradicional usa a demanda como um impulsionador principal e molda manualmente o abastecimento para se adequar à demanda em resposta a cada mudança.

Frágil por natureza

O planejamento de capacidade tradicional produz um plano de alocação de recursos que pode ser interrompido por qualquer alteração aparentemente pequena. Por exemplo:

  • Um serviço sofre uma redução na eficiência e precisa de mais recursos do que o esperado para atender a mesma demanda.
  • As taxas de adoção do cliente aumentam, resultando em um aumento na demanda projetada.
  • A data de entrega de um novo cluster de recursos de computação é cancelada.
  • A decisão do produto sobre uma meta de desempenho muda a forma da implantação do serviço necessário (a pegada do serviço) e a quantidade de recursos necessários.

Pequenas mudanças requerem a verificação cruzada de todo o plano de alocação para ter certeza de que o plano ainda é viável; mudanças maiores (como entrega de recursos atrasada ou mudanças na estratégia do produto) potencialmente requerem a recriação do plano do zero. Um deslize de entrega em um único cluster pode impactar os requisitos de redundância ou latência de vários serviços: as alocações de recursos em outros clusters devem ser aumentadas para compensar o deslize, e essas e quaisquer outras mudanças teriam que se propagar por todo o plano.

Além disso, considere que o plano de capacidade para um determinado trimestre (ou outro período de tempo) é baseado no resultado esperado dos planos de capacidade dos trimestres anteriores, o que significa que uma mudança em qualquer trimestre resulta em trabalho para atualizar os trimestres subsequentes.

Laborioso e impreciso

Para muitas equipes, o processo de coleta dos dados necessários para gerar previsões de demanda é lento e sujeito a erros. E quando chega a hora de encontrar capacidade para atender a essa demanda futura, nem todos os recursos são igualmente adequados. Por exemplo, se os requisitos de latência significam que um serviço deve se comprometer a atender à demanda do usuário no mesmo continente no qual ele se encontra, a obtenção de recursos adicionais na América do Norte não aliviará o déficit de capacidade na Ásia. Cada previsão tem restrições ou parâmetros sobre como pode ser cumprida; as restrições estão fundamentalmente relacionadas à intenção, que será discutida na próxima seção.

O mapeamento de solicitações de recursos restritos em alocações de recursos reais a partir da capacidade disponível é igualmente lento: é complexo e tedioso fazer o bin pack de requisições em um espaço limitado manualmente ou encontrar soluções que caibam em um orçamento limitado.

Esse processo por si só já pode pintar um quadro sombrio, mas, para piorar as coisas, as ferramentas que ele requer são geralmente pouco confiáveis ou complicadas. As planilhas sofrem gravemente com problemas de escalabilidade e têm capacidade limitada de verificação de erros. Os dados ficam desatualizados e o rastreamento das alterações torna-se difícil. As equipes geralmente são forçadas a fazer suposições simplificadoras e a reduzir a complexidade de seus requisitos, simplesmente para tornar a manutenção de uma capacidade adequada um problema tratável.

Quando os proprietários dos serviços se deparam com o desafio de adequar uma série de pedidos de capacidade de vários serviços aos recursos de que dispõem, de forma a responder às várias condicionantes que um serviço pode ter, surge uma imprecisão adicional. O bin pack é um problema NP-difícil para os seres humanos calcularem à mão. Além disso, a solicitação de capacidade de um serviço é geralmente um conjunto inflexível de requisitos de demanda: X núcleos no cluster Y. As razões pelas quais X núcleos ou cluster Y são necessários, e quaisquer graus de liberdade em torno desses parâmetros já estão perdidos quando a solicitação chega a um humano que tenta encaixar uma lista de demandas no suprimento disponível.

O resultado líquido é um grande dispêndio de esforço humano para chegar a um bin pack que seja aproximado, na melhor das hipóteses. O processo é frágil para mudar e não há limites conhecidos em uma solução ótima.

Nossa solução: planejamento de capacidade com base na intenção

Especifique os requisitos, não a implementação.

No Google, muitas equipes mudaram para uma abordagem que chamamos de planejamento de capacidade com base na intenção. A premissa básica desta abordagem é codificar programaticamente as dependências e parâmetros (intenção) das necessidades de um serviço e usar essa codificação para gerar automaticamente um plano de alocação que detalha quais recursos vão para qual serviço, em qual cluster. Se os requisitos de demanda, fornecimento ou serviço mudarem, podemos simplesmente gerar automaticamente um novo plano em resposta aos parâmetros alterados, que agora é a nova melhor distribuição de recursos.

Com os verdadeiros requisitos e flexibilidade de um serviço capturados, o plano de capacidade agora é dramaticamente mais ágil em face da mudança, e podemos chegar a uma solução ideal que atenda ao maior número de parâmetros possível. Com o bin pack delegado aos computadores, o trabalho humano é drasticamente reduzido e os proprietários de serviços podem se concentrar em prioridades de alta ordem, como SLOs, dependências de produção e requisitos de infraestrutura de serviço, em oposição à busca de recursos de baixo nível.

Como um benefício adicional, o uso da otimização computacional para mapear da intenção à implementação atinge uma precisão muito maior, resultando em economia de custos para a organização. O bin pack ainda está longe de ser um problema resolvido, porque certos tipos ainda são considerados NP-difíceis; no entanto, os algoritmos de hoje em dia podem resolver isso em uma solução ótima conhecida.

Planejamento de capacidade com base na intenção

A intenção é a razão de como um proprietário de serviço deseja executar seu serviço. Mover-se de demandas de recursos concretos para razões motivacionais a fim de chegar à verdadeira intenção de planejamento de capacidade frequentemente requer várias camadas de abstração. Considere a seguinte cadeia de abstração:

1) “Quero 50 núcleos nos clusters X, Y e Z para o serviço Foo.”

Esta é uma solicitação de recurso explícita. Mas… por que precisamos de tantos recursos especificamente nesses clusters em particular?

2) “Quero uma pegada de 50 núcleos em quaisquer 3 clusters na região geográfica YYY para o serviço Foo.”

Essa solicitação apresenta mais graus de liberdade e é potencialmente mais fácil de cumprir, embora não explique o raciocínio por trás de seus requisitos. Mas… por que precisamos dessa quantidade de recursos e por que 3 pegadas?


3) “Quero atender à demanda de serviço Foo em cada região geográfica e ter redundância N + 2.”

De repente, uma maior flexibilidade é introduzida e podemos entender em um nível mais “humano” o que acontece se o serviço Foo não receber esses recursos. Mas… por que precisamos de N + 2 para o serviço Foo?

4) “Quero executar o serviço Foo com 5 noves de confiabilidade.”

Este é um requisito mais abstrato, e a ramificação se o requisito não for atendido torna-se clara: a confiabilidade será prejudicada. E temos ainda mais flexibilidade aqui: talvez a execução em N + 2 não seja realmente suficiente ou ideal para este serviço e algum outro plano de implantação seja mais adequado.

Então, que nível de intenção deve ser usado pelo planejamento de capacidade orientado por intenção? Idealmente, todos os níveis de intenção devem ser suportados juntos, com os serviços se beneficiando quanto mais se alteram para especificar a intenção versus implementação. Na experiência do Google, os serviços tendem a obter as melhores vitórias à medida que passam para a etapa 3: bons níveis de flexibilidade estão disponíveis e as ramificações desta solicitação estão em um nível mais alto e em termos compreensíveis. Serviços particularmente sofisticados podem apontar para a etapa 4.

Precursores da intenção

De quais informações precisamos para capturar a intenção de um serviço? Insira dependências, métricas de desempenho e priorização.

Dependências

Os serviços do Google dependem de muitas outras infraestruturas e serviços voltados para o usuário, e essas dependências influenciam fortemente onde um serviço pode ser colocado. Por exemplo, imagine o serviço voltado para o usuário Foo, que depende do Bar, um serviço de armazenamento de infraestrutura. Foo expressa um requisito de que Bar deve estar localizado a 30 milissegundos da latência de rede de Foo. Esse requisito tem repercussões importantes para onde colocamos Foo e Bar, e o planejamento de capacidade orientado pela intenção deve levar essas restrições em consideração.

Além disso, as dependências de produção são aninhadas: para construir sobre o exemplo anterior, imagine que o serviço Bar tem suas próprias dependências no Baz, um serviço de armazenamento distribuído de nível inferior, e Qux, um serviço de gerenciamento de aplicativos. Portanto, onde agora podemos colocar Foo depende de onde podemos colocar Bar, Baz e Qux. Um determinado conjunto de dependências de produção pode ser compartilhado, possivelmente com diferentes estipulações sobre a intenção.

Métricas de desempenho

A demanda por um serviço diminui para resultar na demanda por um ou mais outros serviços. Compreender a cadeia de dependências ajuda a formular o escopo geral do problema de bin pack, mas ainda precisamos de mais informações sobre o uso de recursos esperado. De quantos recursos de computação o serviço Foo precisa para atender a N consultas de usuários? Para cada N queries do serviço Foo, quantos Mbps de dados esperamos para o serviço Bar?

As métricas de desempenho são a cola entre as dependências. Elas são convertidas de um ou mais tipos de recursos de nível superior em um ou mais tipos de recursos de nível inferior. Derivar métricas de desempenho apropriadas para um serviço pode envolver teste de carga e monitoramento de uso de recursos.

Priorização

Inevitavelmente, as restrições de recursos resultam em compensações e decisões difíceis: dos muitos requisitos que todos os serviços têm, quais requisitos devem ser sacrificados em face da capacidade insuficiente?

Talvez a redundância N + 2 para o serviço Foo seja mais importante do que a redundância N + 1 para o serviço Bar. Ou talvez o lançamento de recurso do X seja menos importante do que a redundância N + 0 para o serviço Baz.

O planejamento baseado em intenções força essas decisões a serem tomadas de forma transparente, aberta e consistente. As restrições de recursos implicam nas mesmas compensações, mas, com muita frequência, a priorização pode ser ad hoc e opaca para os proprietários dos serviços. O planejamento com base na intenção permite que a priorização seja tão granular ou grosseira quanto necessário.

Introdução ao Auxon

Auxon é a implementação do Google de uma solução de planejamento de capacidade e alocação de recursos com base na intenção e um excelente exemplo de um produto de engenharia de software desenvolvido por SRE: foi construído por um pequeno grupo de engenheiros de software e um gerente de programa técnico dentro do SRE durante o curso de dois anos. Auxon é um estudo de caso perfeito para demonstrar como o desenvolvimento de software pode ser promovido dentro do SRE.

O Auxon é usado ativamente para planejar o uso de muitos milhões de dólares em recursos de máquina no Google. Ele se tornou um componente crítico do planejamento de capacidade para várias divisões importantes do Google.

Como um produto, o Auxon fornece os meios para coletar descrições baseadas na intenção dos requisitos de recursos e dependências de um serviço. Essas intenções do usuário são expressas como requisitos de como o proprietário gostaria que o serviço fosse fornecido. Os requisitos podem ser especificados como uma solicitação do tipo “Meu serviço deve ser N + 2 por continente” ou “Os servidores front-end não devem estar a mais de 50 metros de distância dos servidores back-end.” O Auxon coleta essas informações através de uma linguagem de configuração do usuário ou por meio de uma API programática, traduzindo assim a intenção humana em restrições analisáveis por máquina. Os requisitos podem ser priorizados, um recurso que é útil se os recursos são insuficientes para atender a todos os requisitos e, portanto, compensações devem ser feitas. Esses requisitos – a intenção – são, em última análise, representados internamente como um programa linear ou inteiro misto gigante. O Auxon resolve o programa linear e usa a solução de bin pack resultante para formular um plano de alocação de recursos.

A figura representada abaixo e as explicações que se seguem descrevem os principais componentes do Auxon.

principais componentes do auxon


Os dados de desempenho (Performance Data) descrevem como um serviço é dimensionado: para cada unidade de demanda X no cluster Y, quantas unidades de dependência Z são usadas? Esses dados de escala podem ser derivados de várias maneiras, dependendo da maturidade do serviço em questão. Alguns serviços são testados quanto à carga, enquanto outros inferem sua escala com base no desempenho anterior.

Os dados de previsão de demanda por serviço (Per-Service Demand Forecast Data) descrevem a tendência de uso dos sinais de demanda previstos. Alguns serviços derivam seu uso futuro de previsões de demanda – uma previsão de queries por segundo dividida por continente. Nem todos os serviços têm uma previsão de demanda: alguns serviços (por exemplo, um serviço de armazenamento como o Colossus) derivam sua demanda puramente de serviços que dependem deles.

O suprimento de recursos (Resource Supply) fornece dados sobre a disponibilidade de recursos fundamentais de nível básico: por exemplo, o número de máquinas que se espera que estejam disponíveis para uso em um determinado ponto no futuro. Na terminologia do programa linear, o fornecimento de recursos atua como um limite superior que determina como os serviços podem crescer e onde os serviços podem ser colocados. Em última análise, queremos fazer o melhor uso desse suprimento de recursos, conforme permite a descrição baseada na intenção do grupo combinado de serviços.

A precificação de recursos (Resource Pricing) fornece dados sobre quanto custam os recursos fundamentais no nível de base. Por exemplo, o custo das máquinas pode variar globalmente com base nas taxas de espaço/energia de uma determinada instalação. Na terminologia dos programas lineares, os preços informam os custos globais calculados, que atuam como o objetivo que queremos minimizar.

A intenção de configuração (Intent Config) é a chave de como as informações baseadas em intenções são enviadas ao Auxon. Ele define o que constitui um serviço e como os serviços se relacionam entre si. A configuração atua basicamente como uma camada que permite que todos os outros componentes sejam conectados juntos. Ele foi projetado para ser legível e configurável por humanos.

O Auxon Configuration Language Engine atua com base nas informações que recebe do Intent Config. Este componente formula uma solicitação legível por máquina: um buffer de protocolo que pode ser compreendido pelo Auxon Solver. Ele aplica a verificação de sanidade leve à configuração e é projetado para atuar como o gateway entre a definição de intenção configurável por humanos e a solicitação de otimização de parsing por máquina.

O Auxon Solver é o cérebro da ferramenta. Ele formula o programa linear ou inteiro misto gigante com base na solicitação de otimização recebida do Configuration Language Engine. Foi projetado para ser muito escalonável, o que permite que o solucionador seja executado em paralelo em centenas ou mesmo milhares de máquinas em execução nos clusters do Google. Além dos toolkits de programação linear inteira mista, também existem componentes no Auxon Solver que lidam com tarefas como agendamento, gerenciamento de grupos de trabalhadores e árvores de decisão decrescentes.

O Allocation Plan é o resultado do Auxon Solver. Ele prescreve quais recursos devem ser alocados para quais serviços e em quais locais. São os detalhes de implementação computados da definição baseada na intenção dos requisitos do problema de planejamento de capacidade. O Allocation Plan também inclui informações sobre quaisquer requisitos que não puderam ser atendidos – por exemplo, se um requisito não pode ser atendido devido à falta de recursos ou requisitos concorrentes que de outra forma eram muito restritos.

Requisitos e implementação: sucessos e lições aprendidas

Auxon foi imaginado pela primeira vez por um SRE e um gerente de programa técnico que havia sido encarregado por suas respectivas equipes de planejar separadamente a capacidade de grandes partes da infraestrutura do Google. Tendo realizado o planejamento de capacidade manual em planilhas, eles estavam bem posicionados para entender as ineficiências e oportunidades de melhoria através da automação e os recursos que essa ferramenta pode exigir.

Ao longo do desenvolvimento do Auxon, a equipe SRE por trás do produto continuou profundamente envolvida no mundo da produção. A equipe manteve uma função em rotações de plantão para vários dos serviços do Google e participou de discussões de projeto e liderança técnica desses serviços. Por meio dessas interações contínuas, a equipe foi capaz de permanecer firmada no mundo da produção: eles agiram tanto como consumidores quanto como desenvolvedores de seus próprios produtos. Quando o produto falhou, a equipe foi impactada diretamente. As solicitações de recursos foram informadas através de experiências em primeira mão da própria equipe. A experiência em primeira mão do espaço problemático não só comprou um enorme senso de propriedade no sucesso do produto, como também ajudou a dar ao produto credibilidade e legitimidade dentro do SRE.

Aproximação

Não se concentre na perfeição e na pureza da solução, especialmente se os limites do problema não forem bem conhecidos. Lance e faça iterações.

Qualquer esforço de engenharia de software suficientemente complexo está fadado a encontrar incertezas sobre como um componente deve ser projetado ou como um problema deve ser resolvido. O Auxon se deparou com essa incerteza no início de seu desenvolvimento porque o mundo da programação linear era um território desconhecido para os membros da equipe. As limitações da programação linear, que pareciam ser uma parte central de como o produto provavelmente funcionaria, não foram bem compreendidas. Para lidar com a consternação da equipe sobre essa dependência insuficientemente compreendida, optamos por construir inicialmente um mecanismo de solucionador simplificado (o chamado “Solucionador Estúpido”) que aplicou algumas heurísticas simples sobre como os serviços devem ser organizados com base nos requisitos especificados do usuário. Embora o “Solucionador Estúpido” (Stupid Solver) nunca fosse capaz de render uma solução verdadeiramente ideal, acabou por dar à equipe uma sensação de que nossa visão para o Auxon era alcançável, mesmo se não construíssemos algo perfeito desde o primeiro dia.

Ao implantar a aproximação para ajudar a acelerar o desenvolvimento, é importante realizar o trabalho de uma forma que permita à equipe fazer melhorias futuras e revisitar a aproximação. No caso do “Solucionador Estúpido”, toda a interface do solucionador foi abstraída dentro do Auxon de forma que os componentes internos do pudessem ser trocados posteriormente. Eventualmente, conforme construímos confiança em um modelo de programação linear unificado, foi uma operação simples trocar o “Solucionador Estúpido” por algo, digamos, bem mais inteligente.

Os requisitos do produto Auxon também tinham algumas incógnitas. Construir software com requisitos difusos pode ser um desafio frustrante, mas algum grau de incerteza não precisa ser um obstáculo. Use essa imprecisão como um incentivo para garantir que o software seja projetado para ser geral e modular. Por exemplo, um dos objetivos do projeto Auxon era integrar-se aos sistemas de automação do Google para permitir que um Plano de Alocação fosse executado diretamente na produção (atribuindo recursos e aumentando / diminuindo / redimensionando serviços conforme a necessidade). No entanto, na época, o mundo dos sistemas de automação estava em um grande fluxo, pois uma grande variedade de abordagens estava em uso. Em vez de tentar projetar soluções exclusivas para permitir que Auxon trabalhe com cada ferramenta individual, moldamos o Plano de Alocação para ser universalmente útil, de modo que esses sistemas de automação pudessem funcionar em seus próprios pontos de integração. Esta abordagem “agnóstica” se tornou a chave para o processo da Auxon de integrar novos clientes, porque permitiu que os clientes começassem a usar o Auxon sem mudar para uma ferramenta de automação de ativação, ferramenta de previsão ou ferramenta de dados de desempenho em particular.

Também aproveitamos projetos modulares para lidar com requisitos difusos ao construir um modelo de desempenho de máquina dentro do Auxon. Os dados sobre o desempenho futuro da plataforma da máquina (por exemplo, CPU) eram escassos, mas nossos usuários queriam uma maneira de modelar vários cenários de potência da máquina. Nós abstraímos os dados da máquina por trás de uma única interface, permitindo que o usuário trocasse em diferentes modelos de desempenho futuro da máquina. Posteriormente, estendemos essa modularidade ainda mais, com base em requisitos cada vez mais definidos, para fornecer uma biblioteca simples de modelagem de desempenho de máquina que funcionasse dentro dessa interface.

Se há um tema a ser extraído de nosso estudo de caso do Auxon, é que o antigo lema de “lançar e iterar” é particularmente relevante em projetos de desenvolvimento de software SRE. Não espere pelo design perfeito; em vez disso, mantenha a visão geral em mente enquanto avança com projeto e desenvolvimento. Quando encontrar áreas de incerteza, projete o software para ser flexível o suficiente para que, se o processo ou estratégia mudar em um nível mais alto, você não incorra em um grande custo de retrabalho. Mas, ao mesmo tempo, mantenha os pés no chão, certificando-se de que as soluções gerais tenham uma implementação específica no mundo real que demonstre a utilidade do projeto.

Aumentando a conscientização e impulsionando a adoção

Como acontece com qualquer produto, o software desenvolvido pelo SRE deve ser projetado com o conhecimento de seus usuários e requisitos. Ele precisa impulsionar a adoção por meio de utilidade, desempenho e capacidade demonstrada para beneficiar as metas de confiabilidade de produção do Google e melhorar a vida dos SREs. O processo de socializar um produto e conseguir adesão em toda a organização é a chave para o sucesso do projeto.

Não subestime o esforço necessário para aumentar a conscientização e o interesse pelo seu produto de software – uma única apresentação ou anúncio por e-mail não é suficiente. Socializar ferramentas de software internas para um grande público exige todas as seguintes considerações:

  • Uma abordagem consistente e coerente
  • Defesa do usuário
  • O patrocínio de engenheiros seniores e de gestão, a quem você terá que demonstrar a utilidade do seu produto


É importante levar em conta a perspectiva do cliente ao tornar seu produto utilizável. Um engenheiro pode não ter tempo ou inclinação para cavar no código-fonte para descobrir como usar uma ferramenta. Embora os clientes internos sejam geralmente mais tolerantes com as arestas e os primeiros alphas do que os clientes externos, ainda é necessário fornecer documentação. Os SREs estão ocupados e, se a sua solução for muito difícil ou confusa, eles escreverão sua própria solução.

Defina as expectativas

Quando um engenheiro com anos de familiaridade em um espaço problemático começa a projetar um produto, é fácil imaginar um estado final utópico para o trabalho. No entanto, é importante diferenciar as metas aspiracionais do produto dos critérios mínimos de sucesso (ou Produto Mínimo Viável). Os projetos podem perder credibilidade e falhar ao prometer muito, muito cedo; ao mesmo tempo, se um produto não promete um resultado suficientemente recompensador, pode ser difícil superar a energia de ativação necessária para convencer as equipes internas a tentar algo novo. Demonstrar um progresso constante e incremental através de pequenos lançamentos aumenta a confiança do usuário na capacidade de sua equipe de fornecer software útil.

No caso do Auxon, alcançamos um equilíbrio planejando um roteiro de longo prazo ao lado de soluções de curto prazo. As equipes receberam a promessa de que:

  • Quaisquer esforços de integração e configuração proporcionariam o benefício imediato de aliviar a dor de fazer o bin pack manual das solicitações de recursos de curto prazo

  • Como recursos adicionais foram desenvolvidos para o Auxon, os mesmos arquivos de configuração seriam transportados e forneceriam novas e muito mais amplas economias de custos e outros benefícios a longo prazo. O roadmap do projeto permitiu que os serviços determinassem rapidamente se seus casos de uso ou recursos necessários não foram implementados nas primeiras versões. Enquanto isso, a abordagem de desenvolvimento iterativo do Auxon alimentou as prioridades de desenvolvimento e trouxe novos marcos para o roadmap.
Identifique os clientes adequados

A equipe de desenvolvimento do Auxon percebeu que uma solução de tamanho único pode não servir para todos; muitas equipes maiores já tinham soluções desenvolvidas internamente para planejamento de capacidade que funcionavam razoavelmente bem. Embora suas ferramentas personalizadas não fossem perfeitas, essas equipes não experimentaram dor suficiente no processo de planejamento de capacidade para tentar uma nova ferramenta, especialmente uma versão alpha com arestas.

As versões iniciais do Auxon visavam intencionalmente equipes que não tinham processos de planejamento de capacidade existentes em vigor. Como essas equipes teriam que investir esforço de configuração, quer adotassem uma ferramenta existente ou nossa nova abordagem, eles estavam interessados em adotar a ferramenta mais recente. Os primeiros sucessos alcançados pelo Auxon com essas equipes demonstraram a utilidade do projeto e transformaram os próprios clientes em defensores da ferramenta. Quantificar a utilidade do produto revelou-se ainda mais benéfico; quando integramos uma das áreas de negócios do Google, a equipe escreveu um estudo de caso detalhando o processo e comparando os resultados antes e depois. A economia de tempo e a redução do trabalho humano por si só representaram um grande incentivo para outras equipes experimentarem o Auxon.

Atendimento ao cliente

Mesmo que o software desenvolvido no SRE seja direcionado a um público de TPMs e engenheiros com alta proficiência técnica, qualquer software suficientemente inovador ainda apresenta uma curva de aprendizado para novos usuários. Não tenha medo de fornecer suporte de alta prioridade para os primeiros usuários para ajudá-los durante o processo de integração. Às vezes, a automação também envolve uma série de preocupações emocionais, como o medo de que o trabalho de alguém seja substituído por um script shell. Trabalhando individualmente com os primeiros usuários, você pode lidar com esses medos pessoalmente e demonstrar que, em vez de assumir o trabalho de executar uma tarefa tediosa manualmente, a equipe é responsável pelas configurações, processos e resultados finais de seu trabalho técnico. Os adotantes posteriores são convencidos pelos exemplos felizes dos primeiros usuários.

Além disso, como as equipes SRE do Google estão distribuídas em todo o mundo, os defensores dos primeiros usuários de um projeto são particularmente benéficos, porque podem servir como especialistas locais para outras equipes interessadas em experimentar o projeto.

Projetando no nível certo

Uma ideia que denominamos agnosticismo – escrever o software para ser generalizado e permitir uma miríade de fontes de dados como entrada – foi um princípio fundamental de design do Auxon. Agnosticismo significava que os clientes não eram obrigados a se comprometer com nenhuma ferramenta para usar o framework Auxon. Essa abordagem permitiu que o Auxon continuasse com utilidade geral suficiente, mesmo quando equipes com casos de uso divergentes começaram a usá-lo. Abordamos os usuários em potencial com a mensagem “venha do jeito que você está; vamos trabalhar com o que você tem.” Ao evitar a personalização excessiva para um ou dois grandes usuários, alcançamos uma adoção mais ampla em toda a organização e reduzimos a barreira de entrada para novos serviços.

Também nos esforçamos conscientemente para evitar a armadilha de definir o sucesso como 100% de adoção em toda a organização. Em muitos casos, há retornos decrescentes ao fechar a última milha para habilitar um conjunto de recursos que é suficiente para todos os serviços na cauda longa do Google.

Dinâmica de equipe

Ao selecionar engenheiros para trabalhar em um produto de desenvolvimento de software SRE, descobrimos um grande benefício em criar uma equipe inicial que combina generalistas que são capazes de se familiarizar rapidamente com um novo tópico com engenheiros que possuem um amplo conhecimento e experiência. Uma diversidade de experiências cobre pontos cegos, bem como as armadilhas de assumir que o caso de uso de cada equipe é igual ao seu.

É essencial que sua equipe estabeleça uma relação de trabalho com os especialistas necessários e que seus engenheiros se sintam confortáveis trabalhando em um novo espaço problemático. Para as equipes de SRE na maioria das empresas, aventurar-se nesse novo espaço problemático requer terceirizar tarefas ou trabalhar com consultores, mas as equipes SRE em organizações maiores podem ser capazes de fazer parceria com especialistas internos. Durante as fases iniciais de conceituação e design do Auxon, apresentamos nosso documento de projeto para as equipes internas do Google especializadas em Pesquisa Operacional e Análise Quantitativa, a fim de aproveitar sua experiência no campo e reforçar o conhecimento da equipe Auxon sobre planejamento de capacidade.

Conforme o desenvolvimento do projeto continuou e o conjunto de recursos do Auxon ficou mais amplo e complexo, a equipe adquiriu membros com experiência em estatística e otimização matemática, o que em uma empresa menor pode ser semelhante a trazer um consultor externo para dentro da empresa. Esses novos membros da equipe foram capazes de identificar áreas de melhoria quando a funcionalidade básica do projeto foi concluída e adicionar requinte tornou-se nossa principal prioridade.

O momento certo para contratar especialistas irá variar, obviamente, de projeto para projeto. Como orientação geral, o projeto deve ser bem-sucedido no início e comprovar esse sucesso, de modo que as habilidades da equipe atual sejam significativamente reforçadas pelo expertise adicional.

Fomentando Engenharia de Software em SRE

O que torna um projeto um bom candidato para saltar de uma ferramenta única para um esforço de engenharia de software completo? Sinais positivos fortes incluem engenheiros com experiência em primeira mão no domínio relativo que estão interessados em trabalhar no projeto e uma base de usuários alvo que é altamente técnica (e, portanto, capaz de fornecer relatórios de bug de alto sinal durante as fases iniciais de desenvolvimento). O projeto deve fornecer benefícios perceptíveis, como redução de trabalho para SREs, melhoria de uma peça de infraestrutura existente ou simplificação de um processo complexo.

É importante que o projeto se encaixe no conjunto geral de objetivos da organização, para que os líderes de engenharia possam pesar seu impacto potencial e, posteriormente, defender seu projeto, tanto com suas equipes de relatórios quanto com outras equipes que podem interagir com suas equipes. A socialização cruzada e a revisão organizacional ajudam a evitar esforços desarticulados ou sobrepostos, e um produto que pode ser facilmente estabelecido como um objetivo de todo o departamento é mais fácil de ganhar equipe e suporte.

O que torna um projeto um candidato ruim? Muitos dos mesmos sinais de alerta que você pode identificar instintivamente em qualquer projeto de software, como software que toca muitas partes móveis ao mesmo tempo ou projeto de software que requer uma abordagem tudo ou nada que impede o desenvolvimento iterativo. Como as equipes de SRE do Google estão atualmente organizadas em torno dos serviços que executam, os projetos desenvolvidos por SRE correm o risco de ser um trabalho excessivamente específico que beneficia apenas uma pequena porcentagem da organização. Como os incentivos da equipe são alinhados principalmente para fornecer uma ótima experiência para os usuários de um serviço específico, os projetos geralmente falham em generalizar para um caso de uso mais amplo, pois a padronização entre as equipes de SRE vem em segundo lugar. Na extremidade oposta do espectro, estruturas excessivamente genéricas podem ser igualmente problemáticas; se uma ferramenta se esforça para ser muito flexível e universal, ela corre o risco de não se ajustar a nenhum caso de uso e, portanto, ter valor insuficiente por si só. Projetos com grande escopo e objetivos abstratos geralmente requerem um esforço significativo de desenvolvimento, mas não possuem os casos de uso concretos necessários para fornecer benefícios ao usuário final em um prazo razoável.

Como um exemplo de caso de uso amplo: um balanceador de carga de camada 3 desenvolvido pelo Google SREs provou ser tão bem-sucedido ao longo dos anos que foi reaproveitado como uma oferta de produto voltada para o cliente por meio do Google Cloud Load Balancer.

Construindo com sucesso uma cultura de Engenharia de Software em SRE: tempo de equipe e desenvolvimento

Os SREs costumam ser generalistas, pois o desejo de aprender primeiro em amplitude, em vez de profundidade, se presta bem à compreensão do quadro geral (e há poucos quadros maiores do que o intrincado funcionamento interno da infraestrutura técnica moderna). Esses engenheiros geralmente têm fortes habilidades de codificação e desenvolvimento de software, mas podem não ter a experiência tradicional do SWE de fazer parte de uma equipe de produto ou ter que pensar sobre as solicitações de recursos do cliente. Uma citação de um engenheiro em um projeto inicial de desenvolvimento de software SRE resume a abordagem SRE convencional para software: “Eu tenho um documento de design; por que precisamos de requisitos?” A parceria com engenheiros, TPMs ou PMs que estão familiarizados com o desenvolvimento de software voltado para o usuário pode ajudar a construir uma cultura de desenvolvimento de software em equipe que reúne o melhor do desenvolvimento de produto de software e experiência prática de produção.

O tempo de trabalho dedicado e ininterrupto de projeto é essencial para qualquer esforço de desenvolvimento de software. O tempo dedicado ao projeto é necessário para possibilitar o progresso do mesmo, porque é quase impossível escrever código – muito menos se concentrar em projetos maiores e mais impactantes – quando você está se debatendo entre várias tarefas no decorrer de uma hora. Portanto, a capacidade de trabalhar em um projeto de software sem interrupções costuma ser um motivo atraente para os engenheiros começarem a abraçar um projeto de desenvolvimento. Esse tempo deve ser defendido de forma agressiva.

A maioria dos produtos de software desenvolvidos no SRE começam como projetos paralelos cuja utilidade os leva a crescer e se formalizar. Neste ponto, um produto pode se ramificar em uma das várias direções possíveis:

  • Permanecer um esforço de base desenvolvido no tempo livre dos engenheiros
  • Estabelecer-se como um projeto formal por meio de processos estruturados
  • Obter patrocínio executivo de dentro da liderança SRE para expandir em um esforço de desenvolvimento de software com equipe completa


No entanto, em qualquer um desses cenários – e este é um ponto que vale a pena enfatizar – é essencial que os SREs envolvidos em qualquer esforço de desenvolvimento continuem trabalhando como SREs em vez de se tornarem desenvolvedores em tempo integral incorporados na organização SRE. A imersão no mundo da produção dá aos SREs que executam o trabalho de desenvolvimento uma perspectiva inestimável, pois eles são ao mesmo tempo criador e o cliente de qualquer produto.

Chegando lá

Se você gosta da ideia de desenvolvimento de software organizado em SRE, provavelmente está se perguntando como apresentar um modelo de desenvolvimento de software a uma organização SRE com foco no suporte à produção.

Primeiro, reconheça que essa meta é tanto uma mudança organizacional quanto um desafio técnico. Os SREs estão acostumados a trabalhar junto com seus colegas de equipe, analisando e reagindo rapidamente aos problemas. Portanto, você está trabalhando contra o instinto natural de um SRE de escrever rapidamente algum código para atender às necessidades imediatas. Se sua equipe SRE for pequena, essa abordagem pode não ser problemática. No entanto, conforme sua organização cresce, esta abordagem ad hoc não será escalonada, em vez disso, resultará em soluções de software amplamente funcionais, embora restritas ou de propósito único, que não podem ser compartilhadas, o que inevitavelmente leva a esforços duplicados e perda de tempo.

A seguir, pense sobre o que você deseja alcançar desenvolvendo software em SRE. Você deseja apenas promover melhores práticas de desenvolvimento de software em sua equipe ou está interessado no desenvolvimento de software que produza resultados que podem ser usados entre as equipes, possivelmente como um padrão para a organização? Em organizações estabelecidas de maior porte, a última mudança levará tempo, possivelmente abrangendo vários anos. Essa mudança precisa ser enfrentada em várias frentes, mas tem um retorno maior. A seguir estão algumas diretrizes da experiência do Google:

Crie e comunique com uma mensagem clara

É importante definir e comunicar sua estratégia, planos e, o mais importante, os benefícios que o SRE ganha com esse esforço. Os SREs são muito céticos (na verdade, o ceticismo é uma característica para a qual contratamos especificamente); a resposta inicial de um SRE a tal esforço provavelmente será “isso parece muito genérico” ou “nunca funcionará”. Comece apresentando um caso convincente de como essa estratégia ajudará o SRE; por exemplo:

  • Soluções de software consistentes e com suporte aceleram o ramp-up para novos SREs.

  • Reduzir o número de maneiras de executar a mesma tarefa permite que todo o departamento se beneficie das habilidades que uma única equipe desenvolveu, tornando o conhecimento e o esforço portáteis entre as equipes.

Quando os SREs começam a fazer perguntas sobre como sua estratégia funcionará, em vez de se a estratégia deve ser seguida, você sabe que ultrapassou o primeiro obstáculo.

Avalie as capacidades da sua organização

Os SREs têm muitas habilidades, mas é relativamente comum que um SRE não tenha experiência como parte de uma equipe que construiu e despachou um produto para um conjunto de usuários. Para desenvolver software útil, você está efetivamente criando uma equipe de produto. Essa equipe inclui funções e habilidades necessárias que sua organização SRE pode não ter exigido anteriormente. Alguém desempenhará o papel de gerente de produto, atuando como advogado do cliente? O seu líder de tecnologia ou gerente de projeto tem as habilidades e/ou experiência para executar um processo de desenvolvimento ágil?

Comece a preencher essas lacunas aproveitando as competências já presentes na sua empresa. Peça a sua equipe de desenvolvimento de produto para ajudá-lo a estabelecer práticas ágeis por meio de treinamento ou coaching. Solicite tempo de consultoria de um gerente de produto para ajudá-lo a definir os requisitos do produto e priorizar o trabalho de recursos. Tendo em vista a oportunidade de desenvolvimento de software grande o suficiente, pode haver o caso de contratar pessoas dedicadas para essas funções. Argumentar para contratar para essas funções é mais fácil, uma vez que você tem alguns resultados de experiência positivos.

Lance e faça iterações

Ao iniciar um programa de desenvolvimento de software SRE, seus esforços serão acompanhados por muitos olhos vigilantes. É importante estabelecer credibilidade entregando algum produto de valor em um período de tempo razoável. Sua primeira rodada de produtos deve ter como objetivo alvos relativamente simples e alcançáveis – aqueles sem controvérsia ou soluções existentes. Também tivemos sucesso ao parear essa abordagem com um ritmo de seis meses de lançamentos de atualização de produto que fornecia recursos adicionais úteis. Este ciclo de lançamento permitiu que as equipes se concentrassem em identificar o conjunto certo de recursos a serem construídos e, em seguida, construir esses recursos enquanto aprendiam simultaneamente como ser uma equipe de desenvolvimento de software produtiva. Após o lançamento inicial, algumas equipes do Google mudaram para um modelo push-on-green para entrega e feedback ainda mais rápidos.

Não diminua seus padrões

Ao começar a desenvolver software, você pode ficar tentado a cortar atalhos. Resista a esse impulso mantendo-se nos mesmos padrões que as equipes de desenvolvimento de produtos seguem. Por exemplo:

  • Pergunte a si mesmo: se este produto fosse criado por uma equipe de desenvolvimento separada, você integraria o produto?

  • Se sua solução tiver ampla adoção, ela pode se tornar crítica para que os SREs executem com sucesso seus trabalhos. Portanto, a confiabilidade é de extrema importância. Você tem práticas adequadas de revisão de código em vigor? Você tem teste de ponta a ponta ou de integração? Peça a outra equipe SRE que analise o produto para verificar se está pronto para a produção, como faria se estivesse integrando qualquer outro serviço.

Leva muito tempo para construir credibilidade para seus esforços de desenvolvimento de software, mas muito pouco tempo também para perder credibilidade devido a um erro.

Conclusões

Os projetos de engenharia de software no Google SRE floresceram à medida que a organização cresceu e, em muitos casos, as lições aprendidas e a execução bem-sucedida de projetos de desenvolvimento de software anteriores abriram caminho para empreendimentos subsequentes. A experiência única de produção prática que os SREs trazem para o desenvolvimento de ferramentas pode levar a abordagens inovadoras para problemas antigos, como visto com o desenvolvimento do Auxon para resolver o problema complexo de planejamento de capacidade. Projetos de software baseados em SRE também são visivelmente benéficos para a empresa no desenvolvimento de um modelo sustentável de suporte a serviços em escala. Como os SREs costumam desenvolver software para agilizar processos ineficientes ou automatizar tarefas comuns, esses projetos significam que a equipe de SRE não precisa escalar linearmente com o tamanho dos serviços para os quais oferecem suporte. Em última análise, os benefícios de ter SREs dedicando parte de seu tempo ao desenvolvimento de software são colhidos pela empresa, pela organização SRE e pelos próprios SREs.


Fonte: Google SRE Book

Rolar para cima