Accepter le risque

On pourrait s’attendre à ce que Google s’efforce de créer des services fiables à 100 %, c’est-à-dire des services qui ne tombent jamais en panne. Il s’avère cependant qu’au-delà d’un certain point, l’augmentation de la fiabilité est pire pour un service (et ses utilisateurs) plutôt que meilleure ! Une fiabilité extrême a un coût : l’optimisation de la stabilité limite la vitesse de développement de nouvelles fonctionnalités et la rapidité de livraison des produits aux utilisateurs, et augmente considérablement leur coût, ce qui réduit à son tour le nombre de fonctionnalités qu’une équipe peut se permettre d’offrir. De plus, les utilisateurs ne remarquent généralement pas la différence entre une fiabilité élevée et une fiabilité extrême dans un service, car l’expérience utilisateur est dominée par des composants moins fiables comme le réseau cellulaire ou l’appareil avec lequel ils travaillent. En d’autres termes, un utilisateur utilisant un smartphone fiable à 99 % ne peut pas faire la différence entre une fiabilité de service de 99,99 % et de 99,999 % ! Dans cette optique, plutôt que de se contenter de maximiser le temps de fonctionnement, l’ingénierie de la fiabilité des sites cherche à équilibrer le risque d’indisponibilité avec les objectifs d’innovation rapide et d’efficacité des opérations de service, afin d’optimiser le bonheur global des utilisateurs en termes de fonctionnalités, de service et de performances.

Gestion du risque

Les systèmes peu fiables peuvent rapidement éroder la confiance des utilisateurs, c’est pourquoi nous voulons réduire le risque de défaillance du système. Cependant, l’expérience montre qu’au fur et à mesure que nous construisons des systèmes, le coût n’augmente pas linéairement en fonction de la fiabilité - une amélioration progressive de la fiabilité peut coûter 100 fois plus cher que l’amélioration précédente. Le coût a deux dimensions :

Le coût lié à la redondance des ressources machines/ordinateurs. Le coût associé à l’équipement redondant qui, par exemple, nous permet de mettre les systèmes hors ligne pour une maintenance de routine ou imprévue, ou nous fournit de l’espace pour stocker des blocs de code de parité qui fournissent une garantie minimale de durabilité des données. Le coût d’opportunité Le coût supporté par une organisation lorsqu’elle alloue des ressources d’ingénierie pour construire des systèmes ou des fonctionnalités qui diminuent le risque au lieu de fonctionnalités qui sont directement visibles ou utilisables par les utilisateurs finaux. Ces ingénieurs ne travaillent plus sur les nouvelles fonctionnalités et les nouveaux produits destinés aux utilisateurs finaux. En SRE, nous gérons la fiabilité des services en grande partie par la gestion du risque. Nous conceptualisons le risque comme un continuum. Nous accordons la même importance à la recherche d’une plus grande fiabilité dans les systèmes Google et à l’identification du niveau de tolérance approprié pour les services que nous exploitons. Cela nous permet d’effectuer une analyse coûts/avantages afin de déterminer, par exemple, à quel endroit du continuum de risque (non linéaire) nous devons placer les services Recherche, Annonces, Gmail ou Photos. Notre objectif est d’aligner explicitement le risque pris par un service donné avec le risque que l’entreprise est prête à supporter. Nous nous efforçons de rendre un service suffisamment fiable, mais pas plus fiable qu’il ne doit l’être. En d’autres termes, lorsque nous fixons un objectif de disponibilité de 99,99 %, nous voulons le dépasser, mais pas de beaucoup : cela reviendrait à gâcher des occasions d’ajouter des fonctionnalités au système, de résorber la dette technique ou de réduire les coûts d’exploitation. En un sens, nous considérons l’objectif de disponibilité à la fois comme un minimum et comme un maximum. Le principal avantage de cette approche est qu’elle permet une prise de risque explicite et réfléchie.

Mesure du risque lié au service

