Skip to Content

Chapitre 15.4 — Scaling

⏱️ TL;DR — Ton site rame parce qu’il a du succès ? Ne cours pas acheter un serveur. D’abord mesurer (Partie 14) pour savoir quoi sature, puis optimiser — cache Nginx, CDN devant les assets, HTTP/2, compression, index de base, un peu de swap : souvent, ça suffit et c’est gratuit. Ensuite seulement, deux façons de grossir : verticalement (un plus gros VPS — simple, souvent un clic, mais un plafond et un point unique de défaillance) ou horizontalement (plusieurs serveurs derrière un load balancer — sans plafond, mais il faut gérer l’état partagé : sessions, fichiers, base). On sépare les rôles (web / base / cache sur des machines distinctes) et on garde un arbre de décision clair. Règle d’or : mesure, optimise, puis seulement scale.

🎯 Objectifs

  • Mesurer avant d’agir : identifier le vrai goulot d’étranglement (CPU, RAM, I/O, base).
  • Optimiser à moindre coût avant d’acheter du matériel (cache, CDN, compression, index).
  • Distinguer scaling vertical et scaling horizontal, avec leurs compromis.
  • Comprendre le rôle d’un load balancer et les défis de l’état partagé.
  • Séparer les rôles (web, base, cache) pour scaler chaque brique indépendamment.
  • Suivre un arbre de décision pour choisir quand et comment grossir.

D’abord mesurer, ensuite optimiser — enfin scaler

Le réflexe coûteux du débutant : « ça rame → je prends un serveur deux fois plus gros ». Mauvaise idée tant que tu ne sais pas ce qui sature. Un site lent peut l’être à cause d’une requête SQL sans index, d’images non compressées, d’un manque de cache — aucun de ces problèmes ne se règle en ajoutant du CPU. L’ordre correct est mesure → optimise → scale.

Mesurer (Partie 14) : htop (CPU, RAM), df -h (disque), free -h (mémoire/swap), le load average, les logs de requêtes lentes de la base. Objectif : nommer le goulot — est-ce le CPU ? la RAM (l’OOM killer rôde) ? les I/O disque ? une requête base ? On ne scale bien que ce qu’on a mesuré.

Optimiser (souvent gratuit, souvent suffisant) :

LevierCe que ça règleEffet
Cache Nginx (statique, proxy_cache)Requêtes répétées servies sans réveiller l’appDécharge l’app, réponses instantanées
CDN devant assets/vidéosImages, CSS, JS, vidéos servis depuis un réseau mondialDécharge le VPS, latence plus faible
HTTP/2Multiplexage des requêtes sur une connexionPages plus rapides à charger
Compression (gzip/brotli)Réponses plus légères sur le réseauMoins de bande passante, plus rapide
Index de baseRequêtes SQL lentes → rapidesSouvent le plus gros gain, gratuit
+ swapAbsorbe les pics de RAM sans OOM killerÉvite les crashs, pansement — pas une solution de fond

💡 Réflexe — Avant toute dépense de matériel, pose la question : « ai-je un problème de charge, ou un problème d’efficacité ? » Neuf fois sur dix au début, c’est l’efficacité : un index manquant, des images de 4 Mo, pas de cache. Optimiser coûte du temps, pas de l’argent récurrent — et le gain est souvent spectaculaire. Le matériel supplémentaire, lui, est une facture tous les mois.

⚠️ Piège — « Scaler » pour masquer un code inefficace. Doubler le serveur pour compenser une requête SQL sans index, c’est payer chaque mois pour ne pas avoir passé une heure à ajouter un CREATE INDEX. Tu déplaces le problème au lieu de le régler — et il reviendra, plus gros, au prochain palier de trafic.

Le CDN : le premier « scaling », gratuit ou presque

Un CDN (Content Delivery Network) est un réseau de serveurs répartis dans le monde qui mettent en cache et servent tes contenus statiques (images, CSS, JS, polices, vidéos) au plus près de chaque visiteur. C’est souvent le premier geste de scaling à faire, avant tout achat :

  • Il décharge ton VPS : les assets lourds (surtout les vidéos) ne passent plus par ton serveur, qui se concentre sur le dynamique.
  • Il réduit la latence : un visiteur à Tokyo reçoit l’image depuis un nœud proche, pas depuis ton datacenter européen.
  • Il absorbe les pics : une page virale ne fait plus tomber ton serveur, le CDN encaisse le statique.

