← Zurück zur Übersicht Speed-Boost für Node.js: Caching mit Redis einfach implementiert

Speed-Boost für Node.js: Caching mit Redis einfach implementiert

[WERBUNG: CONTENT OBEN]

Warum du einen Cache brauchst

Wenn deine Node.js-API Daten ausraten muss – sei es aus einer langsamen Datenbank, einer Third-Party-API oder durch komplexe Berechnungen –, entstehen Engpässe. Wenn 10.000 User dieselbe Anfrage stellen und deine App jedes Mal die Datenbank sekundenlang blockiert, bricht dein Server ein.

Die Lösung ist Redis, eine extrem schnelle In-Memory-Datenbank. Redis speichert das Ergebnis der teuren Anfrage im Arbeitsspeicher. Wenn der zweite User nach exakt demselben Ergebnis fragt, liefert Redis es in unter einer Millisekunde aus!

In diesem Guide bauen wir nicht nur einen nackten Redis-Server auf, sondern zeigen das echte Zusammenspiel: Eine Node.js App und ein Redis-Server in einer Docker-Umgebung, absolut isoliert.

Vorbereitung: Psychologische Sicherheit

Wir starten immer sauber. Damit du dir nicht versehentlich Dateistrukturen zerschießt, legen wir ein strikt isoliertes Demoprojekt an.

Öffne dein Terminal und führe diese Befehle aus:

mkdir redis-cache-demo
cd redis-cache-demo

Von nun an erstellst du alle Dateien nur noch in diesem Ordner.

Der Code: API & Cache in Harmonie

Wir benötigen nun unseren Infrastruktur-Code (Docker Compose) und unseren Applikations-Code (Node.js). Lege die folgenden drei Dateien exakt so an:

redis-cache-demo/package.json:

{
  "dependencies": {
    "express": "^4.18.2",
    "redis": "^4.6.10"
  }
}

redis-cache-demo/server.js:

const express = require('express');
const redis = require('redis');

const app = express();
const redisClient = redis.createClient({
  // 'cache' ist der interne Netzwerk-Name, den wir gleich in Docker Compose definieren
  url: 'redis://cache:6379'
});

redisClient.on('error', (err) => console.log('Redis Client Error', err));

async function fetchExpensiveData() {
  // Simuliert eine sehr langsame Datenbank-Abfrage von 2,5 Sekunden
  return new Promise(resolve => setTimeout(() => resolve("Wichtige Nutzerdaten!"), 2500));
}

app.get('/api/data', async (req, res) => {
  try {
    // 1. Prüfen, ob Daten schon im Cache liegen
    const cachedData = await redisClient.get('user_data');
    if (cachedData) {
      return res.json({ quelle: 'REDIS CACHE ⚡', daten: cachedData });
    }

    // 2. Daten waren NICHT im Cache: Mühsam berechnen...
    console.log("Cache Miss! Berechne mühsam...");
    const newData = await fetchExpensiveData();

    // 3. Neu berechnete Daten in Redis für künftige Anfragen speichern (Gültigkeit: 30 Sekunden)
    await redisClient.setEx('user_data', 30, newData);

    res.json({ quelle: 'LANGSAME DATENBANK 🐢', daten: newData });
  } catch (err) {
    res.status(500).json({ error: err.message });
  }
});

async function start() {
  await redisClient.connect();
  app.listen(3000, () => console.log('Node API gestartet auf Port 3000'));
}

start();

redis-cache-demo/docker-compose.yaml:

version: '3.8'

services:
  # Das Herzstück: Unser In-Memory Cache
  cache:
    image: redis:7-alpine
    container_name: local_redis
    restart: unless-stopped
    ports:
      - "6379:6379"

  # Unsere API, die vom Cache profitiert
  api:
    image: node:18-alpine
    container_name: local_node_api
    working_dir: /app
    volumes:
      - ./server.js:/app/server.js
      - ./package.json:/app/package.json
    command: sh -c "npm install && node server.js"
    ports:
      - "3000:3000"
    depends_on:
      - cache

Die ultimative Performance testen

Anstatt mühsam Container einzeln hochzufahren (via docker run), startet uns Docker Compose nun beide Welten und vernetzt sie vollautomatisch. Führe im Terminal aus:

docker compose up -d

⚠️ 📸 SCREENSHOT ANFRAGE: Hier einen Screenshot vom Terminal einfügen, der den Start der Container (local_redis, local_node_api) zeigt.

Millisekunden statt Sekunden

Wir testen nun unsere API! Öffne im Browser http://localhost:3000/api/data.

  1. Beim Ersten Aufruf: Die Seite wird locker 2,5 Sekunden laden. Das resultierende JSON sieht so aus:
{"quelle": "LANGSAME DATENBANK 🐢", "daten": "Wichtige Nutzerdaten!"}
  1. Beim Zweiten Aufruf (einfach F5 drücken): Die Seite lädt jetzt sofort (unter 5 Millisekunden). Das JSON hat sich verändert:
{"quelle": "REDIS CACHE ⚡", "daten": "Wichtige Nutzerdaten!"}

⚠️ 📸 SCREENSHOT ANFRAGE: Hier einen Screenshot vom Browser-Fenster einfügen, der die "REDIS CACHE ⚡" Antwort zeigt.

Deine App skaliert nun massiv besser! Nach exakt 30 Sekunden verfällt der Cache-Eintrag übrigens (dank setEx in Node.js) und die Daten würden beim nächsten Request wieder frisch aus der langsamen Funktion gezogen werden.

Fazit

Zwei einfache Dateien und schon hast du eine blitzschnelle, caching-optimierte API-Architektur simuliert. Der Cache fängt den kritischen Server-Traffic ab und bewahrt deine langsame Datenbank vor dem Kollaps ("Database Meltdown"). Perfekt für Black-Friday Traffic-Spitzen!

[WERBUNG: CONTENT UNTEN]