Chez Google, nous avons souvent intérêt à identifier une mesure objective pour représenter la propriété d’un système que nous voulons optimiser. En fixant un objectif, nous pouvons évaluer nos performances actuelles et suivre les améliorations ou les dégradations au fil du temps. Pour le risque de service, il n’est pas évident de réduire tous les facteurs potentiels en une seule mesure. Les défaillances de service peuvent avoir de nombreux effets potentiels, notamment le mécontentement, le préjudice ou la perte de confiance des utilisateurs, la perte directe ou indirecte de revenus, l’impact sur la marque ou la réputation et la couverture médiatique indésirable. Il est clair que certains de ces facteurs sont très difficiles à mesurer. Pour rendre ce problème traitable et cohérent dans les nombreux types de systèmes que nous gérons, nous nous concentrons sur les temps d’arrêt non planifiés.

Pour la plupart des services, la façon la plus simple de représenter la tolérance au risque est de définir le niveau acceptable de temps d’arrêt non planifié. Le temps d’arrêt non planifié est représenté par le niveau souhaité de disponibilité du service, généralement exprimé en termes de nombre de “neuf” que nous souhaitons fournir : 99,9%, 99,99% ou 99,999% de disponibilité. Chaque neuf supplémentaire correspond à un ordre de grandeur d’amélioration vers une disponibilité de 100 %. Pour les systèmes de service, cette métrique est traditionnellement calculée sur la base de la proportion de temps de fonctionnement du système (voir Disponibilité basée sur le temps).

La disponibilité dans le temps

image.png

En utilisant cette formule sur une période d’un an, on peut calculer le nombre acceptable de minutes d’arrêt pour atteindre un nombre donné de neuf de disponibilité. Par exemple, un système dont l’objectif de disponibilité est de 99,99 % peut être indisponible pendant 52,56 minutes au maximum en un an et rester dans les limites de son objectif de disponibilité ; voir le tableau de disponibilité pour un tableau.

Chez Google, cependant, une mesure de la disponibilité basée sur le temps n’est généralement pas significative, car nous examinons des services distribués dans le monde entier. Grâce à notre approche de l’isolation des pannes, il est très probable que nous desservions au moins un sous-ensemble du trafic pour un service donné quelque part dans le monde à un moment donné (c’est-à-dire que nous sommes au moins partiellement “opérationnels” à tout moment). Par conséquent, au lieu d’utiliser des mesures relatives au temps de fonctionnement, nous définissons la disponibilité en termes de taux de réussite des demandes. La disponibilité globale montre comment cette métrique basée sur le rendement est calculée sur une fenêtre glissante (c’est-à-dire la proportion de demandes réussies sur une fenêtre d’un jour).

Disponibilité globale

image.png

Par exemple, un système qui sert 2,5 millions de demandes par jour avec un objectif de disponibilité quotidienne de 99,99 % peut servir jusqu’à 250 erreurs tout en atteignant son objectif pour cette journée.

Dans une application typique, toutes les demandes ne sont pas égales : l’échec d’une demande d’inscription d’un nouvel utilisateur est différent de l’échec d’une demande de recherche de nouveaux e-mails en arrière-plan. Dans de nombreux cas, cependant, la disponibilité calculée comme le taux de réussite de toutes les demandes est une approximation raisonnable du temps d’arrêt non planifié, du point de vue de l’utilisateur final.

La quantification du temps d’arrêt non planifié en tant que taux de réussite des demandes rend également cette mesure de disponibilité plus facile à utiliser dans les systèmes qui ne servent généralement pas directement les utilisateurs finaux. La plupart des systèmes sans service (par exemple, les systèmes batch, pipeline, de stockage et transactionnels) ont une notion bien définie d’unités de travail réussies et non réussies. En effet, bien que les systèmes abordés dans ce chapitre soient principalement des systèmes au service des consommateurs et des infrastructures, bon nombre des mêmes principes s’appliquent également aux systèmes sans service avec un minimum de modifications.

