Be Software Architecture Wise
Be Wise Apps

Read in English · Leer en español · Auf Deutsch lesen

Section 6.8 sur 6.8 · Intermédiaire · 28 min de lecture

Architectures serverless et basées sur l’espace

Leçon vidéo

5 min · narré en anglais, avec sous-titres
Écouter seulement (audio)
Lire la transcription

Cette leçon présente deux styles qui répondent à la question de la capacité de manières opposées. Le serverless ne fait payer que l’usage. L’architecture basée sur l’espace sert les pics extrêmes depuis la mémoire. Ce sont deux outils spécialisés, et tous deux sont souvent choisis pour de mauvaises raisons.

Une station de taxis ne fait payer que chaque trajet. Quand personne n’a besoin d’une course, vous ne payez rien, mais lors d’une soirée chargée chaque trajet coûte plus cher que de posséder une voiture. Et le premier taxi peut mettre un moment à arriver. C’est le serverless. Imaginez maintenant la billetterie d’un stade avant un énorme concert. Au lieu que chaque guichetier consulte un registre central unique, chaque guichet garde sa propre copie des places libres, et transmet ses ventes au back-office plus tard. C’est l’architecture basée sur l’espace, conçue pour la ruée.

Serverless ne veut pas dire qu’il n’y a pas de serveurs. Cela veut dire que votre équipe n’a pas à les provisionner, à les corriger, à les dimensionner, ni à les payer quand ils sont inactifs. Avec les fonctions en tant que service, des événements déclenchent de petits morceaux de votre propre code. Ici, une requête web, un message de file, une photo envoyée et une planification nocturne déclenchent chacun une fonction, dont le fournisseur crée, met à l’échelle et détruit les instances. Avec le backend en tant que service, des services entièrement managés remplacent des parties côté serveur : une base de données, l’e-mail et le stockage de fichiers. Les fonctions sont sans état et de courte durée. Tout l’état durable réside dans des services managés : un système serverless est donc par construction un système distribué.

Sans trafic, rien ne tourne et aucun calcul n’est facturé. À mesure que les événements arrivent, de nombreuses instances démarrent en parallèle, et mille d’entre elles peuvent submerger une base de données de connexions. Vous payez par requête, plus la mémoire multipliée par le temps d’exécution. Un code qui attend une API lente paie pour attendre. La première requête adressée à une nouvelle instance attend pendant son démarrage, de quelques dizaines de millisecondes à plusieurs secondes. Ces démarrages à froid frappent surtout les pics soudains. Les fonctions ne conservent rien entre deux appels, s’exécutent sous des limites strictes, et de nombreux déclencheurs livrent au moins une fois : les gestionnaires doivent donc être idempotents. Et le serverless vous lie étroitement à votre fournisseur. Une voie médiane consiste à garder la logique métier dans des modules ordinaires derrière des ports, avec de minces gestionnaires de fonctions comme adaptateurs.

Est-ce moins cher ? La section fait le calcul avec des prix ronds illustratifs, et non avec les prix réels d’un fournisseur. Deux machines virtuelles toujours actives et un équilibreur de charge coûtent cent livres fixes par mois. Sous forme de fonctions, la même API de carte coûte environ trois livres vingt par million de requêtes, un coût qui augmente avec le trafic. Les courbes se croisent à environ trente et un millions de requêtes par mois, soit à peu près douze par seconde. En dessous, le serverless est moins cher, car le temps d’inactivité est gratuit. Au-dessus, un service constamment chargé paie davantage. Ce calcul laisse de côté les personnes, dont le temps peut coûter plus que la différence. Refaites donc le calcul avec des prix réels et un trafic mesuré.

L’architecture basée sur l’espace sort du chemin critique la base de données, que chaque requête sollicite généralement. Ici, pour une mise en vente de billets, une grille de messagerie achemine la requête de chaque acheteur vers une unité de traitement. Chaque unité, identique aux autres, détient en mémoire la logique et les données des places, et une grille de données réplique les modifications entre les unités. Les modifications atteignent la base de données plus tard : les pompes de données les mettent en file d’attente, et les rédacteurs de données les écrivent. Les lecteurs de données chargent les données de la base pour préchauffer la grille au démarrage. Le piège, ce sont les collisions de données : deux unités peuvent mettre à jour le même élément avant que la réplication ne rattrape son retard. Pour les données qui ne doivent jamais entrer en collision, comme la dernière place, acheminez toutes leurs requêtes vers une seule unité.

