Skalierung¶
Umgezogen
Die konkreten Sizing-Profile (Klein/Mittel/Groß/XL), die Pipeline-Ampel und das Anwenden neuer Worker-/Postgres-/Redis-Werte findest du jetzt unter Admin → System → Ressourcen → Leistung — siehe Ressourcen. Diese Seite bleibt als konzeptioneller Leitfaden: wann reicht ein größeres Profil, wann brauchst du mehr?
Wann skalieren?¶
Anzeichen, dass die aktuelle Größe nicht mehr reicht:
- Pipeline-Ampel unter Ressourcen → Leistung steht auf gelb oder rot
- Die RAM-Verteilung unter Ressourcen → RAM zeigt einen Dienst (meist die Datenbank) dauerhaft nahe am Server-Limit
- Neue Check-Ergebnisse kommen sichtbar verzögert im Frontend an
Erste Reaktion: ein Sizing-Profil höher wählen (siehe Ressourcen → Leistung). Das deckt die meisten Fälle ab, ohne dass du einzelne .env-Variablen von Hand anfassen musst.
Vertikal vs. horizontal¶
| Pfad | Vor- / Nachteil |
|---|---|
| Vertikal — größeres Sizing-Profil, mehr RAM/CPU am Server | Einfach (ein Klick + Container-Neustart), kein Architektur-Umbau, irgendwann hardware-limitiert |
| Horizontal — mehrere API-Container, externe Datenbank/Redis | Mehr Komplexität, dafür Wachstum weit über einen einzelnen Server hinaus |
Empfehlung: erst vertikal bis zur größten sinnvollen Server-Konfiguration skalieren (XL-Profil, 16 GB+ RAM). Erst danach horizontal denken.
Externalisieren (Postgres / Redis)¶
Bei sehr großen Setups kann es sinnvoll sein, Postgres oder Redis aus dem Compose-Stack zu nehmen und einen dedizierten oder managed Dienst zu nutzen. Grober Ablauf:
- Externe Instanz aufsetzen (gleiche Postgres-Major-Version, TimescaleDB-Extension installiert)
- Daten migrieren (Dump aus dem eingebauten Backup einspielen)
- Verbindungs-Variable in der
.envauf die externe Instanz umstellen - Den entsprechenden Dienst aus dem eigenen Compose-Stack entfernen
Dieser Pfad ist nicht offiziell durchgetestet — vorher unbedingt an einer Test-Instanz durchspielen, inklusive eines vollständigen Restore-Drills.
Verbindungen zwischen nginx und API/Receiver¶
Seit Oktober 2026 hält nginx die Verbindungen zur API und zum Receiver offen und verwendet sie für weitere Anfragen wieder (Keepalive), statt für jede Anfrage eine neue TCP-Verbindung aufzubauen. Bei vielen Agents und Collectors spart das spürbar Rechenzeit. Wird ein Container neu erzeugt (Update, Neustart), findet nginx dessen neue Adresse nach wenigen Sekunden von selbst.
Zurückschalten (ohne Downgrade, ohne Änderung an der Compose-Datei):
cd /opt/vesana
docker compose -f docker-compose.prod.yml exec nginx touch /etc/nginx/ssl/vesana-upstream-keepalive.off
docker compose -f docker-compose.prod.yml restart nginx
# falls aktiv, ebenso: agent-gateway, nginx-admin
Danach öffnet nginx wieder für jede Anfrage eine eigene Verbindung, wie vor
Oktober 2026 — im Log des Containers steht Upstreams: direkt. Wieder
einschalten: die Datei löschen (rm statt touch) und die Container neu
starten. Die Datei liegt im ssl-Volume, das alle nginx-Container teilen;
sie überlebt Updates. Dieser Weg wirkt auf jeder Installation.
Mit der Compose-Datei ab Oktober 2026 geht es alternativ über die .env:
VESANA_NGINX_KEEPALIVE=off eintragen und docker compose up -d ausführen.
Auf Installationen mit einer älteren Compose-Datei kommt diese Variable nicht
im Container an — dort wirkt nur der Datei-Weg oben.
Wann zurückschalten: wenn nach einem Update vereinzelt 502-Antworten
auftreten, obwohl API und Receiver laufen, oder wenn ein eigener Aufbau
zwischen nginx und den Diensten (Proxy, Firewall) offene Verbindungen kappt.
Startet nginx mit den Keepalive-Einstellungen nicht (etwa ein selbst gebautes Image mit einem nginx älter als 1.27.3), schaltet der Container von selbst auf die bisherige Variante zurück und schreibt eine Warnung ins Log.
Durchsatz-Verbesserungen und ihre Notschalter¶
Seit Oktober 2026 verarbeitet Vesana mehr Ergebnisse pro Kern. Jede dieser
Änderungen lässt sich ohne Downgrade und ohne .env-Änderung auf das
vorherige Verhalten zurückstellen — per SQL in der Datenbank der Instanz:
INSERT INTO system_settings (key, value) VALUES ('<schlüssel>', '<wert>')
ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value;
| Schlüssel | Wert für „wie vorher" | Was es tut | Wann zurückschalten |
|---|---|---|---|
ingest_batch_transaction_enabled |
false |
Der Worker schreibt die Ergebnisse eines gelesenen Pakets in einer gemeinsamen Datenbank-Transaktion statt je Anfrage einzeln. Wirkt nach spätestens einer Minute. | Wenn im Diagnose-Log häufig result_batch_fallback steht oder Ergebnisse spürbar verzögert ankommen. |
worker_processes |
1 |
Anzahl der Verbraucher-Prozesse im Worker-Container (Standard: einer je 4 Kerne, höchstens 4). Wirkt beim nächsten Start des Worker-Containers. | Wenn der Server knapp an Arbeitsspeicher ist oder die Datenbank „too many clients" meldet. |
receiver_auth_cache_enabled |
false |
Der Receiver merkt sich gültige Anmeldungen von Agents und Collectors bis zu 60 Sekunden, statt jede Anfrage in der Datenbank zu prüfen. Ein Widerruf (Token entfernt, Host oder Mandant gelöscht oder deaktiviert) wirkt trotzdem nach spätestens einer Sekunde. Der Schalter wirkt nach spätestens 30 Sekunden. | Wenn ein widerrufener Agent oder Collector weiter Ergebnisse abliefert. |
receiver_collector_rate_limit_by_results |
false |
Ein Collector wird nach der Zahl seiner Ergebnisse begrenzt (Standard 120.000 je Minute) statt nach Anfragen (120 je Minute). Agents bleiben bei 120 Anfragen je Minute. Wirkt nach spätestens 30 Sekunden. | Wenn ein einzelner Collector den Receiver überlastet. |
receiver_collector_results_max |
Zahl | Obergrenze der Ergebnisse je Collector und Minute, wenn nach Ergebnissen begrenzt wird. Wirkt nach spätestens 30 Sekunden. | Um einen Collector gezielt zu drosseln, ohne die Begrenzung ganz umzustellen. |
collector_check_concurrency |
16 |
Wie viele Checks ein Collector (auch der Aktive Collector) gleichzeitig ausführt. Nicht gesetzt oder 0 = nach Kernen (unter 4 Kernen 16, sonst 16 je Kern, höchstens 256); höchstens 1024. Unabhängig davon laufen je Zielgerät und für lokale Scripts (api_script, Plugins) höchstens 16 Checks gleichzeitig. Wirkt beim nächsten Config-Abruf des Collectors (Aktiver Collector nach Sekunden, sonst nach bis zu einer Minute), sobald der Collector auf der Version mit dieser Änderung läuft. |
Wenn Zielgeräte unter gleichzeitigen Abfragen leiden oder der Collector-Rechner knapp an Arbeitsspeicher ist. |
anzeige_teilergebnisse_enabled |
false |
Startseite, Mandanten-Übersicht, Hosts-Seite, Karte, Standorte und Mandanten-Liste rechnen ihre Zahlen aus Zwischenergebnissen je Mandant, die sich alle Nutzer und offenen Tabs teilen. Jede Änderung (neues Ergebnis, ACK, Downtime, Check anlegen, Gerät deaktivieren …) macht das Zwischenergebnis ihres Mandanten sofort ungültig — die Seite zeigt nach einer eigenen Aktion wie bisher gleich den neuen Stand. Die Hosts-Seite und die Karte fragen beim automatischen Aktualisieren nur noch, ob sich etwas geändert hat, statt jedes Mal alle Geräte zu laden. Ausgeschaltet rechnet jede Anfrage wieder frisch und die Hosts-Seite lädt bei jedem Aktualisieren alle Geräte. Wirkt sofort, ohne Neustart. | Wenn eine Übersicht eine andere Zahl zeigt als die Fehlerübersicht oder das Host-Detail, wenn eine Änderung auf der Hosts-Seite erst nach dem Neuladen erscheint, oder wenn im Diagnose-Log status_teilergebnis_abweichung steht. |
anzeige_teilergebnisse_max_age_seconds |
Zahl, 1–30 (Standard 5) |
Höchstens so viele Sekunden gilt ein Zwischenergebnis, auch wenn sich nichts geändert hat — eine Sicherheitsgrenze, kein Takt. | Selten nötig; kleiner stellen, wenn bei status_teilergebnis_abweichung bis zur Klärung jede Zahl so frisch wie möglich sein soll (oder den Schalter oben ausschalten). |
Unabhängig davon gilt: Der Worker löscht aus der Ergebnis-Warteschlange nur noch, was er bereits verarbeitet hat. Nach einem Neustart oder Ausfall des Workers gehen keine wartenden Ergebnisse mehr verloren. Ein Eintrag, der über zehn Minuten immer wieder scheitert, landet sichtbar in den Dead-Letters statt die Warteschlange zu blockieren.
Hintergrund-Prüfungen bei vielen Checks¶
Seit Oktober 2026 suchen die Hintergrund-Prüfungen — überfällige Checks
(„No Data“), Wartungsfenster, Erreichbarkeit der Geräte, Agent offline,
nachgeholte Alarme und Eskalationen — nur noch die betroffenen Checks statt
bei jedem Durchlauf alle. Das Ergebnis ist dasselbe. Vesana prüft das selbst:
beim ersten Durchlauf nach einem Start und danach stündlich rechnet es
zusätzlich den bisherigen Weg. Weicht etwas ab, nimmt der Durchlauf das
bisherige Ergebnis und schreibt watcher_abgleich_abweichung ins
Diagnose-Log.
Jede Gruppe lässt sich einzeln zurückstellen (gleiche SQL-Form wie oben,
Wert false, wirkt im nächsten Durchlauf, also nach spätestens einer
Minute):
| Schlüssel | Betrifft |
|---|---|
watcher_index_stale_enabled |
Checks ohne neue Ergebnisse werden „No Data“ |
watcher_index_downtime_enabled |
Wartungsfenster beginnen und enden (der Ablauf befristeter ACKs ist davon unabhängig) |
watcher_index_reachability_enabled |
Erreichbarkeit der Geräte (Ping-Hinweise, Agent-Herzschlag) |
watcher_index_dead_agent_enabled |
Agents, die sich nicht mehr melden |
watcher_index_suppressed_replay_enabled |
Unterdrückte Alarme, die nachgeholt werden |
watcher_index_escalation_backfill_enabled |
Eskalationen für Alarme, die schon vor einem Neustart bestanden |
Wann zurückschalten: wenn im Diagnose-Log watcher_abgleich_abweichung
steht (der Eintrag nennt die Gruppe) oder ein Check sichtbar falsch steht —
er bleibt grün, obwohl keine Ergebnisse mehr kommen, oder hängt nach dem
Ende eines Wartungsfensters weiter auf „Downtime“. Dann den Schalter dieser
Gruppe auf false setzen und den Fall über den Feedback-Knopf melden.
Sofort prüfen, ohne etwas zu ändern:
Die Ausgabe nennt je Gruppe, ob bisheriger und neuer Weg übereinstimmen; bei einer Abweichung endet der Befehl mit Exit-Code 1.
Drei weitere Einträge im Diagnose-Log gehören dazu:
downtime_flag_reconciled (ein Check stand ohne laufendes Wartungsfenster
auf „Downtime“ und wurde zurückgesetzt), stale_eingaben_repaired (die
gespeicherte „No Data“-Schwelle eines Checks passte nicht mehr zu seinem
Intervall und wurde nachgetragen) und watcher_takt_ueber_sperre (ein
Durchlauf dauerte länger als vorgesehen — ein Zeichen, dass die Datenbank
an ihre Grenze kommt).
Beim Update auf diese Version legt die Datenbank vier kleine Indizes, zwei Spalten und eine kleine Tabelle an und füllt die Spalten einmal; bei sehr vielen Checks dauert das Update dadurch einige Sekunden länger.
Config nur bei Änderung¶
Agents, Collectors und der Aktive Collector holen ihre Konfiguration in festen Abständen beim Server ab (Agent alle 5 Minuten, Collector jede Minute, Aktiver Collector alle 5 Sekunden). Bisher baute der Server sie dabei jedes Mal vollständig neu. Seit Oktober 2026 antwortet er „unverändert", solange sich für den jeweiligen Agent oder Collector nichts geändert hat — Aufträge (Netzwerk-Scans, Netzsuchen, „Jetzt prüfen") kommen trotzdem in jeder Antwort mit. Eine Änderung an einem Check, Gerät, Profil, Script oder an den Freigaben erreicht den Agent bzw. Collector weiter beim nächsten Abruf; eine Änderung am eigenen Gerät erreicht einen Agent schon mit dem nächsten Lebenszeichen (spätestens 20 Sekunden).
Das gilt nur für Agents und Collectors, die die neue Version fahren — ältere bekommen weiter die vollständige Konfiguration wie bisher.
Zur Sicherheit holt jeder Agent und Collector einmal pro Stunde die
vollständige Konfiguration. Weicht sie von dem ab, was er hatte, obwohl der
Server „unverändert" gemeldet hatte, steht im Diagnose-Log ein Eintrag
config_drift (mit den betroffenen Checks bzw. Geräten), und die
Admin-Übersicht nennt den Grund. Die frische Konfiguration gilt ab da sofort.
| Schlüssel | Wert für „wie vorher" | Was es tut | Wann zurückschalten |
|---|---|---|---|
config_delta_enabled |
false |
Ausgeschaltet antwortet der Server wieder bei jedem Abruf mit der vollständigen Konfiguration. Wirkt nach spätestens 5 Sekunden, ohne Neustart. | Wenn im Diagnose-Log config_drift oder config_version_failed auftaucht, oder eine Änderung einen Agent oder Collector nicht erreicht. |
Agent bündelt unveränderte Ergebnisse¶
Bisher schickte ein Agent seine Ergebnisse alle 5 Sekunden, sobald eines anstand — bei vielen Agents der größte Teil aller Anfragen an den Server. Seit Oktober 2026 schickt er alles, was etwas bedeutet, weiterhin sofort (im gewohnten 5-Sekunden-Takt): jedes Ergebnis, das nicht OK ist, jeden Statuswechsel, das erste Ergebnis eines Checks, „Jetzt erheben", Checks mit kurzem Intervall und Checks, deren Status der Server selbst beurteilt. Nur unveränderte OK-Ergebnisse wartet er bis zu 30 Sekunden ab und schickt sie gesammelt. Alarme und Entwarnungen kommen dadurch nicht später an; ein unveränderter Messwert steht in Graphen und Listen höchstens 30 Sekunden später (im Verlauf zu seiner Messzeit).
Logs schickt ein Agent in diesem Modus alle 30 Sekunden statt alle 5 Sekunden. Öffnest du die Live-Ansicht der Logs eines Geräts, schickt sein Agent wieder im 5-Sekunden-Takt, solange die Ansicht offen ist — die ersten Zeilen kommen nach dem Öffnen nach spätestens 30 Sekunden, danach wie gewohnt.
Das gilt nur für Agents, die die neue Version fahren; ältere schicken weiter
wie bisher. Kommt ein Statuswechsel doch einmal gesammelt (später als
10 Sekunden nach der Messung) an, steht im Diagnose-Log ein Eintrag
result_change_late. Ein Einzelfall direkt nach vesana-agent test am
Gerät ist erklärbar (der Testlauf schickt an der laufenden Instanz vorbei).
| Schlüssel | Wert für „wie vorher" | Was es tut | Wann zurückschalten |
|---|---|---|---|
result_batching_window_s |
0 |
Wie lange ein unverändertes OK-Ergebnis höchstens wartet (Standard 30, höchstens 60). 0 = jedes Ergebnis im 5-Sekunden-Takt wie bisher. Wirkt beim nächsten Config-Abruf des Agents (spätestens nach 5 Minuten; sofort mit „Jetzt erheben"), ohne Neustart. |
Wenn im Diagnose-Log result_change_late wiederholt auftaucht oder Werte spürbar verzögert erscheinen. |
agent_log_flush_s |
0 |
Takt, in dem Agents Logs schicken (Standard 30 Sekunden, mindestens 5). 0 = Takt der Log-Konfiguration wie bisher (5 Sekunden). Wirkt beim nächsten Config-Abruf des Agents. |
Wenn Logs ohne Live-Ansicht zu spät erscheinen oder die Live-Ansicht nicht schnell genug wird. |
| ### Lebenszeichen von Agents und Collectors |
Agents melden sich alle 20 Sekunden beim Server, Collectors alle 30 Sekunden („Herzschlag"). Bisher schrieb jeder Herzschlag mehrere Zeilen in die Datenbank. Seit Oktober 2026 hält der Server das Lebenszeichen im schnellen Zwischenspeicher (Redis) und schreibt es alle 15 Sekunden gesammelt in die Datenbank. Für dich ändert sich nichts: „zuletzt gesehen", Offline-Meldungen, Host-down-Alarme und die Verfügbarkeits-Balken zeigen dasselbe wie vorher. Neu ist nur, dass ein noch andauernder Ausfall eines Agents oder Collectors im Verfügbarkeits-Balken schon nach gut fünf Minuten erscheint, nicht erst bis zu einer Stunde später.
Ist Redis nicht erreichbar oder wurde es geleert (etwa nach einem Neustart
ohne gespeicherte Daten), schreibt der Server die Lebenszeichen vorübergehend
wieder direkt in die Datenbank — kein Agent und kein Collector gilt deshalb
als offline. Im Diagnose-Log steht dann edge_liveness_redis_unavailable bzw.
edge_liveness_restored.
Stündlich rechnet der Server die Ausfälle zusätzlich auf dem bisherigen Weg
nach und vergleicht beide Ergebnisse. Weicht etwas ab, steht im Diagnose-Log
edge_outages_schatten_abweichung, und die Admin-Übersicht nennt den Grund.
Steht der Abgleich mit der Datenbank länger als zwei Minuten, meldet sie
edge_liveness_mirror_stale (scheitert ein Abgleich, edge_liveness_mirror_failed)
— die Herzschläge werden dann bis auf Weiteres
wieder einzeln geschrieben, es geht nichts verloren.
Collectors ab dieser Version halten sich beim Herzschlag an den Takt, den der Server vorgibt (heute 30 Sekunden); ältere bleiben bei 30 Sekunden.
| Schlüssel | Wert für „wie vorher" | Was es tut | Wann zurückschalten |
|---|---|---|---|
edge_liveness_redis |
false |
Ausgeschaltet schreibt jeder Herzschlag wieder direkt in die Datenbank, und Ausfälle werden wieder stündlich ermittelt. Wirkt nach spätestens 10 Sekunden, ohne Neustart; Aus- und Wiedereinschalten erzeugt keine Schein-Ausfälle. | Wenn im Diagnose-Log edge_outages_schatten_abweichung oder edge_liveness_mirror_stale auftaucht, wenn Agents oder Collectors fälschlich als offline gelten, oder wenn Redis dauerhaft knapp an Speicher ist. |
Mehrere Aktive Collectors¶
Reichen die Kerne eines Aktiven Collectors nicht mehr, teilen sich mehrere die aktiven Checks — jeder Check gehört genau einem, fällt einer aus, übernehmen die anderen nach 2 Minuten. Wie man einen hinzufügt und was der primäre zusätzlich macht: Aktiver Collector.
| Schlüssel | Wert für „wie vorher" | Was es tut | Wann zurückschalten |
|---|---|---|---|
active_collector_sharing_enabled |
false |
Aus: nur der primäre Aktive Collector prüft, weitere bekommen keine Checks. Wirkt nach wenigen Sekunden. | Wenn Checks auf einer anderen Maschine nicht laufen oder im Diagnose-Log ac_result_not_responsible auftaucht. |
collector_native_ping_enabled |
false |
Ping-Checks aller Collectors laufen über einen ICMP-Socket statt über das Programm ping. Aus: wieder über das Programm. Wirkt beim nächsten Config-Abruf. |
Wenn Ping-Werte nach dem Update anders aussehen. |
Mehrere API-Prozesse und die Hintergrundarbeit¶
Die Web-API nutzt seit Oktober 2026 mehrere Prozesse, wenn die Maschine es
hergibt: einen je 4 Kerne und je 4 GB Arbeitsspeicher, höchstens 8. Unter 8
Kernen oder unter 8 GB bleibt es bei einem Prozess wie bisher. Die
Datenbank-Verbindungen der API (DB_POOL_SIZE + DB_MAX_OVERFLOW, zusammen
standardmäßig 30) bleiben insgesamt dieselben: die Prozesse teilen sie sich, der
Prozess mit der Hintergrundarbeit bekommt davon eine Reserve von 10.
Alles, was im Hintergrund läuft — Alarm-Hochstufung, Eskalation, Ausfall- Erkennung, Wartung, Berichte-Zeitpläne, Status-Seiten, Backups —, fährt trotzdem genau ein Prozess, der „Leiter". Die Prozesse vereinbaren das über Redis; fällt der Leiter aus, übernimmt ein anderer nach höchstens etwa 17 Sekunden, bei einem geordneten Neustart sofort. Das gilt auch mit der Compose-Datei einer älteren Version und im Split-Container-Modus (der Admin-Container fährt nie Hintergrundarbeit).
Ob die Hintergrundarbeit läuft, zeigt die Admin-Übersicht in der Kachel
Hintergrundarbeit: welcher Prozess Leiter ist, wie viele API-Prozesse
laufen und ob eine Aufgabe steht. Steht eine Aufgabe länger als ihr üblicher
Takt (etwa die Alarm-Hochstufung über zwei Minuten) oder führt gar kein
Prozess, nennt die Übersicht den Grund. Im Diagnose-Log (Kategorie Wartung)
stehen dann hintergrund_stillstand, hintergrund_ohne_leiter,
leiter_verloren oder hintergrund_aufgabe_abgestuerzt; eine abgestürzte
Aufgabe startet nach einer Minute von selbst neu.
Login-, 2FA- und Step-Up-Begrenzungen zählen für alle Prozesse gemeinsam in
Redis. Ist Redis nicht erreichbar, gelten dieselben Grenzen im Speicher jedes
Prozesses (Diagnose-Log rate_limit_speicher_ausgefallen) — der Schutz bleibt
bestehen.
| Schlüssel | Wert für „wie vorher" | Was es tut | Wann zurückschalten |
|---|---|---|---|
api_processes |
1 |
Anzahl der API-Prozesse. Nicht gesetzt oder auto = nach Kernen und Arbeitsspeicher wie oben. 1 heißt: genau ein Prozess ohne Leiter-Wahl, die Hintergrundarbeit startet sofort wie vor dieser Version. Eine Zahl ab 2 erzwingt so viele Prozesse. Wirkt beim nächsten Start des API-Containers (docker compose restart api). Mit der Compose-Datei ab dieser Version geht dasselbe über API_WORKERS=1 in der .env und docker compose up -d (eine ältere Compose-Datei reicht die Variable nicht in den Container). |
Wenn die Admin-Übersicht hintergrund_ohne_leiter oder wiederholt leiter_verloren meldet, wenn der Server knapp an Arbeitsspeicher ist, oder wenn die Datenbank „too many clients" meldet. |
Anschluss¶
- Ressourcen — Speicher, RAM, Leistung — die eigentlichen Stellschrauben
- Self-Hosting-Übersicht — vollständige
.env-Referenz