Warum frisst mein Wazuh Indexer-Cluster mehr Speicher als die “Rohdaten-Rechnung” erwarten lässt?

Ausgangslage: 3 Indexer-Nodes à ~1,7 TB (= ~5,1 TB). Ingestion ~100 GB/Tag ⇒ ~3 TB Rohdaten für 30 Tage. Trotzdem sind ~5,1 TB belegt.

Das ist in OpenSearch/Wazuh nicht ungewöhnlich – weil (a) Replikation und Shards Daten vervielfachen und (b) der “Index auf Platte” deutlich mehr ist als der reine JSON-Logstrom.


1) Der häufigste Grund: Replikation vervielfacht den Speicher

In OpenSearch hat jedes Primary-Shard optional Replica-Shards. Replicas enthalten denselben Index-Inhalt (für HA/Query-Last), d. h. Speicherbedarf skaliert grob mit 1 + number_of_replicas.

OpenSearch erklärt das Replica-Prinzip inkl. Beispielrechnung (z. B. 4 Primaries + 3 Replicas ⇒ 12 Replica-Shards) direkt in den Index-Settings.

Faustformel:

  • 0 Replicas: ~3 TB + Overhead
  • 1 Replica (Default ist häufig 1): ~6 TB + Overhead
  • 2 Replicas: ~9 TB + Overhead

Wenn ihr also (clusterweit oder per Index-Template) index.number_of_replicas: 1 habt, wäre “~5,1 TB voll” sogar eher unter der groben Erwartung (je nach Overhead & Kompression).

Quick-Check (Dev Tools):

  • GET /_cat/indices?v&s=store.size:desc
  • GET /wazuh-alerts-4.x-*/_settings?filter_path=**.number_of_replicas,**.number_of_shards

2) Index-Overhead: Index ≠ Rohdaten

Auch ohne Replikation gilt: OpenSearch speichert nicht nur _source, sondern baut u. a.:

  • Inverted Indices (Suchstrukturen),
  • Doc values,
  • Segment-Files,
  • Metadaten.

Zusätzlich können Merge-Prozesse temporär extra Platz benötigen. Daher ist es normal, dass “Rohdaten” und “store.size” nicht 1:1 korrelieren.


3) System- und Nebenindizes (nicht nur wazuh-alerts-*)

Wazuh legt neben den Alerts oft weitere Indizes an (Monitoring, States/Inventory, Dashboards/Kibana/Observability, Security-Plugin etc.). Die sind einzeln vielleicht klein, summieren sich aber – vor allem wenn ihr mehrere Feature-Sets aktiv habt.

Quick-Check:

  • GET /_cat/indices/.kibana*,.opendistro_security,.opensearch*,wazuh-*/?v

4) Retention/ILM/ISM: werden alte Indizes wirklich gelöscht?

Wenn Indizes nicht wie geplant entfernt werden (Policy greift nicht, Pattern passt nicht, manuelles Roll-over/Deletion fehlt), wächst der Footprint stetig.

Wazuh beschreibt das Index Lifecycle/State Management und die Hot-Warm-Architektur in der Doku.

Quick-Check:

  • GET /_plugins/_ism/policies
  • GET /_plugins/_ism/explain/wazuh-alerts-4.x-*

5) Default-Kompression vs. best_compression: was ist Standard, was bringt’s?

Default

OpenSearch nutzt standardmäßig den default-Codec, der LZ4 verwendet (schnell, CPU-sparend).

best_compression

Wenn ihr index.codec: best_compression setzt, wechselt OpenSearch auf zlib (kleinere Indizes, aber CPU-teurer).

Impact in der Praxis:

  • ✅ Weniger Plattenverbrauch (je nach Daten/Mapping teils spürbar)
  • ❌ Höhere CPU-Last beim Indexieren (und teils beim Lesen), potenziell mehr Latenz unter Last
  • ⚠️ Wichtig: index.codec ist ein (static) Index-Setting – idealerweise beim Erstellen neuer Indizes setzen; Änderungen erfordern i. d. R. einen Reindex/Neuerstellung, wenn ihr es auf Altbestände anwenden wollt.

Empfohlene nächsten Schritte (kompakt)

  1. Replikationsfaktor prüfen (index.number_of_replicas) und gegen euer HA-Ziel abwägen.
  2. Top-Indizes nach Größe ausgeben (_cat/indices sortiert nach store.size).
  3. ISM/Retention verifizieren, ob wirklich gelöscht/gerollt wird.
  4. Wenn CPU-Budget da ist: Codec-Strategie für neue Indizes planen (best_compression) und Wirkung messen.