Imaginez une tournée des stades mise en vente à dix heures, avec environ quatre cent mille personnes qui attendent. Le système ne doit jamais vendre deux fois la même place, et ne doit pas s’effondrer. Les requêtes sont acheminées par spectacle et par section : une seule unité traite donc toutes les réservations temporaires d’une section. Les réservations temporaires ne peuvent jamais entrer en collision. Quand un acheteur choisit deux places, l’unité les réserve pendant huit minutes, en mémoire, en quelques microsecondes. Le paiement s’exécute avec une clé d’idempotence. En cas de succès, les places sont marquées comme vendues, et une pompe de données met la vente en file d’attente. La base de données est écrite à un rythme régulier qu’elle peut soutenir, et la file se vide quelques minutes après le pic. Aucun acheteur n’attend la base de données.

Le serverless convient au travail en pics, imprévisible ou de faible volume, au code de liaison piloté par les événements, aux tâches planifiées, et aux équipes sans capacité d’exploitation. Il convient mal à un trafic régulier à fort volume, aux processus de longue durée, et aux exigences strictes de latence de queue que les démarrages à froid ne permettraient pas de respecter. L’architecture basée sur l’espace est complexe et coûteuse, et la base de données est en retard sur la grille. Ne l’utilisez que pour des pics extrêmes. Essayez d’abord la mise en cache, les répliques en lecture, ou une salle d’attente virtuelle qui admet les acheteurs à un rythme contrôlé. C’est bien plus simple, et souvent suffisant à soi seul.

Ainsi s’achève le chapitre 6. Quand vous êtes prêt, passez le test facultatif du chapitre : vingt questions à choix multiples et deux réponses rédigées, avec une note de réussite de quatre-vingts pour cent. Ensuite, poursuivez avec le chapitre 7, consacré à l’architecture des données. À très vite.

Ce qu’il faut savoir

Deux réponses à la question de la capacité

Tous les styles vus jusqu’ici dans ce chapitre supposent que quelqu’un exploite des serveurs et les dimensionne en fonction de la charge. Cette section présente deux styles qui répondent à la question de la capacité de manières opposées. L’architecture serverless confie entièrement les serveurs à un fournisseur cloud et paie à l’usage, ce qui convient à un travail de petite taille, piloté par les événements et souvent inactif. L’architecture basée sur l’espace garde en mémoire tout ce dont une requête a besoin en période de forte charge, réparti sur de nombreuses unités identiques, afin que la base de données ne soit plus sur le chemin critique, ce qui convient à des pics extrêmes et soudains comme une mise en vente de billets. Ce sont deux outils spécialisés ; tous deux sont souvent choisis pour de mauvaises raisons.

Serverless : fonctions et back-ends managés

Le serverless ne veut pas dire qu’il n’y a pas de serveurs ; cela signifie que l’équipe n’a pas à provisionner, corriger, dimensionner ni payer des serveurs inactifs. L’article de Mike Roberts, publié en 2018 et largement cité, distingue deux ingrédients. Les fonctions en tant que service (FaaS) exécutent de petits morceaux du code propre à l’équipe en réponse à des événements, dans des conteneurs que le fournisseur crée, met à l’échelle et détruit, et qui peuvent ne vivre que le temps d’une seule invocation. AWS Lambda, annoncé en novembre 2014 et disponible pour tous en avril 2015, a démocratisé ce modèle ; Azure Functions, Google Cloud Run functions et Cloudflare Workers en sont d’autres exemples. Le backend en tant que service (BaaS) remplace des composants côté serveur par des services tiers entièrement managés, que le client ou la fonction appelle directement : authentification (Auth0, Amazon Cognito), bases de données (Firebase, DynamoDB), stockage d’objets, e-mail et files d’attente.