Par exemple, un processus batch qui extrait, transforme et insère le contenu de l’une de nos bases de données clients dans un entrepôt de données pour permettre une analyse plus approfondie peut être configuré pour s’exécuter périodiquement. En utilisant un taux de réussite des requêtes défini en termes d’enregistrements traités avec succès ou non, nous pouvons calculer une mesure de disponibilité utile malgré le fait que le système batch ne fonctionne pas constamment.

Le plus souvent, nous fixons des objectifs trimestriels de disponibilité pour un service et nous suivons nos performances par rapport à ces objectifs sur une base hebdomadaire, voire quotidienne. Cette stratégie nous permet de gérer le service en fonction d’un objectif de disponibilité de haut niveau en recherchant, en traquant et en corrigeant les écarts significatifs lorsqu’ils se produisent inévitablement. Voir Objectifs de niveau de service pour plus de détails.

Tolérance au risque des services

Qu’est-ce que cela signifie d’identifier la tolérance au risque d’un service ? Dans un environnement formel ou dans le cas de systèmes critiques pour la sécurité, la tolérance au risque des services est généralement intégrée directement dans la définition de base du produit ou du service. Chez Google, la tolérance au risque des services tend à être moins clairement définie.

Pour identifier la tolérance au risque d’un service, les SRE doivent travailler avec les propriétaires du produit pour transformer un ensemble d’objectifs commerciaux en objectifs explicites sur lesquels nous pouvons nous baser. Dans ce cas, les objectifs commerciaux qui nous préoccupent ont un impact direct sur les performances et la fiabilité du service offert. Dans la pratique, cette traduction est plus facile à dire qu’à faire. Alors que les services aux consommateurs ont souvent des propriétaires de produits clairement définis, il est rare que les services d’infrastructure (par exemple, les systèmes de stockage ou une couche de mise en cache HTTP à usage général) aient une structure similaire de propriété des produits. Nous examinerons successivement les cas des consommateurs et des infrastructures.

Identifier la tolérance au risque des services grand public

Nos services grand public disposent souvent d’une équipe produit qui joue le rôle de propriétaire de l’application. Par exemple, la recherche, Google Maps et Google Documents ont chacun leur propre chef de produit. Ces chefs de produit sont chargés de comprendre les utilisateurs et l’entreprise, et de façonner le produit pour qu’il réussisse sur le marché. Lorsqu’une équipe produit existe, elle est généralement la meilleure ressource pour discuter des exigences de fiabilité d’un service. En l’absence d’une équipe dédiée au produit, les ingénieurs qui construisent le système jouent souvent ce rôle, sciemment ou non.

De nombreux facteurs doivent être pris en compte lors de l’évaluation de la tolérance au risque des services, notamment les suivants :

  • Quel est le niveau de disponibilité requis ?
  • Les différents types de défaillances ont-ils des effets différents sur le service ?
  • Comment utiliser le coût du service pour aider à situer un service sur le continuum des risques ?
  • Quelles autres métriques de service sont importantes à prendre en compte ?

Niveau de disponibilité cible

Le niveau de disponibilité cible d’un service Google donné dépend généralement de la fonction qu’il assure et de son positionnement sur le marché. La liste suivante comprend des questions à prendre en compte :

  • Quel niveau de service les utilisateurs attendent-ils ?
  • Ce service est-il directement lié aux revenus (les nôtres ou ceux de nos clients) ?
  • S’agit-il d’un service payant ou gratuit ?
  • S’il existe des concurrents sur le marché, quel niveau de service ces derniers fournissent-ils ?
  • Ce service est-il destiné aux consommateurs ou aux entreprises ?