Le tout pour un coût faible, voire nul aux volumes modestes. Mettre un CDN devant les assets, c’est retarder de loin le moment où tu auras besoin de plus de serveurs.

Scaling vertical vs horizontal

Quand l’optimisation ne suffit plus, deux directions pour grossir.

Scaling vertical (scale up) : prendre un VPS plus puissant (plus de vCPU, de RAM, de disque). Chez la plupart des fournisseurs, c’est un clic et un redémarrage.

  • Simple : rien à changer dans l’architecture, ton app tourne pareil, en plus grand.
  • ✅ Pas de complexité d’état partagé (tout reste sur une machine).
  • ❌ Un plafond : il existe une plus grosse offre, tu ne peux pas monter à l’infini.
  • ❌ Reste un point unique de défaillance (SPOF) : une seule machine, si elle tombe, tout tombe.

Scaling horizontal (scale out) : mettre plusieurs serveurs en parallèle, derrière un load balancer qui répartit le trafic entre eux.

  • Sans plafond théorique : tu ajoutes des serveurs selon la charge.
  • Résilience : si un serveur tombe, les autres continuent (base de la haute dispo, 15.5).
  • Complexe : il faut gérer l’état partagé (sessions, fichiers, base) — le vrai défi (voir plus bas).
  • ❌ Plus de pièces à opérer, surveiller, sécuriser.

💡 RéflexeCommence vertical, passe horizontal quand tu y es forcé. Le scaling vertical résout la majorité des besoins réels sans complexité : pour un site qui grossit normalement, un plus gros VPS (+ optimisation + CDN) tient très longtemps. On ne passe à l’horizontal que quand on atteint le plafond vertical ou qu’on a besoin de résilience (plus de SPOF) — pas « pour faire comme les géants du web ».

Le load balancer et l’état partagé

Un load balancer (répartiteur de charge) est la porte d’entrée du scaling horizontal : il reçoit tout le trafic et le distribue entre plusieurs serveurs web identiques. Ça peut être Nginx lui-même, HAProxy, ou un load balancer managé du fournisseur.

Mais dès qu’il y a plusieurs serveurs web, une requête d’un même utilisateur peut tomber sur n’importe lequel. D’où le problème du scaling horizontal : l’état partagé. Trois états à traiter :

ÉtatLe problèmeLa solution
SessionsConnecté sur le serveur 1, la requête suivante va sur le 2 → déconnectéStore partagé (Redis) ou sticky sessions (le LB garde l’utilisateur sur le même serveur)
Fichiers uploadésUploadé sur le serveur 1, invisible depuis le 2Stockage objet partagé (S3…), pas le disque local
Base de donnéesChaque web a besoin des mêmes donnéesUne seule instance de base (ou base managée), partagée par tous les web

Le principe unificateur : les serveurs web doivent devenir sans état (stateless). Tout ce qui doit être partagé (sessions, fichiers, données) sort du disque local du serveur web vers un service partagé — Redis pour les sessions, stockage objet pour les fichiers, une base commune pour les données. C’est ce qui rend les serveurs web interchangeables et donc multipliables à volonté.

⚠️ Piège — Passer à plusieurs serveurs web sans régler l’état partagé. Les utilisateurs sont déconnectés au hasard (sessions locales), leurs uploads disparaissent (fichiers sur un seul disque), et des incohérences apparaissent. L’état partagé n’est pas un détail d’optimisation : c’est la condition pour que l’horizontal fonctionne. Règle-le avant d’ajouter le deuxième serveur.

🔒 Sécurité — Multiplier les machines multiplie la surface d’attaque. Le trafic entre load balancer, serveurs web, cache et base doit rester sur un réseau privé (jamais ces ports ouverts sur Internet), la base et Redis n’écoutent pas en public, et chaque nouvelle machine est durcie au même niveau que la première (Partie 5). Une architecture distribuée mal cloisonnée offre plus de portes à l’attaquant.

Séparer les rôles