Une application serverless est généralement une combinaison : les fonctions contiennent la logique métier propre à l’organisation, et tout le reste, y compris tout l’état durable, réside dans des services managés. Le fournisseur gère la capacité, la disponibilité entre zones et le système d’exploitation. L’équipe reste responsable de son code, de ses données, de sa configuration et de ses paramètres de sécurité, comme l’explique le modèle de responsabilité partagée présenté dans les serveurs et le cloud.

Les événements déclenchent les fonctions ; l’état réside ailleurs

Des sources d’événements (gateway HTTP, file, stockage d’objets, planificateur) déclenchent des fonctions sans état, qui gardent leur état dans des services managésGateway HTTPPOST /ordersCréer commandefonctionFileOrderPlacedEnvoyer reçufonctionStockage objetsphoto carte envoyéeCréer miniaturesfonctionPlanif.chaque nuit à 02:00Régler virementsfonctionDéclencheursFonctions (FaaS)Services managés (BaaS)BD managéecmdes, virementsService e-mailreçusStockage objetsimagesChaque instance de fonction est sans état et éphémère ; tout l’état durable réside dans des services managés
Sur une plateforme de livraison de repas, quatre types d’événements déclenchent quatre fonctions, qui lisent et écrivent dans des services managés au lieu de conserver quoi que ce soit elles-mêmes.

Comment se comportent les fonctions : les caractéristiques qui façonnent la conception

Déclencheurs d’événements. Les fonctions s’exécutent en réponse à des événements : une requête HTTP passant par une gateway, un message dans une file ou un flux, un fichier déposé dans un stockage d’objets, une modification de base de données, ou une planification. Les déclencheurs qui invoquent la fonction de façon asynchrone, comme les files et les notifications de stockage, livrent généralement au moins une fois et réessaient en cas d’échec : les gestionnaires doivent donc être idempotents, exactement comme dans l’architecture pilotée par les événements.

Mise à l’échelle jusqu’à zéro et à l’horizontale. Sans trafic, aucune instance ne tourne et aucun calcul n’est facturé. À mesure que les événements arrivent, la plateforme démarre davantage d’instances en parallèle, jusqu’à une limite de concurrence fixée pour le compte ou pour la fonction ; sur AWS Lambda, la limite régionale par défaut est de 1000 exécutions simultanées au moment de la rédaction, et peut être relevée sur demande. Ce passage à l’échelle rapide est à la fois un atout et un danger : mille fonctions simultanées peuvent ouvrir mille connexions à la base de données et submerger une base de données relationnelle conçue pour quelques centaines, d’où l’existence des proxys de connexions et des plafonds de concurrence par fonction.

Facturation par invocation. Le coût est généralement une petite somme par requête, plus un montant pour la mémoire multipliée par le temps d’exécution (en gigaoctets-secondes). Un code qui attend sans rien faire une API en aval lente paie donc pour attendre.

Démarrages à froid (cold starts). La première requête adressée à une nouvelle instance doit attendre que la plateforme démarre un conteneur, charge l’environnement d’exécution et exécute le code d’initialisation : de quelques dizaines de millisecondes à plusieurs secondes, selon le langage, la taille du paquet et la configuration réseau. Les instances sont réutilisées pour les requêtes suivantes tant qu’elles restent chaudes, si bien que les démarrages à froid frappent surtout le trafic peu fréquent et les pics soudains. Parmi les parades figurent des paquets de déploiement plus petits, des environnements d’exécution plus légers, l’initialisation en dehors du gestionnaire, et le fait de payer pour garder des instances pré-initialisées (AWS appelle cela la concurrence provisionnée, ou provisioned concurrency), ce qui réintroduit en partie un coût permanent.

Limites. Les fonctions s’exécutent sous des limites strictes de durée d’exécution, de mémoire, de taille des données transmises et de disque temporaire ; pour AWS Lambda, au moment de la rédaction : 15 minutes, de 128 Mo à 10 240 Mo de mémoire (avec un CPU alloué en proportion) et 6 Mo pour une requête ou une réponse synchrone. Les tâches longues doivent être découpées en étapes, et les grosses données transmises par référence au stockage d’objets.

Absence d’état. Rien de ce qui se trouve dans la mémoire ou sur le disque local d’une instance n’est garanti de survivre jusqu’à l’invocation suivante. La mise en cache en mémoire entre deux appels est une optimisation qui peut fonctionner ou non, jamais un endroit où mettre des données importantes.