Considérez les besoins de Google Apps for Work. La majorité de ses utilisateurs sont des entreprises, certaines grandes, d’autres petites. Ces entreprises dépendent des services de Google Apps for Work (par exemple, Gmail, Agenda, Drive, Docs) pour fournir les outils qui permettent à leurs employés d’effectuer leur travail quotidien. En d’autres termes, une panne d’un service Google Apps for Work est une panne non seulement pour Google, mais aussi pour toutes les entreprises qui dépendent de nous de manière critique. Pour un service Google Apps for Work type, nous pourrions fixer un objectif de disponibilité trimestrielle externe de 99,9 % et l’assortir d’un objectif de disponibilité interne plus strict et d’un contrat prévoyant des pénalités si nous n’atteignons pas l’objectif externe.

YouTube offre un ensemble contrasté de considérations. Lorsque Google a acquis YouTube, nous avons dû décider de l’objectif de disponibilité approprié pour le site Web. En 2006, YouTube était axé sur les consommateurs et se trouvait dans une phase du cycle de vie de son entreprise très différente de celle de Google à l’époque. Si YouTube disposait déjà d’un excellent produit, il était encore en pleine évolution et en pleine croissance. Nous avons fixé un objectif de disponibilité plus faible pour YouTube que pour nos produits d’entreprise, car le développement rapide des fonctionnalités était par conséquent plus important.

Types de défaillances

La forme prévue des défaillances pour un service donné est une autre considération importante. Quelle est la résilience de notre entreprise face aux interruptions de service ? Qu’est-ce qui est le plus grave pour le service : un faible taux constant de défaillances ou une panne occasionnelle sur tout le site ? Les deux types de défaillance peuvent entraîner le même nombre absolu d’erreurs, mais peuvent avoir des impacts très différents sur l’entreprise.

Un exemple illustrant la différence entre les pannes totales et partielles se présente naturellement dans les systèmes qui servent des informations privées. Prenons l’exemple d’une application de gestion des contacts et la différence entre des pannes intermittentes qui empêchent l’affichage des photos de profil et une panne qui fait que les contacts privés d’un utilisateur sont montrés à un autre utilisateur. Dans le premier cas, il s’agit clairement d’une mauvaise expérience utilisateur, et les SRE s’efforceraient de remédier rapidement au problème. Dans le second cas, en revanche, le risque d’exposition de données privées pourrait facilement ébranler la confiance de base des utilisateurs de manière significative. Par conséquent, le retrait complet du service serait approprié pendant la phase de débogage et de nettoyage potentiel dans le second cas.

À l’autre extrémité des services proposés par Google, il est parfois acceptable d’avoir des interruptions régulières pendant les fenêtres de maintenance. Il y a quelques années, l’Ads Frontend était l’un de ces services. Il est utilisé par les annonceurs et les éditeurs de sites Web pour mettre en place, configurer, exécuter et contrôler leurs campagnes publicitaires. Étant donné que la majeure partie de ce travail a lieu pendant les heures de travail normales, nous avons déterminé que des interruptions occasionnelles, régulières et planifiées sous forme de fenêtres de maintenance seraient acceptables, et nous avons compté ces interruptions planifiées comme des temps d’arrêt planifiés, et non comme des temps d’arrêt non planifiés.

Coût

Le coût est souvent le facteur clé pour déterminer l’objectif de disponibilité approprié pour un service. Les annonces sont particulièrement bien placées pour faire ce compromis car les succès et les échecs des demandes peuvent être directement traduits en recettes gagnées ou perdues. Pour déterminer l’objectif de disponibilité de chaque service, nous posons des questions telles que :

  • Si nous construisons et exploitons ces systèmes avec une disponibilité d’un neuf de plus, quelle serait l’augmentation de nos revenus ?
  • Ces recettes supplémentaires compensent-elles le coût de l’atteinte de ce niveau de fiabilité ?

Pour rendre cette équation de compromis plus concrète, considérez le rapport coûts/avantages suivant pour un exemple de service où chaque demande a une valeur égale :

  • Objectif d’amélioration proposée de la disponibilité : 99,9 % → 99,99 %.
  • Augmentation proposée de la disponibilité : 0,09 %.
  • Revenu du service : 1M
  • Valeur de l’amélioration de la disponibilité : 1M $ * 0,0009 = 900 $.

