Lors d'un entretien de conception de systèmes comme dans un document de conception, c'est le diagramme qui rend le raisonnement visible. Une boîte étiquetée « cache » se dessine facilement ; ce qui rend le diagramme digne d'être lu, c'est de montrer pourquoi elle est là, quelle part du trafic elle absorbe et ce qui se passe quand le cache est froid.
Ce guide déroule un exercice classique, le réducteur d'URL, des exigences jusqu'au diagramme de conception de systèmes final. Le sujet n'est pas le réducteur lui-même, mais la méthode : d'abord les exigences et les chiffres, puis l'API et les données, puis les boîtes, chaque décision étant écrite là où tout le monde peut la voir.
Étape 1 : exigences
Fonctionnelles :
- Créer un lien court pour une URL longue, avec en option un alias personnalisé et une date d'expiration.
- Rediriger un lien court vers son URL longue.
- Compter les clics par lien.
Non fonctionnelles :
- Les redirections doivent être rapides et hautement disponibles ; la création de liens peut tolérer plus de latence.
- Le système est dominé par les lectures : un lien est créé une fois et cliqué de nombreuses fois.
- Les codes courts ne doivent pas être faciles à énumérer.
Étape 2 : calculs de coin de table
Supposons 100 millions de nouveaux liens par mois et 100 redirections par lien créé :
| Grandeur | Estimation |
|---|---|
| Écritures | 100M / 2,6M secondes par mois ≈ 40 par seconde en moyenne |
| Lectures | 100 × 40 ≈ 4 000 redirections par seconde ; prévoyez des pics à 10×, soit 40 000 par seconde |
| Liens après 5 ans | 100M × 12 × 5 = 6 milliards |
| Stockage | 6 milliards × ~500 octets ≈ 3 TB, hors réplicas |
| Longueur du code | 7 caractères en base62 donnent 62⁷ ≈ 3,5 billions de codes |
Les chiffres orientent déjà la conception : les lectures dominent, donc le chemin de lecture reçoit un cache ; 3 TB ne tiendront pas éternellement sur une petite base de données, donc le modèle de données doit se prêter à un sharding propre ; et 7 caractères laissent beaucoup de marge.
Étape 3 : API
POST /api/links
{ "url": "https://example.com/a/very/long/path", "alias": "launch", "expiresAt": "2027-01-01" }
→ 201 { "code": "launch", "shortUrl": "https://s.example/launch" }
GET /{code}
→ 302 Location: https://example.com/a/very/long/path
Une décision mérite une ligne sur le diagramme : 301 ou 302 ? Une 301 est permanente : les navigateurs la mettent en cache et les visites suivantes ne vous parviennent jamais. On économise du trafic, mais on perd le comptage des clics. Une 302 fait passer chaque clic par le service de redirection, et c'est ce dont l'analytique a besoin. Cette conception utilise la 302.
Étape 4 : modèle de données et identifiants
La table principale est simple : code (clé primaire), long_url, owner_id, created_at, expires_at. Chaque lecture est une recherche par code : un stockage clé-valeur comme une base relationnelle avec clé primaire font l'affaire, et un sharding sur un hachage de code répartit la charge uniformément.
La génération des codes est la partie intéressante :
| Approche | Avantages | Inconvénients |
|---|---|---|
| Compteur + base62 | Aucune collision | Les codes séquentiels sont faciles à énumérer ; demande de la coordination |
| 7 caractères aléatoires | Difficiles à deviner, sans coordination | Il faut vérifier les collisions à l'insertion |
| Hachage de l'URL | La même URL obtient le même code | Collisions à la troncature ; les alias demandent un traitement spécial |
Ici, l'API d'écriture réserve des plages d'identifiants auprès d'un allocateur de plages d'ID, par exemple un million à la fois, et brouille chaque identifiant par une permutation réversible avant l'encodage en base62 : les codes sont uniques sans vérification de collision et, vus de l'extérieur, ne se suivent pas.
Étape 5 : le diagramme
Séparez les chemins dont les exigences diffèrent. Le chemin d'écriture a un faible volume et doit être correct ; le chemin de lecture a un fort volume et doit être rapide ; l'analytique peut prendre du retard.
Contenu du diagramme
- Users
- Load balancer
- ID range allocator
- Write API
- Redirect service
- Cache: code → URL
- Links DB (sharded by code)
- click events
- Analytics workers
- Analytics store
- HTTPS
- POST · 40/s
- GET · 4k/s, peak 40k/s
- lease ID range
- INSERT link
- GET code
- on cache miss
- click event
- consume
- counts
Comment le lire :
- Chemin d'écriture (en haut). Le répartiteur de charge envoie
POST /api/linksà l'API d'écriture, qui prend un identifiant dans sa plage réservée, l'encode et écrit le lien dans la base de données. - Chemin de lecture (au milieu).
GET /{code}arrive au service de redirection, qui interroge d'abord Redis. Tant que les données chaudes tiennent en mémoire, la plupart des redirections ne touchent jamais la base. En cas de défaut de cache, le service lit la base de données et remplit le cache. - Analytique (en bas). Chaque redirection émet un événement de clic vers Kafka, et des workers d'analytique agrègent les compteurs dans le stockage analytique. La redirection n'attend jamais l'analytique.
Dessinez-le pour que le raisonnement se voie
- Mettez des chiffres sur les liens.
40/ssur le lien d'écriture et4k/s, peak 40k/ssur le lien de lecture expliquent le cache mieux que n'importe quelle étiquette. - Écrivez les hypothèses à côté des boîtes. « Taux de succès du cache visé : 90 % », « 302 pour l'analytique », « ID réservés par plages de 1M ».
- Séparez le synchrone de l'asynchrone. Des liens en trait plein pour le chemin des requêtes, en tirets pour les événements de clic.
- Montrez ce qui se passe en cas de panne. Si Redis tombe, les redirections se rabattent sur la base de données, avec une latence plus élevée ; écrivez-le sur le diagramme.
- Gardez les estimations sur le canevas. Un petit tableau de chiffres à côté du diagramme en fait un document de conception.
Approfondissements à préparer
- Cache. Les liens populaires suivent une distribution à longue traîne : un cache LRU avec un TTL modeste couvre l'essentiel du trafic. Invalidez à la suppression et à l'expiration.
- Montée en charge de la base de données. Les réplicas en lecture aident moins ici que le cache ; le sharding par code fait croître les écritures et le stockage de façon homogène.
- Expiration. Vérifiez
expires_atà la lecture et nettoyez en arrière-plan, plutôt que de lancer un gigantesque job de suppression. - Abus. Limitez le débit de création de liens par utilisateur et vérifiez les URL cibles dans des listes de logiciels malveillants.
Le construire dans Archboard
- Connectez-vous avec Google ou GitHub et créez un diagramme.
- Ajoutez un nœud Internet du pack Réseau pour les utilisateurs et un Répartiteur de charge cloud du pack Cloud pour la répartition de charge.
- Ajoutez l'API d'écriture, le service de redirection, l'allocateur d'ID et les workers d'analytique comme nœuds Conteneur du pack Modèle C4, avec le langage dans le champ Technologie.
- Ajoutez depuis le pack Données un Redis pour le cache, un Postgres pour la base des liens, un Sujet pour les événements de clic et un Entrepôt de données pour l'analytique.
- Étiquetez les liens avec les opérations et les débits, passez les événements de clic en tirets et placez les estimations dans un bloc Markdown du pack Base.
L'exemple utilise 11 nœuds de diagramme, bloc Markdown des estimations compris, et reste dans les limites de l'offre Free. Pour la méthode générale qui sous-tend tout diagramme d'architecture, consultez comment dessiner un diagramme d'architecture logicielle.
FAQ
Quel niveau de détail pour un diagramme de conception de systèmes en entretien ? Assez pour montrer les chemins de lecture et d'écriture, le stockage des données, le cache et une brique asynchrone. N'approfondissez que là où l'intervieweur le demande.
SQL ou NoSQL pour la table des liens ? Les deux conviennent pour une recherche par clé primaire. Choisissez selon la façon dont vous comptez sharder et ce que votre équipe sait bien exploiter, et écrivez la raison sur le diagramme.
Faut-il dessiner un CDN ? Seulement si vous mettez les redirections en cache en périphérie. Avec la 302 et le comptage des clics, le cache en périphérie a un intérêt limité, et beaucoup de conceptions s'en passent.
Pourquoi pas des 301 partout ? Une 301 économise du trafic, mais les navigateurs cessent de vous interroger : vous perdez les données de clics et ne pouvez plus changer la cible pour les visiteurs qui reviennent.
Où mettre les chiffres ? Sur le canevas, à côté du diagramme, pour que toute personne qui relit la conception puisse vérifier les hypothèses derrière les boîtes.