Où va l’état

Comme les fonctions ne conservent rien, le travail d’architecture se déplace vers le choix de l’endroit où réside chaque type d’état. Les données métier durables vont dans une base de données managée, souvent une base qui gère bien de nombreuses connexions de courte durée (bases clé-valeur ou orientées documents, ou base de données relationnelle derrière un proxy de connexions). Les gros objets vont dans le stockage d’objets et passent d’une fonction à l’autre par leur clé. L’état partagé de courte durée, comme les compteurs de limitation de débit, va dans un cache managé. La progression d’un processus en plusieurs étapes va dans un service de workflow (AWS Step Functions, Azure Durable Functions ou équivalent), qui joue le rôle d’orchestrateur de saga durable, comme décrit dans la section sur les sagas. Les sessions utilisateur vont dans des jetons conservés par le client ou dans un magasin de sessions.

La conséquence est qu’un système serverless est par construction un système distribué, avec toutes les préoccupations de ce chapitre : latence réseau entre chaque fonction et ses données, défaillance partielle, événements en double, cohérence à terme et besoin de traçage distribué. Une seule action métier peut traverser une gateway, trois fonctions, une file et deux bases de données. L’observabilité (voir observabilité) n’est pas facultative.

Couplage au fournisseur : le prix de ne pas exploiter de serveurs

Le serverless couple un système à son fournisseur plus étroitement que la location de machines virtuelles ou l’exécution de conteneurs. Les formats d’événements, la configuration des déclencheurs, les modèles d’identité et de permissions, les définitions de workflows et les services managés eux-mêmes sont tous propres au fournisseur. Migrer une application serverless mature vers un autre cloud tient davantage de la réécriture que de la migration.

Les praticiens ne s’accordent pas sur l’importance de ce point. Selon un premier point de vue, la dépendance au fournisseur (lock-in) est le prix d’une forte réduction du travail d’exploitation, et la plupart des organisations ne changent jamais de cloud : optimiser pour la portabilité serait donc un effort perdu. Selon l’autre, les changements de tarifs, les exigences réglementaires ou les acquisitions imposent bel et bien des migrations, et un couplage profond retire tout pouvoir de négociation. Une voie médiane consiste à accepter le couplage en périphérie et à le contenir dans le cœur : garder la logique métier dans des modules ordinaires derrière des ports, avec de minces gestionnaires de fonctions jouant le rôle d’adaptateurs (l’approche de l’architecture hexagonale), gérer l’infrastructure en tant que code, et consigner le couplage comme une décision explicite. Le coût et la dépendance au fournisseur sont approfondis dans FinOps et dépendance au fournisseur.

Exemple commenté

Exemple commenté : quand une capacité toujours active devient-elle moins chère ?

L’API de carte des restaurants de la plateforme de livraison de repas pourrait tourner sous forme de fonctions ou sur deux machines virtuelles toujours actives. Tous les prix sont des chiffres ronds illustratifs choisis pour faciliter le calcul, et non les prix catalogue actuels d’un quelconque fournisseur. Chaque requête s’exécute en moyenne pendant 200 ms avec 0,5 Go de mémoire : elle consomme donc 0,1 Go-seconde.

Prix serverless illustratifsCalcul : £0,00002 par Go-seconde ; £0,20 par million d’invocations ; £1,00 par million de requêtes passant par la gateway HTTP.
Coût serverless par million de requêtesCalcul : 1 000 000 × 0,1 Go-s × £0,00002 = £2,00. Invocations : £0,20. Gateway : £1,00. Total : £3,20 par million.
Coût illustratif d’une capacité toujours activeDeux petites VM à £40 par mois chacune (deux pour la redondance), plus un équilibreur de charge à £20 = £100 par mois, dimensionnées pour des pics d’environ 300 requêtes par seconde.
1 million de requêtes par mois (0,4 par seconde en moyenne)Serverless : £3,20 ; toujours actif : £100. Le serverless est environ 30 fois moins cher.
10 millions par mois (environ 4 par seconde)Serverless : £32 ; toujours actif : £100.
Point de bascule£100 ÷ £3,20 ≈ 31 millions de requêtes par mois, soit environ 12 requêtes par seconde en moyenne (31,25 millions ÷ 2,59 millions de secondes en 30 jours).
100 millions par mois (environ 39 par seconde)Serverless : £320 ; toujours actif : toujours £100, car deux VM ont encore de la marge.
Effet d’une réduction de moitié de la durée, à 100 msLe calcul tombe à £1,00, le total à £2,20 par million, et le point de bascule passe à environ 45 millions. En serverless, l’optimisation est directement rentable.

