Builders Academy
Cache Distribué — Stratégies et Patterns
1 of 1

Chapitre 1 · Leçon 1

Stratégies de Cache

Cache-Aside, Write-Through et invalidation

Section 1

Les 4 stratégies fondamentales

Step 1

Cache-Aside (Lazy Loading)

Cache-Aside : l'application gère le cache elle-même. Lecture → chercher dans le cache → si miss → aller en DB → mettre en cache. C'est la stratégie la plus courante.

snippet.typescript

typescript
1// ─── Cache-Aside (Read-Through Manuel) ───────────────────────
2// Lecture : cache first, DB si miss
3async function getTutorial(slug: string): Promise<Tutorial | null> {
4  const key = `tutorial:v2:${slug}`;  // Versionner la clé évite les données obsolètes
5
6  // 1. Lire le cache
7  const hit = await redis.get(key);
8  if (hit) {
9    metrics.increment("cache.hit");
10    return JSON.parse(hit);
11  }
12
13  // 2. Cache miss → DB
14  metrics.increment("cache.miss");
15  const tutorial = await db.tutorial.findUnique({
16    where: { slug },
17    include: { chapters: { include: { lessons: { orderBy: { order: "asc" } } } } },
18  });
19
20  // 3. Remplir le cache (seulement si résultat non-null)
21  if (tutorial) {
22    await redis.setex(key, 300, JSON.stringify(tutorial));
23    // TTL 300s = 5 min. Si souvent accédé, augmenter. Si données critiques, diminuer.
24  }
25
26  return tutorial;
27}
28
29// Écriture : mettre à jour DB + invalider le cache
30async function updateTutorial(id: string, data: UpdateDTO): Promise<Tutorial> {
31  const updated = await db.tutorial.update({ where: { id }, data });
32
33  // Invalider — ne pas mettre à jour le cache (risque de race condition)
34  const key = `tutorial:v2:${updated.slug}`;
35  await redis.del(key);
36  // Prochaine lecture → cache miss → DB → nouvelle mise en cache
37
38  return updated;
39}
40
41// ─── Write-Through ─────────────────────────────────────────────
42// Écriture → DB ET cache simultanément
43async function writeThrough(id: string, data: UpdateDTO): Promise<Tutorial> {
44  const updated = await db.tutorial.update({ where: { id }, data });
45  const key = `tutorial:v2:${updated.slug}`;
46  // Mettre à jour le cache en même temps que la DB
47  await redis.setex(key, 300, JSON.stringify(updated));
48  return updated;
49}
50// ✅ Cache toujours à jour
51// ❌ Latence d'écriture augmentée (DB + Redis)
52// ❌ On cache des données peut-être jamais lues (écriture "pour rien")

Step 2

Cache Stampede — le problème et la solution

Le cache stampede (ou thundering herd) se produit quand un cache expire et que des milliers de requêtes simultanées frappent la DB en même temps.

snippet.typescript

typescript
1// ─── Cache-Aside (Read-Through Manuel) ───────────────────────
2// Lecture : cache first, DB si miss
3async function getTutorial(slug: string): Promise<Tutorial | null> {
4  const key = `tutorial:v2:${slug}`;  // Versionner la clé évite les données obsolètes
5
6  // 1. Lire le cache
7  const hit = await redis.get(key);
8  if (hit) {
9    metrics.increment("cache.hit");
10    return JSON.parse(hit);
11  }
12
13  // 2. Cache miss → DB
14  metrics.increment("cache.miss");
15  const tutorial = await db.tutorial.findUnique({
16    where: { slug },
17    include: { chapters: { include: { lessons: { orderBy: { order: "asc" } } } } },
18  });
19
20  // 3. Remplir le cache (seulement si résultat non-null)
21  if (tutorial) {
22    await redis.setex(key, 300, JSON.stringify(tutorial));
23    // TTL 300s = 5 min. Si souvent accédé, augmenter. Si données critiques, diminuer.
24  }
25
26  return tutorial;
27}
28
29// Écriture : mettre à jour DB + invalider le cache
30async function updateTutorial(id: string, data: UpdateDTO): Promise<Tutorial> {
31  const updated = await db.tutorial.update({ where: { id }, data });
32
33  // Invalider — ne pas mettre à jour le cache (risque de race condition)
34  const key = `tutorial:v2:${updated.slug}`;
35  await redis.del(key);
36  // Prochaine lecture → cache miss → DB → nouvelle mise en cache
37
38  return updated;
39}
40
41// ─── Write-Through ─────────────────────────────────────────────
42// Écriture → DB ET cache simultanément
43async function writeThrough(id: string, data: UpdateDTO): Promise<Tutorial> {
44  const updated = await db.tutorial.update({ where: { id }, data });
45  const key = `tutorial:v2:${updated.slug}`;
46  // Mettre à jour le cache en même temps que la DB
47  await redis.setex(key, 300, JSON.stringify(updated));
48  return updated;
49}
50// ✅ Cache toujours à jour
51// ❌ Latence d'écriture augmentée (DB + Redis)
52// ❌ On cache des données peut-être jamais lues (écriture "pour rien")

Topics and skills covered

  • Redis
  • Cache
  • Cache-Aside
  • Write-Through
  • Invalidation