-
Notifications
You must be signed in to change notification settings - Fork 21
Description
Performance-Analyse: Firewall Orchestrator
Problemstellung
Datenbankabfragen über die Hasura GraphQL API sind für Nicht-Admin-Benutzer signifikant langsamer als für Admin-Benutzer (tenant_id = 1). Die Ursache liegt primär in der Tenant-basierten Row-Level-Security, die über PL/pgSQL-Funktionen in fworch-api-funcs.sql realisiert wird.
Architektur-Überblick
Abfragen laufen über GraphQlApiConnection.SendQueryAsync(). Hasura wertet den x-hasura-role-Header aus und ruft pro Zeile PL/pgSQL-Filterfunktionen auf.
Identifizierte Bottlenecks
🔴 1. Tenant-Filterfunktionen — Per-Row Execution (KRITISCH)
Kernproblem: Für tenant_id = 1 (Admin) geben alle Funktionen sofort true zurück. Für jeden anderen Tenant werden pro Zeile komplexe mehrstufige JOINs ausgeführt.
Dokumentierte Komplexität (aus Quellcode):
| Funktion | Komplexität | Beschreibung |
|---|---|---|
rule_relevant_for_tenant() |
O(rf + rt) | 2× JOINs über 4 Tabellen pro Regel |
rule_from_relevant_for_tenant() |
O(rt) | Verschachtelte Schleifen + Sub-Queries |
rule_to_relevant_for_tenant() |
O(rf) | Symmetrisch zu rule_from |
get_rules_for_tenant() |
O(rf + rt) | UNION zweier komplexer Queries |
get_objects_for_tenant() |
O(r × rf × rt) | UNION mit 6-fach JOINs |
| Gesamt pro Regel | O(rf + rt + 2×rf×rt) |
Admin-Pfad (schnell) — sofortiger Return:
🔴 2. Fehlende Datenbankindizes (KRITISCH)
Die bestehenden Indizes decken die Tenant-Filter-Queries nicht ab:
| Tabelle | Vorhandener Index | Fehlender Index |
|---|---|---|
objgrp_flat |
❌ keiner | objgrp_flat_id, objgrp_flat_member_id |
tenant_network |
❌ keiner | tenant_id |
rule_from |
✅ rule_id |
obj_id |
rule_to |
✅ rule_id |
obj_id |
tenant_to_management |
❌ keiner | (management_id, tenant_id) |
tenant_to_device |
❌ keiner | (device_id, tenant_id) |
Empfohlene Indizes:
🟠 3. ip_ranges_overlap() in JOIN-Bedingungen (MITTEL)
Die Funktion wird in JOIN-Klauseln aufgerufen, was Index-Nutzung verhindert und Full Table Scans auf tenant_network erzwingt:
🟡 6. Newtonsoft.Json statt System.Text.Json (NIEDRIG)
Die Response-Deserialisierung nutzt JObject/JProperty (Newtonsoft.Json). Der schnellere System.Text.Json-Pfad ist auskommentiert (Zeilen 224-230) bzw. wirft NotImplementedException (Zeile 273).
Maßnahmen-Matrix
| Prio | Maßnahme | Aufwand | Impact | Quick-Win |
|---|---|---|---|---|
| 🔴 1 | Fehlende Indizes hinzufügen | Gering | Hoch | ✅ |
| 🔴 2 | Materialized View für Tenant-Sichtbarkeit | Hoch | Sehr hoch | ❌ |
| 🟠 3 | rulebase_fully_visible_to_tenant() optimieren |
Gering | Mittel | ✅ |
| 🟠 4 | ip_ranges_overlap() aus JOINs entfernen / vorberechnen |
Mittel | Hoch | ❌ |
| 🟡 5 | Doppelte Serialisierung in SendQueryAsync fixen |
Gering | Niedrig | ✅ |
| 🟡 6 | Migration auf System.Text.Json für Responses |
Mittel | Niedrig | ❌ |
Empfohlene Sofortmaßnahmen
- Indizes anlegen — größter Impact bei geringstem Aufwand
EXPLAIN ANALYZEauf den langsamsten Tenant-Queries ausführen, um fehlende Indizes zu verifizierenrulebase_fully_visible_to_tenant()auf einen kombinierten Query umstellen- Langfristig: Materialized View für die Tenant→Regel-Zuordnung evaluieren, um die O(rf×rt)-Komplexität auf O(1) zu reduzieren