En dessous du point de bascule, le serverless est moins cher parce que le temps d’inactivité est gratuit ; au-dessus, un service constamment chargé paie davantage pour le même travail. Un trafic en rafales, avec de longues périodes d’inactivité, favorise le serverless même à des volumes plus élevés.

La comparaison brute laisse de côté le coût le plus important pour beaucoup d’équipes : les personnes. Les correctifs, la mise à l’échelle et l’astreinte pour des VM peuvent facilement coûter plus que la différence, ce qui repousse vers le haut le point de bascule réel. Les frais de transfert de données, de journalisation et d’observabilité s’appliquent aux deux et sont souvent plus élevés que l’une ou l’autre facture de calcul.

Comme le résultat dépend de la durée, de la mémoire, de la forme du trafic et des prix en vigueur, refaites le calcul avec des prix réels et un trafic mesuré avant de décider, puis à nouveau à mesure que le trafic augmente.

Le point de bascule, en graphique

Graphique linéaire du coût mensuel illustratif selon les requêtes mensuelles : le coût serverless croît linéairement et croise un coût toujours actif fixe vers 31 millions de requêtes par mois0255075100£0£100£200£300Requêtes par mois (millions)Coût parmoisToujours actif : £100Serverless : £3,20 par millionbascule à environ 31 millions(env. 12 requêtes par seconde)
Avec ces prix illustratifs, le coût serverless augmente de £3,20 par million de requêtes et rejoint le coût fixe de £100 de la capacité toujours active à environ 31 millions de requêtes par mois.

Quand le serverless convient, et quand il ne convient pas

Le serverless convient aux charges de travail en pics, imprévisibles ou de faible volume, pour lesquelles payer des serveurs inactifs est du gaspillage ; au code de liaison piloté par les événements, par exemple pour réagir à des envois de fichiers, à des messages de file et à des modifications de base de données ; aux tâches planifiées et à l’automatisation du back-office ; aux prototypes et nouveaux produits, pour lesquels l’équipe doit consacrer son temps au produit plutôt qu’à l’infrastructure ; et aux équipes sans capacité de plateforme ni d’exploitation.

Il convient mal à un trafic régulier et à fort volume, pour lequel la tarification par requête dépasse le coût d’une capacité toujours active (comme dans l’exemple commenté) ; aux processus de longue durée ou avec état, comme le transcodage vidéo au-delà de la limite de durée ou les serveurs WebSocket qui maintiennent de nombreuses connexions ; aux exigences strictes de faible latence de queue que les démarrages à froid ne permettraient pas de respecter ; aux charges de travail nécessitant du matériel spécial ou un contrôle fin de l’environnement d’exécution ; et aux conceptions à grain fin dans lesquelles de nombreuses fonctions s’appellent les unes les autres de façon synchrone, ce qui ajoute à chaque étape des sauts réseau, des coûts et des points de défaillance. Le chapitre 1 a décrit comment Amazon Prime Video, en 2023, a fait passer un service de supervision d’étapes serverless distribuées à un processus unique, et a fait état d’une baisse de plus de 90 % du coût d’infrastructure (pourquoi l’architecture compte) : ce n’est pas un verdict sur le serverless, mais un rappel que l’adéquation compte plus que la mode.

L’architecture basée sur l’espace : sortir la base de données du chemin critique

La plupart des architectures font facilement passer à l’échelle les niveaux web et applicatif, mais finissent par buter sur la base de données, que chaque requête sollicite. Ajouter des serveurs en amont ne fait que déplacer la file d’attente vers la base de données. L’architecture basée sur l’espace (space-based), telle que la décrivent Mark Richards et Neal Ford dans Fundamentals of Software Architecture, retire complètement la base de données du chemin synchrone. Chaque requête est traitée entièrement en mémoire par l’une des nombreuses unités de traitement identiques, et la base de données est mise à jour de façon asynchrone, en coulisses.

