8 Elasticsearch-Einrichtung

Zabbix kann Verlaufsdaten alternativ zu einer relationalen Datenbank in Elasticsearch speichern.

Die Unterstützung von Elasticsearch ist derzeit experimentell.

Diese Anleitung behandelt die Einrichtung für Elasticsearch 7.X. Wenn Sie eine andere Version verwenden, funktioniert ein Teil der Funktionalität möglicherweise nicht wie vorgesehen.

Die Einrichtung umfasst das Erstellen eines Elasticsearch-Speicherorts für jeden Werttyp, das Einrichten der Vorverarbeitung (falls erforderlich) und das Verbinden von Zabbix mit Ihrer Elasticsearch-Instanz.

Elasticsearch kann die folgenden Werttypen speichern:

Werttyp des Datenpunkts Datenbanktabelle Elasticsearch-Typ
Numerisch (unsigned) history_uint uint
Numerisch (float) history dbl
Zeichen history_str str
Log history_log log
Text history_text text
Binär history_bin von Zabbix nicht unterstützt
JSON history_json json

Wichtige Hinweise

  • Elasticsearch erfordert libcurl. Siehe Anforderungen für Details.
  • Der housekeeper löscht keine Daten aus Elasticsearch.
  • Wenn alle Verlaufsdaten in Elasticsearch gespeichert werden, werden Trends nicht berechnet oder in der Datenbank gespeichert. Ziehen Sie eine Verlängerung der Speicherdauer für Verlaufsdaten in Betracht.
  • Wenn Elasticsearch verwendet wird, sind Bereichsabfragen zum Abrufen von Werten aus der Datenbank durch den Zeitstempel des Datenspeicherzeitraums begrenzt.
  • Elasticsearch wird für Zabbix Proxy nicht unterstützt; bitte verwenden Sie stattdessen SQLite.

Falls Elasticsearch noch nicht installiert ist, lesen Sie vor dem Fortfahren die offizielle Installationsanleitung.

Elasticsearch konfigurieren

Um Verlaufsdaten in Elasticsearch zu speichern, müssen Sie:

  • Für jeden Werttyp, den Sie speichern möchten, einen Index erstellen – dort speichert Elasticsearch die Daten, ähnlich wie in einer Tabelle in einer relationalen Datenbank.
  • Für jeden Index ein Mapping definieren – dieses legt die Struktur der Daten fest, ähnlich wie ein Tabellenschema.
  • Eine Ingest-Pipeline einrichten, um Werte vor der Speicherung zu verarbeiten (erforderlich für JSON-Werte und datumsbasierte Indizes).

Elasticsearch kann Daten in einem einzelnen Index pro Werttyp oder über mehrere datumsbasierte Indizes hinweg speichern. Beide Ansätze werden unten beschrieben.

Verlauf in einem einzelnen Index speichern

Bei diesem Ansatz werden alle Verlaufsdaten für einen bestimmten Werttyp in einen einzelnen Index geschrieben (z. B. uint oder text).

Um einen Index für den Werttyp Numerisch (vorzeichenlos) zu erstellen, senden Sie die folgende Anfrage (mit /uint in der URL) an Ihre Elasticsearch-Instanz:

curl -X PUT \
 http://localhost:9200/uint \
 -H 'content-type:application/json' \
 -d '{
     "settings": {
      "index": {
         "number_of_replicas": 1,
         "number_of_shards": 5
      }
   },
   "mappings": {
      "properties": {
         "itemid": { "type": "long" },
         "clock": { "format": "epoch_second", "type": "date" },
         "value": { "type": "long" }
      }
   }
}'

Elasticsearch antwortet mit einer Bestätigung, dass der Index erstellt wurde:

{"acknowledged": true, "shards_acknowledged": true, "index": "uint"}

Ähnliche Anfragen müssen für jeden zusätzlichen Werttyp gesendet werden, den Sie in Elasticsearch speichern möchten.

Mappings für alle Werttypen sind im Zabbix source repository verfügbar.

Zum Beispiel, um einen Index für den Werttyp Text zu erstellen:

curl -X PUT \
 http://localhost:9200/text \
 -H 'content-type:application/json' \
 -d '{
   "settings": {
      "index": {
         "number_of_replicas": 1,
         "number_of_shards": 5
      }
   },
   "mappings": {
      "properties": {
         "itemid": { "type": "long" },
         "clock": { "format": "epoch_second", "type": "date" },
         "value": {
            "fields": {
               "analyzed": { "index": true, "type": "text", "analyzer": "standard" }
            },
            "index": false,
            "type": "text"
         }
      }
   }
}'
JSON-Werttyp

Im Gegensatz zu anderen Werttypen erfordern JSON-Werte vor der Speicherung eine zusätzliche Verarbeitung.