Dans ce cas, si le coût de l’amélioration de la disponibilité d’un neuf est inférieur à 900 $, l’investissement en vaut la peine. Si le coût est supérieur à 900 $, les coûts seront supérieurs à l’augmentation prévue des revenus.

Autres mesures de services

L’examen de la tolérance au risque des services par rapport à d’autres mesures que la disponibilité est souvent fructueux. Comprendre quelles mesures sont importantes et quelles mesures ne le sont pas nous donne des degrés de liberté lorsque nous essayons de prendre des risques réfléchis.

La latence des services de nos systèmes de publicité en est un bon exemple. Lorsque Google a lancé la recherche sur le Web, l’une des principales caractéristiques du service était la vitesse. Lorsque nous avons introduit AdWords, qui affiche des annonces à côté des résultats de recherche, l’une des principales exigences du système était que les annonces ne devaient pas ralentir l’expérience de recherche. Cette exigence a déterminé les objectifs techniques de chaque génération de systèmes AdWords et est traitée comme un invariant.

AdSense, le système d’annonces de Google qui diffuse des annonces contextuelles en réponse aux demandes du code JavaScript que les éditeurs insèrent dans leurs sites Web, a un objectif de latence très différent. L’objectif de latence pour AdSense est d’éviter de ralentir le rendu de la page tierce lors de l’insertion d’annonces contextuelles. L’objectif de latence spécifique dépend donc de la vitesse de rendu de la page d’un éditeur donné. Cela signifie que les annonces AdSense peuvent généralement être diffusées des centaines de millisecondes plus lentement que les annonces AdWords.

Cette exigence moins stricte en matière de latence de diffusion nous a permis d’effectuer de nombreux compromis judicieux en matière de provisionnement (c’est-à-dire de déterminer la quantité et l’emplacement des ressources de diffusion que nous utilisons), ce qui nous permet de réaliser des économies substantielles par rapport à un provisionnement naïf. En d’autres termes, étant donné la relative insensibilité du service AdSense à des changements modérés dans les performances de latence, nous sommes en mesure de consolider la desserte dans moins de sites géographiques, réduisant ainsi nos frais d’exploitation.

Identification de la tolérance au risque des services d’infrastructure

Les exigences relatives à la construction et au fonctionnement des composants d’infrastructure diffèrent de celles des produits de consommation à plusieurs égards. Une différence fondamentale est que, par définition, les composants d’infrastructure ont de multiples clients, dont les besoins varient souvent.

Niveau cible de disponibilité

Considérons Bigtable [Cha06], un système de stockage distribué à grande échelle pour les données structurées. Certains services consommateurs servent des données directement à partir de Bigtable sur le chemin d’une demande de l’utilisateur. Ces services ont besoin d’une faible latence et d’une grande fiabilité. D’autres équipes utilisent Bigtable comme un référentiel pour les données qu’elles utilisent pour effectuer des analyses hors ligne (par exemple, MapReduce) sur une base régulière. Ces équipes ont tendance à être plus préoccupées par le débit que par la fiabilité. La tolérance au risque pour ces deux cas d’utilisation est très distincte.

Une approche pour répondre aux besoins des deux cas d’utilisation consiste à concevoir tous les services d’infrastructure pour qu’ils soient ultra-fiables. Étant donné que ces services d’infrastructure ont également tendance à regrouper d’énormes quantités de ressources, une telle approche est généralement beaucoup trop coûteuse dans la pratique. Pour comprendre les différents besoins des différents types d’utilisateurs, vous pouvez examiner l’état souhaité de la file d’attente des demandes pour chaque type d’utilisateur de Bigtable.

Types d’échecs