Le nom vient de l’espace de tuples, une mémoire associative partagée introduite en 1985 par Linda, le langage de coordination de David Gelernter : les processus communiquent en écrivant des tuples dans un espace partagé et en y lisant ou en y prélevant les tuples correspondants, sans se connaître les uns les autres. JavaSpaces, de Sun, a apporté l’idée à Java à la fin des années 1990, et des plateformes commerciales ont bâti sur elle des espaces distribués et répliqués, qui ont évolué vers les grilles de données en mémoire actuelles comme Hazelcast, Apache Ignite et Oracle Coherence.

Les composants d’un système basé sur l’espace

  1. Unité de traitementUnité déployable contenant la logique applicative et une grille de données en mémoire (in-memory data grid) qui détient les données dont cette logique a besoin, ainsi qu’un moteur de réplication. Les unités sont identiques : en ajouter une ajoute de la capacité. Dans l’exemple de la billetterie, chaque unité détient le plan des places et les réservations temporaires en cours pour les événements qu’elle sert.
  2. Middleware virtualiséL’infrastructure qui gère les unités. La grille de messagerie reçoit les requêtes et achemine chacune vers une unité disponible. La grille de données réplique les modifications entre les copies en mémoire des unités. La grille de traitement, facultative, coordonne les requêtes qui nécessitent plusieurs types d’unités. Le gestionnaire de déploiement démarre et arrête des unités à mesure que la charge augmente et diminue.
  3. Pompes de donnéesCanaux asynchrones, généralement des files de messages persistantes, qui transportent chaque modification faite dans une unité vers le côté base de données. Si la base de données est lente ou indisponible, les modifications attendent dans la file ; les acheteurs n’en sont pas affectés.
  4. Rédacteurs de donnéesComposants qui consomment les messages des pompes et écrivent les modifications dans la base de données. Ils peuvent être mis à l’échelle et mis en pause indépendamment des unités.
  5. Lecteurs de donnéesComposants qui chargent les données de la base de données dans les unités quand la grille démarre à froid, par exemple après le redémarrage ou le redéploiement de toutes les unités. Ils ne servent pas au traitement normal des requêtes.

L’architecture basée sur l’espace pour une mise en vente de billets

Architecture basée sur l’espace : les requêtes vont à des unités de traitement aux données en grille mémoire répliquée ; les mises à jour gagnent la base en asynchrone via pompes et rédacteursAcheteursMiddleware virtualiséGrille de messagerie : routageGest. déploiementUnité traitement 1logique + placesgrille mémoireUnité traitement 2logique + placesgrille mémoireUnité traitement 3logique + placesgrille mémoireGrille de données : réplication entre unitéspompesRédacteurs de donnéesBaseLecteurs de donnéeschargement initial
Les requêtes sont servies depuis la mémoire par des unités de traitement identiques ; la base de données est mise à jour de façon asynchrone par des pompes et des rédacteurs de données, et n’est lue que pour préchauffer la grille.

Collisions de données et autres coûts

Conserver des copies répliquées dans de nombreuses unités transpose en mémoire les problèmes de cohérence vus dans les sections précédentes. Avec un cache répliqué, chaque unité dispose d’une copie complète et les modifications sont copiées de façon asynchrone, ce qui permet des lectures locales rapides, mais deux unités peuvent mettre à jour le même élément avant que la réplication ne rattrape son retard. Richards et Ford appellent cela une collision de données et en estiment le taux comme le nombre d’unités multiplié par le carré du taux de mise à jour, divisé par le nombre d’éléments, multiplié par la latence de réplication. Avec 5 unités, 20 mises à jour par seconde, 50 000 éléments et 100 ms de latence, on obtient 5 × 400 ÷ 50 000 × 0,1 = 0,004 par seconde, soit environ 115 collisions sur une journée de huit heures ; réduire la latence à 1 ms ramène ce chiffre à environ une.

