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が必要です。詳細は要件を参照してください。
- ハウスキーパーはElasticsearchからデータを削除しません。
- すべての履歴データがElasticsearchに保存されている場合、トレンドは計算も保存もされません。 履歴保存期間の延長を検討してください。
- Elasticsearchを使用する場合、データベースから値を取得する範囲クエリは、データ保存期間のタイムスタンプで制限されます。
- ZabbixプロキシではElasticsearchはサポートされていません。代わりにSQLiteを使用してください。
まだElasticsearchがインストールされていない場合は、公式インストールガイドを参照してください。
Elasticsearchの設定
履歴データをElasticsearchに保存するには、以下の手順が必要です。
- 保存したい値の型ごとにインデックスを作成します。これはElasticsearchがデータを保存する場所であり、リレーショナルデータベースのテーブルに相当します。
- 各インデックスにマッピングを定義します。これはデータの構造を定義し、テーブルスキーマに相当します。
- 保存前に値を処理するためのインジェストパイプラインを設定します(JSON値や日付ベースのインデックスには必須です)。
Elasticsearchは、値の型ごとに単一のインデックスにデータを保存することも、複数の日付ベースのインデックスに分散して保存することもできます。 両方のアプローチについて以下で説明します。
1つのインデックスに履歴を保存する
この方法では、指定した値のタイプのすべての履歴データが1つのインデックス(例: uintやtext)に書き込まれます。
数値(整数)の値のタイプのインデックスを作成するには、次のリクエスト(URLの/uint付き)を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ソースリポジトリで利用できます。
たとえば、テキスト値のタイプのインデックスを作成するには:
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としてパースし、正しいフィールドに保存するためのインジェストパイプラインが必要です。
JSON値タイプのインデックスを作成するには、Elasticsearchインスタンスに次のリクエスト(URLに/jsonを指定)を送信します。
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 }
}
}
}'
次に、インジェストパイプラインを作成します:
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は、インジェストパイプラインが作成されたことを確認する応答を返します:
{"acknowledged": true}
日付ベースのインデックスへの履歴の保存
すべての履歴データを単一のインデックス(例:uint)に書き込む代わりに、Elasticsearchはこのデータを複数の日付ベースのインデックス(例:uint-2026-01-01、uint-2026-01-02)に分散して保存できます。
これにより、時間の経過とともにデータ量や保持期間の管理が容易になります。
これを有効にするには、以下の手順が必要です:
- 保存したい各値のタイプごとにインデックステンプレートを作成します。これにより、Elasticsearchは新しい日付ベースのインデックスを自動的に作成する際に適用するマッピングを認識します。
- 各値のタイプごとにインジェストパイプラインを作成します。これにより、受信した各値が処理され、正しい日付ベースのインデックスにルーティングされます。
- Zabbixサーバーの設定ファイルで
HistoryStorageDateIndexパラメータを設定します。これにより、複数の日付ベースのインデックスに値を保存できるようになります。
インデックステンプレート
textインデックスのテンプレートを作成するには、以下の詳細でリクエストを送信します。
- ElasticsearchインスタンスのURLに
_template/text_templateを使用します。 - インデックス名に一致させるため、
"index_patterns"フィールドに"text*"を使用します。 text値タイプのマッピングを使用します(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 }
}
}
}'
インジェストパイプライン
textインデックスのインジェストパイプラインを作成するには:
- ElasticsearchインスタンスのURLで
_ingest/pipeline/text-pipelineを使用します。 - 各値をそのタイムスタンプに基づいて正しい日付ベースのインデックスにルーティングするために、
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- ElasticsearchインスタンスのURLHistoryStorageTypes- 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 Webインターフェースの設定
Zabbix Webインターフェースの設定ファイル(zabbix.conf.php)で、$HISTORYをグローバル変数として宣言し、そのurlとtypesの値をサーバーの設定に合わせて設定します。
// Zabbix GUI configuration file.
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": {} }
- マッピング、テンプレート、インジェストパイプラインが正しいことを、それぞれのURLに
GETリクエストを送信して確認します。
curl -X GET http://localhost:9200/json
curl -X GET http://localhost:9200/_template/json*
curl -X GET http://localhost:9200/_ingest/pipeline/json*
受信したレスポンスとElasticsearch APIドキュメントに記載されている期待されるレスポンスを比較できます。
-
シャードが失敗状態になっていないか確認します。Elasticsearchを再起動することで解決する場合があります。
-
Elasticsearchの設定でZabbixサーバーおよびZabbix Webインターフェースからのアクセスが許可されていることを確認します。
-
LogSlowQueriesZabbixサーバーの設定パラメータを使用して、遅いクエリを特定します。 -
Elasticsearchのログにエラーがないか確認します。
-
Elasticsearchのセットアップをリセットしてやり直す必要がある場合は、すべてのインデックス、テンプレート、インジェストパイプラインを削除できます。
curl -X DELETE "http://localhost:9200/_all"
curl -X DELETE "http://localhost:9200/_template/*"
curl -X DELETE "http://localhost:9200/_ingest/pipeline/*"