8 Настройка Elasticsearch
Zabbix может хранить исторические данные в Elasticsearch в качестве альтернативы реляционной базе данных.
Поддержка Elasticsearch в настоящее время является экспериментальной.
Это руководство описывает настройку для Elasticsearch 7.X. Если вы используете другую версию, часть функциональности может работать не так, как ожидается.
Настройка включает создание хранилища Elasticsearch для каждого типа значений, настройку предобработки (при необходимости) и подключение Zabbix к вашему экземпляру Elasticsearch.
Elasticsearch может хранить следующие типы значений:
| Тип значения элемента данных | Таблица базы данных | Тип Elasticsearch |
|---|---|---|
| Числовой (без знака) | history_uint | uint |
| Числовой (с плавающей точкой) | history | dbl |
| Символьный | history_str | str |
| Журнал | history_log | log |
| Текст | history_text | text |
| Двоичный | history_bin | не поддерживается Zabbix |
| JSON | history_json | json |
Важные примечания
- Elasticsearch требует libcurl. Подробности см. в требованиях.
- housekeeper не удаляет данные из Elasticsearch.
- Если все исторические данные хранятся в Elasticsearch, тренды не вычисляются и не сохраняются в базе данных. Рассмотрите возможность увеличения периода хранения истории.
- При использовании Elasticsearch запросы диапазона, извлекающие значения из базы данных, ограничиваются временной меткой периода хранения данных.
- Elasticsearch не поддерживается для Zabbix прокси; вместо него используйте SQLite.
Если 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 для каждого типа значения — он обрабатывает каждое поступающее значение и направляет его в правильный индекс на основе даты.
- Настроить параметр
HistoryStorageDateIndexв файле конфигурации сервера Zabbix — это включает хранение значений в нескольких индексах на основе даты.
Шаблоны индексов
Чтобы создать шаблон для индекса 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) задайте следующие параметры:
HistoryStorageURL- URL вашего экземпляра Elasticsearch.HistoryStorageTypes- список типов значений, разделенных запятыми, которые нужно хранить в Elasticsearch.
Например, чтобы хранить значения типов Character, Log, Text и JSON в Elasticsearch (при этом значения Numeric будут храниться в базе данных):
HistoryStorageURL=http://localhost:9200
HistoryStorageTypes=str,log,text,json
Если вы используете индексы на основе даты для всех значений, хранящихся в Elasticsearch, также задайте параметр HistoryStorageDateIndex:
HistoryStorageDateIndex=1
После внесения изменений перезапустите сервер Zabbix:
systemctl restart zabbix-server
Настройка веб-интерфейса Zabbix
В файле конфигурации веб-интерфейса Zabbix (zabbix.conf.php) объявите $HISTORY как глобальную переменную и задайте значения url и types в соответствии с конфигурацией сервера:
// Файл конфигурации графического интерфейса Zabbix.
global $DB, $HISTORY;
$HISTORY['url'] = 'http://localhost:9200';
$HISTORY['types'] = ['str', 'log', 'text', 'json'];
Устранение неполадок
Следующие шаги могут помочь вам устранить проблемы с настройкой Elasticsearch:
- Убедитесь, что
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": {} }
- Убедитесь, что сопоставления, шаблоны и конвейеры ingest настроены правильно, отправив запросы
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.
-
Проверьте, нет ли шардов в состоянии сбоя; перезапуск Elasticsearch может решить эту проблему.
-
Убедитесь, что конфигурация Elasticsearch позволяет доступ с сервера Zabbix и веб-интерфейса Zabbix.
-
Используйте параметр конфигурации сервера Zabbix
LogSlowQueries, чтобы выявить медленные запросы. -
Проверьте журналы Elasticsearch на наличие ошибок.
-
Если вам нужно сбросить настройку Elasticsearch и начать заново, вы можете удалить все индексы, шаблоны и конвейеры ingest:
curl -X DELETE "http://localhost:9200/_all"
curl -X DELETE "http://localhost:9200/_template/*"
curl -X DELETE "http://localhost:9200/_ingest/pipeline/*"