Pour les données qui ne doivent jamais entrer en collision, comme la dernière place d’une rangée, les alternatives sont un cache distribué, dans lequel chaque élément réside dans une seule partition, où chaque unité le lit et l’écrit (c’est cohérent, mais chaque accès est un appel réseau et les partitions de la grille doivent rester disponibles), ou l’acheminement de toutes les requêtes portant sur un même événement ou une même section vers la même unité, pour qu’une seule unité modifie jamais ces places. La plupart des conceptions réelles combinent les deux : partitionner par clé les données chaudes et disputées, et répliquer les données surtout lues, comme les plans de salle et les prix.

Les autres coûts sont importants. Les données conservées en mémoire sont limitées par la taille de la mémoire et doivent être reconstruites après un redémarrage complet. La base de données est cohérente à terme avec la grille : les rapports et les autres systèmes voient donc les modifications avec retard, et la perte de modifications en file d’attente est un risque réel que la durabilité des pompes doit couvrir. Les tests à une charge de pointe réaliste sont coûteux et difficiles. Et ce style est complexe et coûteux à construire : Richards et Ford lui attribuent une note faible en simplicité et en testabilité, et élevée en coût. Il n’en vaut la peine que lorsque la charge ne peut vraiment pas être absorbée par la mise en cache, les répliques en lecture et une base de données bien réglée.

Exemple commenté

Exemple commenté : une mise en vente pour un stade

Les billets d’une tournée des stades sont mis en vente à 10:00. Environ 400 000 personnes attendent ; pendant les dix premières minutes, la demande représente des centaines de fois le niveau normal, puis elle retombe. Le système de billetterie ne doit pas vendre deux fois la même place et ne doit pas s’effondrer.

Avant la mise en venteLes lecteurs de données chargent dans la grille le plan des places de chaque spectacle. Le gestionnaire de déploiement démarre suffisamment d’unités de traitement pour le pic prévu.
RoutageLa grille de messagerie achemine les requêtes par spectacle et par section, si bien que toutes les réservations temporaires pour la section 112 du spectacle du samedi sont traitées par la même unité. Les réservations temporaires n’entrent jamais en collision.
Un acheteur sélectionne deux placesL’unité les marque HELD pour cet acheteur pendant 8 minutes, en mémoire, en quelques microsecondes, et répond. Les plans des places des autres acheteurs se mettent à jour par réplication.
La réservation temporaire devient une venteL’étape de paiement s’exécute (un appel externe, avec une clé d’idempotence) ; en cas de succès, l’unité marque les places SOLD et une pompe de données met la vente en file d’attente.
La base de donnéesLes rédacteurs de données écrivent les ventes à un rythme régulier que la base de données peut soutenir. Pendant le pic, la file grossit ; elle se vide quelques minutes après la baisse de la demande. Aucune requête d’acheteur n’attend la base de données.
Une réservation temporaire expireL’unité libère les places en mémoire ; la pompe met en file d’attente un enregistrement de libération.

De nombreux systèmes de billetterie placent aussi une salle d’attente virtuelle devant la vente, qui admet les acheteurs à un rythme contrôlé. C’est beaucoup plus simple, et souvent suffisant à soi seul ; l’architecture basée sur l’espace est faite pour les cas où la charge admise reste elle-même trop élevée pour une conception centrée sur la base de données.

Le routage par section est la décision de conception qui fait passer le problème des collisions de « rare mais possible » à « impossible » pour les données les plus importantes.

Caractéristiques comparées (qualitatives, pour des conceptions typiques)

CaractéristiqueServerless (FaaS et BaaS)Basée sur l’espace
ÉlasticitéTrès élevée, automatique, y compris la réduction à zéroTrès élevée pour les pics, mais les unités mettent du temps à démarrer et à charger les données
PerformancesBon niveau à chaud ; les démarrages à froid et les sauts réseau ajoutent de la latenceNiveau très élevé : requêtes servies depuis la mémoire
Profil de coûtPaiement à l’usage ; excellent en cas d’inactivité ou de pics, cher en cas de charge constanteÉlevé : nombreuses unités, beaucoup de mémoire, middleware complexe, toujours actif
SimplicitéSimple par fonction ; le système dans son ensemble peut devenir difficile à suivreFaible : réplication, collisions, pompes et chargement au démarrage à froid
CohérenceCe que fournissent les magasins de données managésRéplication en mémoire à terme, sauf si les données disputées sont partitionnées ; la base de données est en retard
TestabilitéLes unités sont faciles à tester ; l’intégration nécessite des environnements cloudDifficile : les tests de pointe réalistes coûtent cher
Effort d’exploitationFaible pour l’infrastructure ; élevé pour l’observabilité et les limitesÉlevée
PortabilitéFaible : déclencheurs et services propres au fournisseurMoyenne : dépend du produit de grille de données