L’utilisateur à faible latence veut que les files d’attente de demandes de Bigtable soient (presque toujours) vides afin que le système puisse traiter chaque demande en suspens immédiatement après son arrivée. (En effet, une mise en file d’attente inefficace est souvent une cause de latence élevée). L’utilisateur concerné par l’analyse hors ligne est plus intéressé par le débit du système, il veut donc que les files d’attente ne soient jamais vides. Pour optimiser le débit, le système Bigtable ne devrait jamais avoir besoin de tourner au ralenti en attendant la prochaine demande.

Comme vous pouvez le voir, le succès et l’échec sont antithétiques pour ces groupes d’utilisateurs. Le succès pour l’utilisateur à faible latence est un échec pour l’utilisateur concerné par l’analyse hors ligne.

Coût

Une façon de satisfaire ces contraintes concurrentes de manière rentable est de partitionner l’infrastructure et de la proposer à plusieurs niveaux de service indépendants. Dans l’exemple de Bigtable, nous pouvons construire deux types de clusters : les clusters à faible latence et les clusters à haut débit. Les clusters à faible latence sont conçus pour être exploités et utilisés par des services qui ont besoin d’une faible latence et d’une grande fiabilité. Pour garantir des files d’attente courtes et répondre à des exigences plus strictes en matière d’isolement des clients, le système Bigtable peut être doté d’une quantité importante de capacité de réserve pour réduire la contention et augmenter la redondance. Les clusters de débit, d’autre part, peuvent être approvisionnés pour fonctionner à très haute température et avec moins de redondance, optimisant le débit sur la latence. En pratique, nous sommes en mesure de satisfaire ces besoins à un coût beaucoup plus faible, peut-être aussi peu que 10-50% du coût d’un cluster à faible latence. Étant donné l’échelle massive de Bigtable, cette économie de coût devient très rapidement significative.

La stratégie clé en ce qui concerne l’infrastructure est de fournir des services avec des niveaux de service explicitement délimités, permettant ainsi aux clients de faire les bons compromis en matière de risque et de coût lors de la construction de leurs systèmes. Avec des niveaux de service explicitement délimités, les fournisseurs d’infrastructure peuvent effectivement externaliser la différence de coût nécessaire pour fournir un service à un niveau donné aux clients. Le fait d’exposer les coûts de cette manière incite les clients à choisir le niveau de service le moins coûteux tout en répondant à leurs besoins. Par exemple, Google+ peut décider de placer les données essentielles au respect de la vie privée des utilisateurs dans un magasin de données à haute disponibilité et cohérent à l’échelle mondiale (par exemple, un système de type SQL répliqué à l’échelle mondiale comme Spanner [Cor12]), tout en plaçant les données facultatives (les données qui ne sont pas essentielles, mais qui améliorent l’expérience de l’utilisateur) dans un magasin de données moins cher, moins fiable, moins frais et finalement cohérent (par exemple, un magasin NoSQL avec une réplication au mieux comme Bigtable).

Notez que nous pouvons exécuter plusieurs classes de services en utilisant un matériel et un logiciel identiques. Nous pouvons fournir des garanties de service très différentes en ajustant une variété de caractéristiques de service, telles que les quantités de ressources, le degré de redondance, les contraintes d’approvisionnement géographique et, surtout, la configuration logicielle de l’infrastructure.

Exemple : Infrastructure frontale

Pour démontrer que ces principes d’évaluation de la tolérance au risque ne s’appliquent pas uniquement à l’infrastructure de stockage, examinons une autre grande catégorie de services : L’infrastructure frontale de Google. L’infrastructure frontale est constituée de systèmes de proxy inverse et d’équilibrage de charge fonctionnant à proximité de la périphérie de notre réseau. Ce sont les systèmes qui, entre autres choses, servent de point d’arrivée aux connexions des utilisateurs finaux (par exemple, terminent le TCP du navigateur de l’utilisateur). Compte tenu de leur rôle critique, nous concevons ces systèmes pour qu’ils offrent un niveau de fiabilité extrêmement élevé. Si les services aux consommateurs peuvent souvent limiter la visibilité du manque de fiabilité des backends, ces systèmes d’infrastructure n’ont pas cette chance. Si une requête n’arrive jamais jusqu’au serveur frontal du service d’application, elle est perdue.

