Elasticsearch-Einrichtung
Zabbix kann Verlaufsdaten in Elasticsearch als Alternative zu einer relationalen Datenbank speichern.
Diese Anleitung behandelt die Einrichtung der unterstützten Versionen von Elasticsearch.
Der Zabbix Server wird nicht gestartet, wenn Ihre Elasticsearch-Version älter als die mindestens unterstützte Version ist.
Wenn sie neuer als die maximal unterstützte Version ist, wird der Zabbix Server nur gestartet, wenn der Parameter AllowUnsupportedDBVersions auf 1 gesetzt ist.
Elasticsearch kann die folgenden Werttypen speichern:
| Datenpunkt-Werttyp | Datenbanktabelle | Elasticsearch-Typ |
|---|---|---|
| Numerisch (vorzeichenlos) | history_uint | uint |
| Numerisch (Gleitkomma) | history | dbl |
| Zeichen | history_str | str |
| Protokoll | 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. Weitere Informationen finden Sie unter Voraussetzungen.
- Der Housekeeper löscht keine Daten aus Elasticsearch. Informationen dazu, wie lange Daten aufbewahrt werden, finden Sie unter Index Lifecycle Management.
- Zabbix berechnet oder speichert keine Trends in Elasticsearch. Erwägen Sie, den Aufbewahrungszeitraum für Verlaufsdaten zu verlängern, um ältere Daten zu erhalten.
- Wenn Elasticsearch verwendet wird, sind Bereichsabfragen, die Werte aus der Datenbank abrufen, durch den Zeitstempel des Datenaufbewahrungszeitraums begrenzt.
- Elasticsearch wird für Zabbix-Proxys nicht unterstützt.
- Ab Elasticsearch 8.0 sind Sicherheitsfunktionen standardmäßig aktiviert: Elasticsearch erfordert eine Authentifizierung und verwendet HTTPS für seine HTTP-API. Dabei werden Zertifikate verwendet, die von einer automatisch generierten CA signiert wurden.
Die Beispiele auf dieser Seite verwenden
http://localhost:9200ohne Authentifizierung. Wenn die Sicherheit aktiviert ist, verwenden Sie einehttps://-URL und übergeben Sie das CA-Zertifikat sowie die Anmeldedaten in Ihren Anfragen (zum Beispielsudo curl --cacert /etc/elasticsearch/certs/http_ca.crt -u elastic https://localhost:9200; die Zertifikatsdatei der CA kann nur vonrootund der Gruppeelasticsearchgelesen werden). Informationen zum Verbinden des Zabbix-Servers und des Zabbix-Frontends mit einem solchen Cluster finden Sie unter Verbindung mit einem gesicherten Cluster herstellen.
Wenn Elasticsearch noch nicht installiert ist, lesen Sie vor dem Fortfahren den offiziellen Installationsleitfaden.
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.
Speichern des Verlaufs in einem einzelnen Index
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"}
Für jeden Werttyp, den Sie in Elasticsearch speichern möchten, müssen ähnliche Anfragen gesendet werden, also für jeden Typ, der in der Option value_types der Zabbix-Server-Konfiguration aufgeführt ist.
Mappings für alle Werttypen sind im Zabbix-Quell-Repository verfügbar.
Um beispielsweise 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-Wertetyp
Im Gegensatz zu anderen Wertetypen erfordern JSON-Werte vor der Speicherung eine zusätzliche Verarbeitung. Der Index für den JSON-Wertetyp speichert jeden Wert in einem von zwei Feldern:
value_parsed– JSON-Objekte, die als flattened-Feld gespeichert werden, damit sie nach Schlüssel und Wert durchsucht werden können;value_raw– alle anderen JSON-Werte (Arrays, Zeichenfolgen, Zahlen, boolesche Werte undnull), die als Zeichenfolge gespeichert werden.
Eine Ingest-Pipeline analysiert jeden Wert als JSON und speichert ihn im richtigen Feld. Werte, die kein gültiges JSON darstellen, werden nicht an Elasticsearch gesendet, da die Datenpunkte, die sie empfangen, nicht unterstützt werden.
Erstellen Sie zunächst 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
}
},
{
"script": {
"source": "if (ctx.value_parsed == null || !(ctx.value_parsed instanceof Map)) { ctx.value_raw = ctx.value; ctx.remove(\"value_parsed\"); }"
}
}
]
}'
Elasticsearch antwortet mit einer Bestätigung, dass die Ingest-Pipeline erstellt wurde:
{"acknowledged": true}
Erstellen Sie anschließend einen Index für den JSON-Wertetyp, indem Sie die folgende Anfrage (mit /json in der URL) an Ihre Elasticsearch-Instanz senden.
Die Einstellung default_pipeline bewirkt, dass Elasticsearch jeden in diesen Index geschriebenen Wert mit der JSON-Ingest-Pipeline verarbeitet.
Diese Einstellung ist erforderlich, da der Zabbix Server beim Speichern des Verlaufs in einem einzelnen Index keine Ingest-Pipeline angibt.
curl -X PUT \
http://localhost:9200/json \
-H 'content-type:application/json' \
-d '{
"settings": {
"index": {
"number_of_replicas": 1,
"number_of_shards": 5,
"default_pipeline": "json"
}
},
"mappings": {
"dynamic": false,
"properties": {
"itemid": { "type": "long" },
"clock": { "type": "date", "format": "epoch_second" },
"ns": { "type": "long" },
"value_parsed": { "type": "flattened", "ignore_above": 8191 },
"value_raw": { "type": "keyword", "ignore_above": 8191 }
}
}
}'
Elasticsearch kann keine keyword- und flattened-Werte mit einer Länge von mehr als 32766 Byte indizieren.
Mit "ignore_above": 8191 werden Zeichenfolgen mit mehr als 8191 Zeichen nicht indiziert (und können nicht durchsucht werden), aber weiterhin vollständig gespeichert und an Zabbix zurückgegeben.
Ohne diese Begrenzung weist Elasticsearch solche Werte zurück, und sie gehen verloren.
Speicherung von History in datumsbasierten Indizes
Anstatt alle History-Daten in einen einzelnen Index zu schreiben (z. B. uint), kann Elasticsearch diese Daten auf mehrere datumsbasierte Indizes verteilen (z. B. uint-2026-01-01, uint-2026-01-02).
Dadurch lassen sich Datenvolumen und Aufbewahrung im Laufe der Zeit einfacher verwalten.
Um dies zu aktivieren, müssen Sie:
- Für jeden Werttyp, den Sie speichern möchten, eine Indexvorlage erstellen - diese teilt Elasticsearch mit, welches Mapping angewendet werden soll, wenn automatisch ein neuer datumsbasierter Index erstellt wird.
- Für jeden Werttyp eine Ingest-Pipeline erstellen - sie verarbeitet jeden eingehenden Wert und leitet ihn an den richtigen datumsbasierten Index weiter.
Indexvorlagen
Um eine Vorlage für den text-Index zu erstellen, senden Sie eine Anfrage mit den folgenden Angaben:
- Verwenden Sie
_index_template/text_templatein der URL Ihrer Elasticsearch-Instanz. - Verwenden Sie
"text-*"im Feld"index_patterns", um die Namen datumsbasierter Indizes abzugleichen. - Geben Sie im Feld
"template"die Indexeinstellungen und ein Mapping für den Werttyptextan (siehe die Mappings im Zabbix-Quell-Repository).
curl -X PUT \
http://localhost:9200/_index_template/text_template \
-H 'content-type:application/json' \
-d '{
"index_patterns": [ "text-*" ],
"template": {
"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"
}
}
}
}
}'
Erstellen Sie für jeden Werttyp, den Sie speichern möchten, eine Vorlage. Ändern Sie dabei den Vorlagennamen, das Indexmuster und das Mapping entsprechend.
Beispiel für eine Vorlage für den json-Index (Details zu den Feldern value_parsed und value_raw finden Sie unter JSON-Werttyp):
curl -X PUT \
http://localhost:9200/_index_template/json_template \
-H 'content-type:application/json' \
-d '{
"index_patterns": [ "json-*" ],
"template": {
"settings": {
"number_of_replicas": 1
},
"mappings": {
"dynamic": false,
"properties": {
"itemid": { "type": "long" },
"clock": { "type": "date", "format": "epoch_second" },
"ns": { "type": "long" },
"value_parsed": { "type": "flattened", "ignore_above": 8191 },
"value_raw": { "type": "keyword", "ignore_above": 8191 }
}
}
}
}'
Verwenden Sie wie oben gezeigt zusammensetzbare Indexvorlagen (_index_template).
Veraltete Indexvorlagen (_template) werden nicht mehr empfohlen. Elasticsearch lehnt veraltete Vorlagen ab, deren Indexmuster sich mit integrierten Vorlagen überschneiden (beispielsweise eine veraltete Vorlage mit dem Muster log* für den log-Index).
Ingest-Pipelines
Um eine Ingest-Pipeline für den Index text zu erstellen:
- Verwenden Sie
_ingest/pipeline/text-pipelinein der URL Ihrer Elasticsearch-Instanz. - Fügen Sie einen
date_index_name-Prozessor ein, um jeden Wert anhand seines Zeitstempels an den richtigen 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"
}
}
]
}'
Erstellen Sie für jeden Werttyp, den Sie speichern möchten, eine Pipeline. Ändern Sie dabei den Namen der Pipeline, die Beschreibung und den Wert von "index_name_prefix" entsprechend.
Der Name der Pipeline muss aus dem Indexnamen und dem Suffix -pipeline bestehen (zum Beispiel uint-pipeline), da der Zabbix Server diesen Namen beim Senden von Werten an Elasticsearch verwendet.
Für den Index json muss die Pipeline außerdem den JSON-Wert analysieren, bevor er an den richtigen Index weitergeleitet wird:
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"
}
}
]
}'
Konfigurieren des Zabbix-Servers
Legen Sie in der Konfigurationsdatei des Zabbix-Servers (zabbix_server.conf) den Parameter HistoryProvider fest.
Um beispielsweise Werte der Typen Character, Log, Text und JSON in Elasticsearch zu speichern (während Werte des Typs Numeric in einer Datenbank verbleiben), verwenden Sie:
HistoryProvider=elasticsearch;value_types="str,log,text,json",url=http://localhost:9200
Wenn Sie indexbasierte Datumsangaben verwenden, fügen Sie dem Parameter date_index=1 hinzu:
HistoryProvider=elasticsearch;value_types="str,log,text,json",url=http://localhost:9200,date_index=1
Wenn die Sicherheitsfunktionen von Elasticsearch aktiviert sind, geben Sie eine https://-URL mit Anmeldedaten an (siehe Verbindung mit einem gesicherten Cluster herstellen).
Starten Sie den Zabbix-Server nach den Änderungen neu:
systemctl restart zabbix-server
Konfigurieren des Zabbix Frontends
Legen Sie in Ihrer Frontend-Konfigurationsdatei (zabbix.conf.php) die Variable $HISTORY_PROVIDERS entsprechend der Server-Konfiguration fest:
$HISTORY_PROVIDERS[] = [
'types' => ['str','log','text','json'],
'provider' => 'elasticsearch',
'url' => 'http://localhost:9200'
];
Wenn die Sicherheitsfunktionen von Elasticsearch aktiviert sind, geben Sie dieselbe https://-URL mit den Anmeldedaten wie in der Server-Konfiguration an (siehe Verbindung mit einem gesicherten Cluster herstellen).
Verbindung mit einem gesicherten Cluster herstellen
Wenn die Elasticsearch-Sicherheitsfunktionen aktiviert sind (seit Elasticsearch 8.0 standardmäßig), müssen der Zabbix Server und das Zabbix Frontend dem CA-Zertifikat der HTTP-Schicht von Elasticsearch vertrauen und sich mit einem Benutzernamen und Passwort authentifizieren.
- Erstellen Sie eine Rolle und einen Benutzer für Zabbix.
Die folgende Rolle ermöglicht es Zabbix, die Elasticsearch-Version abzurufen (das Cluster-Privileg
monitor), Indizes zu erstellen, Verlaufsdaten zu schreiben und zu lesen sowie Verlaufsdaten zu löschen, wenn der Verlauf eines Datenpunkts gelöscht wird:
sudo curl -X PUT \
--cacert /etc/elasticsearch/certs/http_ca.crt -u elastic \
https://localhost:9200/_security/role/zabbix_history \
-H 'content-type:application/json' \
-d '{
"cluster": [ "monitor" ],
"indices": [
{
"names": [ "uint", "uint-*", "dbl", "dbl-*", "str", "str-*", "log", "log-*", "text", "text-*", "json", "json-*" ],
"privileges": [ "create_index", "index", "read", "delete" ]
}
]
}'
sudo curl -X PUT \
--cacert /etc/elasticsearch/certs/http_ca.crt -u elastic \
https://localhost:9200/_security/user/zabbix \
-H 'content-type:application/json' \
-d '{
"password": "<password>",
"roles": [ "zabbix_history" ]
}'
- Fügen Sie das Elasticsearch-CA-Zertifikat zu den vertrauenswürdigen Zertifikaten des Betriebssystems auf den Hosts des Zabbix Servers und des Zabbix Frontends hinzu.
Wenn Zabbix auf einem anderen Host als Elasticsearch ausgeführt wird, kopieren Sie das CA-Zertifikat (
/etc/elasticsearch/certs/http_ca.crt) zunächst auf diesen Host. Beispielsweise unter Debian/Ubuntu:
sudo cp /etc/elasticsearch/certs/http_ca.crt /usr/local/share/ca-certificates/elasticsearch-http-ca.crt
sudo update-ca-certificates
Der Hostname in der URL muss mit dem HTTP-Zertifikat von Elasticsearch übereinstimmen.
Das automatisch generierte Zertifikat ist für localhost, den Hostnamen und die IP-Adressen des Elasticsearch-Hosts gültig.
- Geben Sie die Zugangsdaten sowohl in der Konfigurationsdatei des Zabbix Servers als auch in der Konfigurationsdatei des Frontends in der URL an.
Wenn das Passwort Sonderzeichen enthält, müssen diese mit Prozentkodierung versehen werden (z. B.
@als%40,:als%3Aund,als%2C).
HistoryProvider=elasticsearch;value_types="str,log,text,json",url=https://zabbix:<password>@localhost:9200
$HISTORY_PROVIDERS[] = [
'types' => ['str','log','text','json'],
'provider' => 'elasticsearch',
'url' => 'https://zabbix:<password>@localhost:9200'
];
- Starten Sie den Zabbix Server und PHP-FPM neu (oder den Webserver, wenn PHP als Webservermodul ausgeführt wird).
Fehlerbehebung
Die folgenden Schritte können Ihnen bei der Fehlerbehebung Ihrer Elasticsearch-Einrichtung helfen:
- Überprüfen Sie die Elasticsearch- oder Zabbix-Server-Protokolle auf Fehler. Beispielsweise weisen die folgenden Zabbix-Server-Protokollmeldungen auf Probleme bei der Verbindung mit einem gesicherten Cluster hin (siehe Verbindung mit einem gesicherten Cluster):
cannot query Elasticsearch: SSL certificate problem: self-signed certificate in certificate chain– das Elasticsearch-CA-Zertifikat wird nicht als vertrauenswürdig eingestuft;cannot query Elasticsearch, HTTP error message: The requested URL returned error: 401– die Anmeldedaten fehlen oder sind falsch;cannot query Elasticsearch, HTTP error message: The requested URL returned error: 403– der Benutzer verfügt nicht über die erforderlichen Berechtigungen.
Das Zabbix-Frontend zeigt ähnliche Fehler an (zum Beispiel Elasticsearch error: missing authentication credentials for REST request).
-
Um langsame Abfragen zu identifizieren, legen Sie den Zabbix-Server-Konfigurationsparameter
LogSlowQueriesfest. Wenn das Lesen des Verlaufs aus Elasticsearch länger als die angegebene Zeit dauert, protokolliert der Zabbix-Serverslow query: <N> sec, "<query>". Während der Zabbix-Server auf eine Antwort von Elasticsearch wartet, protokolliert er außerdem jedes Mal, wenn die angegebene Zeit verstrichen ist,waiting for Elasticsearch response <N>secoder alle 10 Sekunden, wennLogSlowQueriesauf 0 gesetzt ist. -
Überprüfen Sie, ob Elasticsearch den Zugriff vom Zabbix-Server und vom Zabbix-Frontend erlaubt.
-
Überprüfen Sie, ob
auto_create_indexaktiviert ist (standardmäßig ist es aktiviert):
curl -X GET \
"http://localhost:9200/_cluster/settings?include_defaults=true&filter_path=**.auto_create_index"
# {"persistent": {"action": {"auto_create_index": "false"} } }
Um die Einstellung 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": {} }
- Überprüfen Sie, ob 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/_index_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.
-
Überprüfen Sie, ob sich Shards in einem fehlerhaften Zustand befinden. Ein Neustart von Elasticsearch kann dieses Problem beheben. In einem Cluster mit einem einzelnen Knoten haben Indizes mit Replikaten (
"number_of_replicas": 1) den Status „yellow“, da Replikate nicht demselben Knoten wie primäre Shards zugewiesen werden können. Dies hat keine Auswirkungen auf Zabbix. Um dies zu vermeiden, setzen Sie"number_of_replicas"auf0. -
Fragen Sie Elasticsearch ab, um zu überprüfen, ob die von Zabbix erfassten Daten gespeichert werden, zum Beispiel:
curl "http://localhost:9200/json*/_search" \
-H 'Content-Type: application/json' \
-d '{
"query": {
"term": {
"itemid": 42269
}
}
}'
- Wenn Sie Ihre Elasticsearch-Einrichtung zurücksetzen und von vorn beginnen müssen, löschen Sie die für Zabbix erstellten Indizes, Indexvorlagen und Ingest-Pipelines (dadurch werden alle in Elasticsearch gespeicherten Verlaufsdaten gelöscht).
Standardmäßig erlaubt Elasticsearch das Löschen von Indizes mithilfe von Platzhalterausdrücken nicht. Um datumsbasierte Indizes zu löschen, ändern Sie daher vorübergehend die Einstellung
action.destructive_requires_name. Indexvorlagen und Ingest-Pipelines müssen einzeln gelöscht werden. Anfragen für nicht vorhandene Vorlagen oder Pipelines geben einen Fehler zurück, der ignoriert werden kann.
curl -X DELETE "http://localhost:9200/uint,dbl,str,log,text,json?ignore_unavailable=true"
curl -X PUT \
http://localhost:9200/_cluster/settings \
-H 'content-type:application/json' \
-d '{"persistent": {"action.destructive_requires_name": false}}'
curl -X DELETE "http://localhost:9200/uint-*,dbl-*,str-*,log-*,text-*,json-*"
curl -X PUT \
http://localhost:9200/_cluster/settings \
-H 'content-type:application/json' \
-d '{"persistent": {"action.destructive_requires_name": null}}'
for type in uint dbl str log text json; do
curl -X DELETE "http://localhost:9200/_index_template/${type}_template"
curl -X DELETE "http://localhost:9200/_ingest/pipeline/${type}-pipeline"
done
curl -X DELETE "http://localhost:9200/_ingest/pipeline/json"