Avant même de multiplier les serveurs web, une étape intermédiaire puissante : séparer les rôles sur des machines distinctes. Au lieu de tout empiler sur un VPS (web + base + cache), on éclate :

  • Serveur web : Nginx + l’app (Next.js, Symfony…).
  • Serveur base de données : PostgreSQL, dédié, dimensionné pour l’I/O et la RAM.
  • Serveur cache : Redis, si besoin.

L’intérêt : chaque brique se dimensionne et se scale indépendamment (la base réclame de la RAM et du disque rapide ; le web réclame du CPU), et un pic sur l’une ne vient plus étouffer les autres. C’est aussi le prérequis naturel de l’horizontal : une fois la base sortie sur sa propre machine, tu peux multiplier les serveurs web devant elle.

L’arbre de décision

Face à « mon site rame » ou « le trafic monte », déroule cet arbre dans l’ordre — chaque étape est plus coûteuse que la précédente :

« Ça rame / le trafic monte » 1. As-tu MESURÉ le goulot ? ── non ──► mesurer (htop, df, requêtes lentes) d'abord │ oui 2. Peux-tu OPTIMISER ? ── oui ──► index DB, cache, CDN, compression, HTTP/2 (gratuit) │ non / déjà fait 3. Un CDN devant les assets suffit-il ? ── oui ──► poser le CDN (quasi gratuit) │ non 4. Le VERTICAL suffit-il ? ── oui ──► plus gros VPS (simple, un clic) │ non (plafond atteint / besoin de résilience) 5. SÉPARER LES RÔLES (web / base / cache sur des machines dédiées) │ toujours insuffisant 6. HORIZONTAL : load balancer + N serveurs web stateless (sessions → Redis, fichiers → objet, base → une instance/managée)

La leçon de l’arbre : les solutions gratuites et simples (mesurer, optimiser, CDN, vertical) viennent avant les solutions coûteuses et complexes (séparer, horizontal). La plupart des projets ne descendent jamais jusqu’à l’étape 6 — et c’est très bien.

📚 La doc — Les mécanismes précis (directives proxy_cache de Nginx, configuration d’un load balancer, upstream avec plusieurs backends, sticky sessions) sont dans la doc officielle Nginx et celle de ton load balancer/fournisseur. On enseigne ici la démarche et les compromis ; la syntaxe exacte, versionnée, se vérifie sur la référence.

🧭 Sur FormaCampus — Quand les inscriptions ont bondi à la rentrée, la première réaction de l’équipe n’a pas été d’acheter un serveur. Elle a mesuré : le CPU tenait, mais les vidéos de cours saturaient la bande passante du VPS et quelques requêtes de statistiques étaient lentes. Deux gestes gratuits : un CDN devant les vidéos et les assets (le VPS ne sert plus que le dynamique) et deux index sur les tables de progression. Résultat : le site a retrouvé sa vivacité sans changer de serveur. Le plan de scaling est écrit pour la suite : d’abord passer vertical (VPS plus gros) si la charge dynamique monte, puis sortir PostgreSQL sur sa propre machine, et seulement si nécessaire un load balancer devant plusieurs fronts Next.js — avec les sessions dans Redis et les uploads déjà sur stockage objet (ils y sont depuis les sauvegardes). L’horizontal est prévu, pas subi.

✏️ Exercices

Exercice 1 — Le bon ordre. Un site e-commerce devient lent aux heures de pointe. Le dev veut « prendre le plus gros VPS disponible ». Quelle est la première chose à faire à la place, et cite deux optimisations gratuites à tester avant tout achat.

✅ Solution

La première chose : mesurer pour identifier le goulot (Partie 14) — htop (CPU/RAM), load average, free -h (swap/OOM), et surtout les logs de requêtes lentes de la base. « Lent aux heures de pointe » sur un e-commerce sent la requête SQL non indexée ou l’absence de cache, pas forcément le manque de CPU. Deux optimisations gratuites à tester avant d’acheter : ajouter les index manquants sur les requêtes lentes (souvent le plus gros gain), et mettre un CDN devant les images/assets produits (décharge le VPS). On peut aussi activer cache Nginx, compression et HTTP/2. On n’achète du matériel qu’après avoir épuisé ces leviers — sinon on paie chaque mois pour masquer une inefficacité.

Exercice 2 — Vertical ou horizontal ? Pour chaque cas, choisis vertical ou horizontal et justifie : (A) un blog qui grossit régulièrement, jamais de pic extrême, un seul admin ; (B) un service qui doit rester en ligne même si un serveur tombe et absorber des pics imprévisibles.