Der unten stehende Index verwendet separate Felder für geparste und rohe Werte, daher wird eine Ingest-Pipeline benötigt, um jeden Wert als JSON zu parsen und im richtigen Feld zu speichern.

Um einen Index für den Werttyp JSON zu erstellen, senden Sie die folgende Anfrage (mit /json in der URL) an Ihre Elasticsearch-Instanz.

curl -X PUT \
 http://localhost:9200/json \
 -H 'content-type:application/json' \
 -d '{
   "settings": {
      "number_of_shards": 5,
      "number_of_replicas": 1
   },
   "mappings": {
      "dynamic": false,
      "properties": {
         "itemid": { "type": "long" },
         "clock": { "type": "date", "format": "epoch_second" },
         "ns": { "type": "long" },
         "value_parsed": { "type": "flattened" },
         "value_raw": { "type": "keyword", "ignore_above": 1000000 }
    }
  }
}'

Erstellen Sie dann die Ingest-Pipeline:

curl -X PUT \
 http://localhost:9200/_ingest/pipeline/json \
 -H 'content-type:application/json' \
 -d '{
   "processors": [
      {
         "json": {
            "field": "value",
            "target_field": "value_parsed",
            "ignore_failure": true
         }
      },
      {
         "set": {
            "if": "ctx.value_parsed == null",
            "field": "value_raw",
            "value": "{{{ value }}}"
         }
      }
   ],
   "on_failure": [
      {
         "set": {
            "field": "value_raw",
            "value": "{{{ value }}}"
         }
      }
   ]
}'

Elasticsearch antwortet mit einer Bestätigung, dass die Ingest-Pipeline erstellt wurde:

{"acknowledged": true}

Verlauf in datumsbasierten Indizes speichern

Anstatt alle Verlaufsdaten in einen einzelnen Index (z. B. uint) zu schreiben, kann Elasticsearch diese Daten auf mehrere datumsbasierte Indizes verteilen (z. B. uint-2026-01-01, uint-2026-01-02). Dadurch wird es einfacher, das Datenvolumen und die Aufbewahrung im Zeitverlauf zu verwalten.

Um dies zu aktivieren, müssen Sie:

  • eine Index-Vorlage für jeden Werttyp erstellen, den Sie speichern möchten — diese teilt Elasticsearch mit, welches Mapping angewendet werden soll, wenn automatisch ein neuer datumsbasierter Index erstellt wird.
  • eine Ingest-Pipeline für jeden Werttyp erstellen — sie verarbeitet jeden eingehenden Wert und leitet ihn an den richtigen datumsbasierten Index weiter.
  • den Parameter HistoryStorageDateIndex in der Zabbix-Server-Konfigurationsdatei konfigurieren — dadurch wird das Speichern von Werten in mehreren datumsbasierten Indizes aktiviert.
Index-Vorlagen

Um eine Vorlage für den text-Index zu erstellen, senden Sie eine Anfrage mit den folgenden Details:

  • Verwenden Sie _template/text_template in der URL Ihrer Elasticsearch-Instanz.
  • Verwenden Sie "text*" im Feld "index_patterns", um den Index-Namen abzugleichen.
  • Verwenden Sie ein Mapping für den Werttyp text (siehe Mappings im Zabbix-Quellcode-Repository).
curl -X PUT \
 http://localhost:9200/_template/text_template \
 -H 'content-type:application/json' \
 -d '{
   "index_patterns": [ "text*" ],
   "settings": {
      "index": {
         "number_of_replicas": 1,
         "number_of_shards": 5
      }
   },
   "mappings": {
      "properties": {
         "itemid": { "type": "long" },
         "clock": { "format": "epoch_second", "type": "date" },
         "value": {
            "fields": {
               "analyzed": { "index": true, "type": "text", "analyzer": "standard" }
            },
            "index": false,
            "type": "text"
         }
      }
   }
}'

Vorlage für den json-Index:

curl -X PUT \
 http://localhost:9200/_template/json_template \
 -H 'content-type:application/json' \
 -d '{
   "index_patterns": [ "json*" ],
   "settings": {
      "number_of_shards": 5,
      "number_of_replicas": 1
   },
   "mappings": {
      "dynamic": false,
      "properties": {
         "itemid": { "type": "long" },
         "clock": { "type": "date", "format": "epoch_second" },
         "ns": { "type": "long" },
         "value_parsed": { "type": "flattened" },
         "value_raw": { "type": "keyword", "ignore_above": 1000000 }
      }
   }
}'
Ingest-Pipelines

Um eine Ingest-Pipeline für den Index text zu erstellen:

  • Verwenden Sie _ingest/pipeline/text-pipeline in der URL Ihrer Elasticsearch-Instanz.
  • Fügen Sie einen Prozessor date_index_name hinzu, um jeden Wert anhand seines Zeitstempels an den korrekten datumsbasierten Index weiterzuleiten.