Nous avons exploré les moyens d’identifier la tolérance au risque des services consommateurs et d’infrastructure. Nous allons maintenant aborder l’utilisation de ce niveau de tolérance pour gérer le manque de fiabilité via des budgets d’erreurs.

Motivation pour les budgets d’erreur

D’autres chapitres de cet ouvrage traitent des tensions qui peuvent apparaître entre les équipes de développement de produits et les équipes SRE, étant donné qu’elles sont généralement évaluées sur des mesures différentes. Les performances en matière de développement de produits sont largement évaluées en fonction de la vélocité des produits, ce qui incite à produire du nouveau code aussi rapidement que possible. Dans le même temps, les performances du SRE sont (sans surprise) évaluées en fonction de la fiabilité d’un service, ce qui incite à repousser un rythme de changement élevé. L’asymétrie d’information entre les deux équipes amplifie encore cette tension inhérente. Les développeurs de produits ont une meilleure visibilité sur le temps et les efforts nécessaires à l’écriture et à la publication de leur code, tandis que les SRE ont une meilleure visibilité sur la fiabilité du service (et l’état de la production en général).

Ces tensions se traduisent souvent par des opinions différentes sur le niveau d’effort à consacrer aux pratiques d’ingénierie. La liste suivante présente quelques tensions typiques :

Tolérance aux fautes du logiciel

Jusqu’à quel point devons-nous rendre le logiciel résistant aux événements inattendus ? Trop peu, et nous avons un produit fragile et inutilisable. Trop, et nous avons un produit que personne ne veut utiliser (mais qui fonctionne de manière très stable).

Tests

Encore une fois, si vous ne testez pas assez, vous risquez de subir des pannes embarrassantes, des fuites de données confidentielles ou d’autres événements dignes de la presse. Trop de tests, et vous risquez de perdre votre marché.

Fréquence des poussées

Chaque poussée est risquée. Dans quelle mesure devrions-nous travailler à réduire ce risque, plutôt que de faire autre chose ?

Durée et taille du canari

Une bonne pratique consiste à tester une nouvelle version sur un petit sous-ensemble d’une charge de travail typique, une pratique souvent appelée canarying. Combien de temps faut-il attendre, et quelle est la taille du canari ?

En général, les équipes préexistantes ont trouvé un équilibre informel entre elles quant à la limite risque/effort. Malheureusement, il est rarement possible de prouver que cet équilibre est optimal et qu’il n’est pas simplement fonction des talents de négociateur des ingénieurs concernés. Ces décisions ne doivent pas non plus être motivées par la politique, la peur ou l’espoir. (En effet, la devise officieuse de Google SRE est “L’espoir n’est pas une stratégie”). Notre objectif est plutôt de définir une mesure objective, acceptée par les deux parties, qui peut être utilisée pour guider les négociations de manière reproductible. Plus la décision est fondée sur des données, mieux c’est.

Établir votre budget d’erreur

Afin de fonder ces décisions sur des données objectives, les deux équipes définissent conjointement un budget d’erreurs trimestriel basé sur l’objectif de niveau de service du service, ou SLO (voir Objectifs de niveau de service). Le budget d’erreur fournit une mesure claire et objective qui détermine le niveau de non-fiabilité du service autorisé pour un trimestre donné. Cette mesure élimine la politique des négociations entre les SRE et les développeurs de produits lorsqu’il s’agit de décider du niveau de risque à autoriser.