✅ Solution

(A)vertical. Croissance régulière, pas de pic extrême, exigence de simplicité (un seul admin) : un plus gros VPS (+ CDN + optimisation) répond au besoin sans la complexité de l’état partagé. Inutile de gérer un load balancer et des sessions Redis pour un blog.

(B)horizontal. Le besoin de résilience (« rester en ligne même si un serveur tombe ») élimine le vertical, qui reste un point unique de défaillance. Il faut plusieurs serveurs derrière un load balancer (si l’un tombe, les autres tiennent) et une capacité d’ajout de serveurs pour absorber les pics — au prix de gérer l’état partagé (sessions, fichiers, base).

Exercice 3 — Diagnostique l’état partagé. Une équipe est passée à 2 serveurs web derrière un load balancer. Depuis, les utilisateurs se plaignent d’être déconnectés au hasard et de ne plus voir des photos qu’ils viennent d’uploader. Que s’est-il passé, et comment corriger ?

✅ Solution

C’est un problème d’état partagé non traité. Déconnexions au hasard : les sessions sont stockées localement sur chaque serveur ; quand le load balancer envoie la requête suivante sur l’autre serveur, la session n’y est pas → déconnexion. Correction : stocker les sessions dans un store partagé (Redis), ou activer les sticky sessions sur le load balancer. Photos disparues : les uploads sont écrits sur le disque local d’un seul serveur, invisibles depuis l’autre. Correction : envoyer les uploads vers un stockage objet partagé (S3…) accessible par tous les serveurs. Principe général : rendre les serveurs web stateless en sortant tout état partagé vers des services communs (Redis, objet, base unique).

🧠 Quiz de révision

1. Dans quel ordre aborde-t-on un problème de performance ?

Mesurer → optimiser → scaler. D’abord mesurer (Partie 14) pour identifier le vrai goulot (CPU, RAM, I/O, requête SQL). Ensuite optimiser — souvent gratuit et suffisant : index de base, cache Nginx, CDN, compression, HTTP/2. Seulement ensuite, si nécessaire, scaler le matériel. On ne paie du matériel qu’après avoir épuisé l’efficacité.

2. Scaling vertical vs horizontal : définis chacun et un inconvénient de chaque.

Vertical = un VPS plus gros (plus de CPU/RAM). Simple, souvent un clic, mais il a un plafond et reste un point unique de défaillance. Horizontal = plusieurs serveurs derrière un load balancer. Sans plafond et résilient, mais complexe : il faut gérer l’état partagé (sessions, fichiers, base) et plus de machines à opérer.

3. Qu’est-ce que « l’état partagé » et pourquoi est-ce le défi central de l’horizontal ?

C’est tout ce qui doit être cohérent entre les serveurs : sessions (sinon déconnexions au hasard), fichiers uploadés (sinon invisibles d’un serveur à l’autre), base de données. Avec plusieurs serveurs web, une requête peut tomber sur n’importe lequel : il faut donc sortir l’état du disque local vers des services partagés (Redis pour les sessions, stockage objet pour les fichiers, une base commune) et rendre les web stateless. Sans ça, l’horizontal casse l’expérience.

4. Pourquoi un CDN est-il souvent le premier geste de scaling ?

Parce qu’il décharge le VPS en servant les contenus statiques (images, CSS, JS, vidéos) depuis un réseau mondial proche de chaque visiteur : le serveur ne s’occupe plus que du dynamique, la latence baisse, et les pics de trafic sur le statique sont absorbés par le CDN. Le tout pour un coût faible ou nul — ça retarde de loin le besoin d’ajouter des serveurs.

5. Qu’apporte le fait de « séparer les rôles » (web, base, cache) ?

Chaque brique se dimensionne et se scale indépendamment (la base veut de la RAM et du disque rapide, le web du CPU), un pic sur l’une n’étouffe plus les autres, et c’est le prérequis du scaling horizontal : une fois la base sur sa propre machine, on peut multiplier les serveurs web devant elle.


Chapitre suivant : Haute disponibilité — viser la résilience sans sur-ingénierer : SPOF, redondance, failover et les « neuf ».

Last updated on