Liste de contrôle : avant de choisir le serverless ou l’architecture basée sur l’espace

Répondez-y avec des chiffres mesurés quand vous le pouvez.

  • Forme du traficLa charge est-elle en pics, souvent inactive ou régulière ? Le serverless récompense l’inactivité ; l’architecture basée sur l’espace récompense les pics extrêmes ; une charge régulière favorise des services ordinaires toujours actifs.
  • Point de bascule des coûtsAvez-vous comparé le coût par requête au coût d’une capacité toujours active avec des prix, des durées et un trafic réels, en incluant la gateway, le transfert de données et les personnes ?
  • Budget de latenceLe temps de réponse le plus lent acceptable peut-il absorber un démarrage à froid, ou le saut réseau jusqu’à l’endroit où réside l’état ?
  • LimitesDes tâches dépassent-elles les limites de durée d’exécution, de mémoire ou de taille des données ? Peuvent-elles être découpées en étapes ou leurs données transmises par référence ?
  • État et connexionsOù réside chaque type d’état, et les magasins de données peuvent-ils supporter des rafales soudaines de connexions simultanées ?
  • IdempotenceChaque gestionnaire peut-il s’exécuter deux fois sans risque pour le même événement ?
  • ContentionPour les conceptions basées sur l’espace, quelles données sont disputées, et seront-elles partitionnées ou routées de façon à ne pas pouvoir entrer en collision ?
  • Durabilité des écritures en attenteSi la grille ou les pompes tombent en panne, que perd-on ? Les pompes sont-elles persistantes, et le retard de la base de données est-il acceptable pour les rapports et les autres systèmes ?
  • Alternatives plus simplesLa mise en cache, des répliques en lecture, une file d’attente devant la base de données ou une salle d’attente virtuelle répondraient-elles au besoin avec moins de complexité ?
  • Décision sur la dépendance au fournisseurLe couplage au fournisseur ou au produit de grille est-il consigné comme une décision consciente, avec la logique métier maintenue derrière des ports ?

Vérifiez votre compréhension

Pourquoi une fonction déclenchée par une file doit-elle être idempotente ?

Parce que les déclencheurs asynchrones livrent généralement au moins une fois et réessaient en cas d’échec : le même événement peut donc invoquer la fonction plus d’une fois.

Avec les prix illustratifs de l’exemple commenté, combien coûteraient environ 50 millions de requêtes par mois en serverless, et quelle option est la moins chère ?

50 × £3,20 = £160 par mois : l’option toujours active à £100 est donc moins chère en coût brut d’infrastructure, avant de compter les personnes et les autres frais.

Dans l’architecture basée sur l’espace, que font les lecteurs de données, et quand ?

Ils chargent les données de la base de données dans les grilles en mémoire des unités de traitement quand la grille démarre à froid, par exemple après un redémarrage complet ou un redéploiement ; ils ne servent pas pour les requêtes normales.

En quoi l’acheminement de toutes les requêtes d’une même section du stade vers une seule unité de traitement aide-t-il ?

Seule cette unité modifie jamais ces places : deux unités ne peuvent donc pas mettre à jour la même place avant que la réplication ne rattrape son retard, ce qui élimine les collisions de données pour ces données.

Fin du chapitre 6Passer le test du chapitreFacultatif : 20 questions à choix multiples et 2 réponses rédigées, dans l’application.Accéder au test →

Sources et lectures complémentaires

Une question sur cette section ? ArchitectBot, l’assistant d’étude IA du cours, répond d’abord à partir du cours.

Demander : « Notre site de billetterie s’effondre chaque fois qu’un grand spectacle est mis en vente. Devons-nous passer au serverless, à l’architecture basée sur l’espace, ou à quelque chose de plus simple comme une salle d’attente virtuelle ? »