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.
- Beim Ersten Aufruf: Die Seite wird locker 2,5 Sekunden laden. Das resultierende JSON sieht so aus:
{"quelle": "LANGSAME DATENBANK 🐢", "daten": "Wichtige Nutzerdaten!"}
- 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!
Login