Notre pratique est alors la suivante :

  • Le Product Management définit un SLO, qui fixe une attente quant au temps de fonctionnement du service par trimestre.
  • Le temps de fonctionnement réel est mesuré par une tierce partie neutre : notre système de surveillance.
  • La différence entre ces deux chiffres constitue le “budget” de la quantité de “non-fiabilité” restante pour le trimestre.
  • Tant que le temps de fonctionnement mesuré est supérieur au SLO - en d’autres termes, tant qu’il reste un budget d’erreur - de nouvelles versions peuvent être lancées.

Par exemple, imaginez que le SLO d’un service est de servir avec succès 99,999% de toutes les requêtes par trimestre. Cela signifie que le budget d’erreur du service est un taux d’échec de 0,001% pour un trimestre donné. Si un problème nous fait échouer 0,0002% des requêtes attendues pour le trimestre, le problème dépense 20% du budget d’erreur trimestriel du service.

Avantages

Le principal avantage d’un budget d’erreur est qu’il fournit une incitation commune qui permet au développement du produit et au SRE de se concentrer sur la recherche du bon équilibre entre innovation et fiabilité.

De nombreux produits utilisent cette boucle de contrôle pour gérer la vitesse de publication : tant que les SLO du système sont respectés, les publications peuvent se poursuivre. Si les violations des SLO sont suffisamment fréquentes pour épuiser le budget d’erreurs, les versions sont temporairement interrompues pendant que des ressources supplémentaires sont investies dans les tests et le développement du système pour le rendre plus résistant, améliorer ses performances, etc. Il existe des approches plus subtiles et plus efficaces que cette simple technique de marche/arrêt15 : par exemple, ralentir les mises en production ou les annuler lorsque le budget d’erreur de violation des SLO est sur le point d’être épuisé.

Par exemple, si le développement du produit veut faire l’impasse sur les tests ou augmenter la vitesse de poussée et que le SRE y résiste, le budget d’erreurs guide la décision. Lorsque le budget est important, les développeurs de produits peuvent prendre plus de risques. Lorsque le budget est presque épuisé, les développeurs de produits eux-mêmes pousseront pour plus de tests ou une vitesse d’exécution plus lente, car ils ne veulent pas risquer d’épuiser le budget et de retarder leur lancement. En fait, l’équipe de développement du produit s’autosurveille. Elle connaît le budget et peut gérer ses propres risques. (Bien sûr, ce résultat repose sur une équipe SRE ayant l’autorité d’arrêter réellement les lancements si le SLO n’est pas respecté).

Que se passe-t-il si une panne de réseau ou une défaillance du centre de données réduit le SLO mesuré ? De tels événements grugent également le budget des erreurs. Par conséquent, le nombre de nouveaux lancements peut être réduit pour le reste du trimestre. L’ensemble de l’équipe soutient cette réduction car chacun partage la responsabilité de la disponibilité.

Le budget permet également de mettre en évidence certains des coûts liés à des objectifs de fiabilité trop élevés, en termes de rigidité et de ralentissement de l’innovation. Si l’équipe a du mal à lancer de nouvelles fonctionnalités, elle peut choisir de relâcher l’objectif de fiabilité (et donc d’augmenter le budget d’erreurs) afin d’accroître l’innovation.

Perspectives clés

La gestion de la fiabilité des services est en grande partie une question de gestion du risque, et la gestion du risque peut être coûteuse. 100% n’est probablement jamais le bon objectif de fiabilité : non seulement il est impossible à atteindre, mais il s’agit généralement d’une fiabilité supérieure à ce que les utilisateurs d’un service souhaitent ou remarquent. Faites correspondre le profil du service au risque que l’entreprise est prête à prendre. Un budget d’erreur aligne les incitations et met l’accent sur l’appropriation conjointe entre le SRE et le développement de produits. Les budgets d’erreur facilitent la prise de décision concernant le rythme des mises en production et permettent de désamorcer efficacement les discussions sur les interruptions de service avec les parties prenantes, et permettent à plusieurs équipes de parvenir à la même conclusion sur le risque de production sans rancune.