curl -X PUT \
 http://localhost:9200/_ingest/pipeline/text-pipeline \
 -H 'content-type:application/json' \
 -d '{
   "description": "daily text index naming",
   "processors": [
      {
         "date_index_name": {
            "field": "clock",
            "date_formats": ["UNIX"],
            "index_name_prefix": "text-",
            "date_rounding": "d"
         }
      }
   ]
}'

Für den Index json muss die Pipeline den JSON-Wert vor der Weiterleitung an den korrekten Index außerdem parsen:

curl -X PUT \
 http://localhost:9200/_ingest/pipeline/json-pipeline \
 -H 'content-type:application/json' \
 -d '{
   "description": "daily json index naming"
   "processors": [
      {
         "json": {
            "field": "value",
            "target_field": "value_parsed",
            "ignore_failure": true
         }
      },
      {
         "script": {
            "source": "if (ctx.value_parsed == null || !(ctx.value_parsed instanceof Map)) { ctx.value_raw = ctx.value; ctx.remove(\"value_parsed\"); }"
         }
      },
      {
         "date_index_name": {
            "field": "clock",
            "date_formats": [ "UNIX" ],
            "index_name_prefix": "json-",
            "date_rounding": "d"
         }
      }
   ]
}'

Konfiguration des Zabbix Server

Legen Sie in Ihrer Zabbix-Server-Konfigurationsdatei (zabbix_server.conf) die folgenden Parameter fest:

Zum Beispiel, um Werte der Typen Character, Log, Text und JSON in Elasticsearch zu speichern (während Numeric-Werte in einer Datenbank verbleiben):

HistoryStorageURL=http://localhost:9200
HistoryStorageTypes=str,log,text,json

Wenn Sie datumsbasierte Indizes für alle in Elasticsearch gespeicherten Werte verwenden, setzen Sie zusätzlich den Parameter HistoryStorageDateIndex:

HistoryStorageDateIndex=1

Starten Sie nach den Änderungen den Zabbix Server neu:

systemctl restart zabbix-server

Konfigurieren des Zabbix Frontend

Deklarieren Sie in Ihrer Zabbix-Frontend-Konfigurationsdatei (zabbix.conf.php) $HISTORY als globale Variable und setzen Sie die Werte url und types so, dass sie mit der Server-Konfiguration übereinstimmen:

// Zabbix GUI configuration file.
global $DB, $HISTORY;

$HISTORY['url']   = 'http://localhost:9200';
$HISTORY['types'] = ['str', 'log', 'text', 'json'];

Fehlerbehebung

Die folgenden Schritte können Ihnen bei der Fehlerbehebung von Problemen mit Ihrer Elasticsearch-Einrichtung helfen:

  1. Vergewissern Sie sich, dass auto_create_index aktiviert ist:
curl -X GET \
 "http://localhost:9200/_cluster/settings?include_defaults=true&filter_path=**.auto_create_index"

# {"defaults": {"action": {"auto_create_index": "false"} } }

Um dies zu aktivieren, senden Sie die folgende Anfrage:

curl -X PUT \
 http://localhost:9200/_cluster/settings \
 -H 'content-type:application/json' \
 -d '{
   "persistent": {
      "action.auto_create_index": "true"
   }
}'

# {"acknowledged": true, "persistent": {"action": {"auto_create_index": "true"} }, "transient": {} }
  1. Vergewissern Sie sich, dass Mappings, Vorlagen und Ingest-Pipelines korrekt sind, indem Sie GET-Anfragen an die jeweiligen URLs senden:
curl -X GET http://localhost:9200/json
curl -X GET http://localhost:9200/_template/json*
curl -X GET http://localhost:9200/_ingest/pipeline/json*

Sie können die empfangenen Antworten mit den erwarteten Antworten in der Elasticsearch-API-Dokumentation vergleichen.

  1. Prüfen Sie, ob sich Shards in einem Fehlerzustand befinden; ein Neustart von Elasticsearch kann dies möglicherweise beheben.

  2. Vergewissern Sie sich, dass Ihre Elasticsearch-Konfiguration den Zugriff vom Zabbix Server und Zabbix Frontend erlaubt.

  3. Verwenden Sie den Zabbix-Server-Konfigurationsparameter LogSlowQueries, um langsame Abfragen zu identifizieren.

  4. Prüfen Sie die Elasticsearch-Protokolle auf Fehler.

  5. Wenn Sie Ihre Elasticsearch-Einrichtung zurücksetzen und von vorn beginnen müssen, können Sie alle Indizes, Vorlagen und Ingest-Pipelines löschen:

curl -X DELETE "http://localhost:9200/_all"
curl -X DELETE "http://localhost:9200/_template/*"
curl -X DELETE "http://localhost:9200/_ingest/pipeline/*"