Zum Inhalt

Skalierung

Wenn der System-Health-Tab anschlägt, oder du proaktiv für Wachstum vorbauen willst.

Größenprofile

Profil Hosts Hardware WORKER_REPLICAS WORKER_CONCURRENCY PG_SHARED_BUFFERS PG_EFFECTIVE_CACHE
Klein < 50 2 GB / 1 Core 1 4 256 MB 512 MB
Mittel 50–500 4 GB / 2 Cores 2 4 512 MB 1 GB
Groß 500–2 000 8 GB / 4 Cores 3 8 1 GB 4 GB
XL > 2 000 16 GB+ / 8 Cores 4+ 8 2 GB 8 GB

Werte gelten als Startpunkt. Tatsächliches Tuning hängt von Check-Mix ab — viele SNMP-Walks brauchen mehr Worker, viele Agent-Checks brauchen mehr DB-Schreibrate.

Worker

Worker konsumieren den Redis-Stream und schreiben in die DB.

WORKER_REPLICAS=3      # Anzahl der Worker-Container
WORKER_CONCURRENCY=8   # Goroutines pro Worker
WORKER_BATCH_SIZE=200  # Messages pro DB-Insert-Batch

Mehr Worker helfen bei vielen kleinen Inserts. Mehr Batch hilft bei DB-Round-Trip-Limits.

Faustregel: pro 1 000 Hosts ein zusätzlicher Worker.

Anwenden:

docker compose -f /opt/vesana/docker-compose.prod.yml up -d

Postgres

PG_SHARED_BUFFERS=1GB       # ~25 % vom RAM
PG_WORK_MEM=64MB
PG_EFFECTIVE_CACHE=4GB      # ~50 % vom RAM
PG_MAX_CONNECTIONS=400

Connection-Limit ist der häufigste Engpass bei mehreren API-Replicas. Wenn pg_stat_activity voll: pgbouncer davorschalten (siehe unten) oder MAX_CONNECTIONS erhöhen (kostet RAM).

TimescaleDB-Compression

check_results und logs sind Hypertables. Compression reduziert Disk-Verbrauch um Faktor 6.

Seit v0.17.x

Default-Compression-Window ist 3 Tage (war 30 Tage) — Migration 116. Ältere Chunks werden automatisch komprimiert.

Manuell triggern:

SELECT compress_chunk(c) FROM show_chunks('check_results') c;

Retention

Default:

Tabelle Retention
check_results 90 Tage
logs 30 Tage

Konfigurierbar in Admin → Einstellungen → Retention. Niedriger = weniger Disk, weniger Historie.

Redis

REDIS_MAXMEMORY=1gb          # Default 512mb

Policy ist noeviction — Redis lehnt neue Daten ab statt alte zu löschen. Bei Stream-Überlauf siehst du das im System-Tab als „Receiver rejecting" — bedeutet: dringend skalieren.

Redis-Backups: nicht nötig, Stream-Inhalte sind transient. Bei Restart läuft alles ab vom letzten DB-State weiter.

API-Replicas

Mehrere API-Container hinter nginx-Upstream:

api:
  deploy:
    replicas: 3

Voraussetzung: Distributed Locking via Redis ist eingebaut — kritische Background-Jobs (Watcher) laufen pro Replica per Lock auf nur einem.

pgbouncer

Connection-Pool für viele Replicas. In docker-compose.prod.yml:

pgbouncer:
  image: edoburu/pgbouncer
  environment:
    DATABASE_URL: postgresql://vesana:${POSTGRES_PASSWORD}@postgres:5432/vesana
    POOL_MODE: transaction
    MAX_CLIENT_CONN: 1000
    DEFAULT_POOL_SIZE: 50

API-Services dann via pgbouncer:6432 statt postgres:5432.

Profil aktivieren:

docker compose -f /opt/vesana/docker-compose.prod.yml --profile pgbouncer up -d

Hot-Tables

current_status, agent_tokens haben Hot-Updates. Migration 115 setzt fillfactor=80 auf diese Tabellen — Update-Bloat reduziert.

agent_tokens.last_seen_at wird im Receiver gebatcht (60 s) gespeichert — sonst hätte jeder Heartbeat einen UPDATE-Roundtrip.

Compose-Profile

Profil Wann
Default Immer
ai wenn lokales Ollama
backup wenn Backup-Sidecar
pgbouncer bei vielen Replicas

Alle aktiv:

docker compose -f docker-compose.prod.yml \
  --profile ai --profile backup --profile pgbouncer \
  up -d

Vertikales vs. horizontales Skalieren

Pfad Vor- / Nachteil
Vertikal (mehr RAM/CPU am Server) Einfach, kein Architektur-Umbau, Limit irgendwann hardware-bedingt
Horizontal (mehrere API-Replicas + pgbouncer) Mehr Komplexität, dafür quasi linear bis zum DB-Limit

Empfehlung: erst vertikal skalieren, bis 16 GB RAM / 8 Cores erreicht sind. Dann horizontal.

Performance-Baseline

50 000 Checks Skalierungs-Test in scale-test/:

  • ~960 checks/s sustained mit Default-Config
  • p95 ≤ 150 ms
  • 0 Errors über 30 min Soak
  • 6 Bugs gefunden + gefixt während Test (siehe Changelog v0.17.x)

Bei deinem Workload: System-Tab beobachten, bei Yellow-Bandbreite anfangen zu skalieren.

Externalisieren (Postgres / Redis)

Bei sehr großen Setups kann es sinnvoll sein, Postgres oder Redis aus dem Compose-Stack zu nehmen und einen managed Service oder dedizierte VMs zu nutzen.

Schritte:

  1. Externe Instanz aufsetzen
  2. Daten migrieren (pg_dump / pg_restore)
  3. DATABASE_URL in .env umstellen
  4. Postgres-Service aus Compose entfernen oder Dependencies anpassen

Test-Restore vorher in einer Test-Umgebung — der Pfad ist nicht offiziell unterstützt.

Anschluss