Настройка Elasticsearch
Zabbix может хранить данные истории в Elasticsearch в качестве альтернативы реляционной базе данных.
Поддержка Elasticsearch в настоящее время является экспериментальной.
В этом руководстве описана настройка поддерживаемых версий Elasticsearch. Если вы используете другую версию, некоторые функции могут работать не так, как ожидается.
Elasticsearch может хранить следующие типы значений:
| Тип значения элемента данных | Таблица базы данных | Тип Elasticsearch |
|---|---|---|
| Numeric (unsigned) | history_uint | uint |
| Numeric (float) | history | dbl |
| Character | history_str | str |
| Log | history_log | log |
| Text | history_text | text |
| Binary | history_bin | не поддерживается Zabbix |
| JSON | history_json | json |
Elasticsearch не принимает массивы JSON. Значение JSON должно быть либо одним объектом, либо набором объектов.
Важные примечания
- Elasticsearch требует libcurl. Подробности см. в разделе требования.
- housekeeper не удаляет данные из Elasticsearch. Чтобы управлять сроком хранения данных, см. Index Lifecycle Management.
- Zabbix не вычисляет и не хранит тренды в Elasticsearch. Рассмотрите возможность увеличения периода хранения истории, чтобы сохранить более старые данные.
- При использовании Elasticsearch запросы диапазона, извлекающие значения из базы данных, ограничены временной меткой периода хранения данных.
- Elasticsearch не поддерживается для прокси Zabbix.
Если Elasticsearch еще не установлен, перед продолжением обратитесь к официальному руководству по установке.
Настройка Elasticsearch
Чтобы хранить исторические данные в Elasticsearch, необходимо:
- Создать индекс для каждого типа значений, который вы хотите хранить — именно здесь Elasticsearch хранит данные, аналогично таблице в реляционной базе данных.
- Определить mapping для каждого индекса — он задаёт структуру данных, аналогично схеме таблицы.
- Настроить ingest pipeline для обработки значений перед сохранением (требуется для значений JSON и индексов на основе даты).
Elasticsearch может хранить данные в одном индексе для каждого типа значений или в нескольких индексах на основе даты. Оба подхода описаны ниже.
Хранение истории в одном индексе
При таком подходе все исторические данные для заданного типа значений записываются в один индекс (например, uint или text).
Чтобы создать индекс для типа значений Numeric (unsigned), отправьте следующий запрос (с /uint в URL) вашему экземпляру Elasticsearch:
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 ответит подтверждением о том, что индекс был создан:
{"acknowledged": true, "shards_acknowledged": true, "index": "uint"}
Аналогичные запросы необходимо отправить для каждого дополнительного типа значений, который вы хотите хранить в Elasticsearch.
Сопоставления для всех типов значений доступны в репозитории исходного кода Zabbix.
Например, чтобы создать индекс для типа значений Text:
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
В отличие от других типов значений, значения JSON требуют дополнительной обработки перед сохранением.
Приведённый ниже индекс использует отдельные поля для разобранных и необработанных значений, поэтому для разбора каждого значения как JSON и сохранения его в правильном поле необходим ingest pipeline.
Чтобы создать индекс для типа значения JSON, отправьте следующий запрос (с /json в URL) вашему экземпляру Elasticsearch.
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 }
}
}
}'
Затем создайте 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 ответит подтверждением того, что ingest pipeline был создан:
{"acknowledged": true}
Хранение истории в индексах на основе даты
Вместо записи всех данных истории в один индекс (например, uint) Elasticsearch может распределять эти данные по нескольким индексам на основе даты (например, uint-2026-01-01, uint-2026-01-02).
Это упрощает управление объемом данных и сроками хранения с течением времени.
Чтобы включить это, необходимо:
- Создать шаблон индекса для каждого типа значения, который вы хотите хранить — это сообщает Elasticsearch, какое сопоставление применять при автоматическом создании нового индекса на основе даты.
- Создать конвейер ingest для каждого типа значения — он обрабатывает каждое входящее значение и направляет его в правильный индекс на основе даты.
Шаблоны индексов
Чтобы создать шаблон для индекса text, отправьте запрос со следующими данными:
- Используйте
_template/text_templateв URL вашего экземпляра Elasticsearch. - Используйте
"text*"в поле"index_patterns"для сопоставления имени индекса. - Используйте mapping для типа значения
text(см. mappings в репозитории исходного кода Zabbix).
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"
}
}
}
}'
Шаблон для индекса json:
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
Чтобы создать конвейер ingest для индекса text:
- Используйте
_ingest/pipeline/text-pipelineв URL вашего экземпляра Elasticsearch. - Добавьте процессор
date_index_name, чтобы направлять каждое значение в правильный индекс на основе даты в соответствии с его временной меткой.
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"
}
}
]
}'
Для индекса json конвейер также должен разбирать значение JSON перед его направлением в правильный индекс:
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"
}
}
]
}'
Настройка сервера Zabbix
В файле конфигурации сервера Zabbix (zabbix_server.conf) задайте параметр HistoryProvider.
Например, чтобы хранить значения типов Character, Log, Text и JSON в Elasticsearch (при этом значения Numeric оставлять в базе данных):
HistoryProvider=elasticsearch;value_types="str,log,text,json",url=http://localhost:9200
Если вы используете индексы на основе даты, добавьте date_index=1 к параметру:
HistoryProvider=elasticsearch;value_types="str,log,text,json",url=http://localhost:9200,date_index=1
После внесения изменений перезапустите сервер Zabbix:
systemctl restart zabbix-server
Настройка веб-интерфейса Zabbix
В файле конфигурации веб-интерфейса Zabbix (zabbix.conf.php) задайте переменную $HISTORY_PROVIDERS в соответствии с конфигурацией сервера:
$HISTORY_PROVIDERS[] = [
'types' => ['str','log','text','json'],
'provider' => 'elasticsearch',
'url' => 'http://localhost:9200'
];
Устранение неполадок
Следующие шаги могут помочь вам устранить проблемы с настройкой Elasticsearch:
-
Проверьте журналы Elasticsearch или сервера Zabbix на наличие ошибок.
-
Чтобы выявить медленные запросы, используйте параметр
log_slow_queriesв параметре конфигурации сервера ZabbixHistoryProvider. -
Убедитесь, что Elasticsearch разрешает доступ с сервера Zabbix и веб-интерфейса Zabbix.
-
Убедитесь, что
auto_create_indexвключен:
curl -X GET \
"http://localhost:9200/_cluster/settings?include_defaults=true&filter_path=**.auto_create_index"
# {"defaults": {"action": {"auto_create_index": "false"} } }
Чтобы включить его, отправьте следующий запрос:
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": {} }
- Проверьте, что mappings, шаблоны и ingest pipelines настроены правильно, отправив запросы
GETк соответствующим URL:
curl -X GET http://localhost:9200/json
curl -X GET http://localhost:9200/_template/json*
curl -X GET http://localhost:9200/_ingest/pipeline/json*
Вы можете сравнить полученные ответы с ожидаемыми ответами в документации API Elasticsearch.
-
Проверьте, не находятся ли какие-либо shards в состоянии сбоя; перезапуск Elasticsearch может решить эту проблему.
-
Выполните запрос к Elasticsearch, чтобы проверить, сохраняются ли данные, собранные Zabbix, например:
curl 'http://localhost:9200/json/_search' \
-H 'Content-Type: application/json' \
-d '{
"query": {
"term": {
"itemid": 42269
}
}
}'
- Если вам нужно сбросить настройку Elasticsearch и начать заново, вы можете удалить все индексы, шаблоны и ingest pipelines:
curl -X DELETE "http://localhost:9200/_all"
curl -X DELETE "http://localhost:9200/_template/*"
curl -X DELETE "http://localhost:9200/_ingest/pipeline/*"