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つのインデックス(例: uinttext)に書き込まれます。

数値(整数)の値のタイプのインデックスを作成するには、次のリクエスト(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-01uint-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)で、以下のパラメータを設定します。

例えば、CharacterLogTextJSONタイプの値を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をグローバル変数として宣言し、そのurltypesの値をサーバーの設定に合わせて設定します。

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

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

トラブルシューティング

Elasticsearchのセットアップに問題がある場合、以下の手順でトラブルシューティングを行うことができます。

  1. 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": {} }
  1. マッピング、テンプレート、インジェストパイプラインが正しいことを、それぞれの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ドキュメントに記載されている期待されるレスポンスを比較できます。

  1. シャードが失敗状態になっていないか確認します。Elasticsearchを再起動することで解決する場合があります。

  2. Elasticsearchの設定でZabbixサーバーおよびZabbix Webインターフェースからのアクセスが許可されていることを確認します。

  3. LogSlowQueries Zabbixサーバーの設定パラメータを使用して、遅いクエリを特定します。

  4. Elasticsearchのログにエラーがないか確認します。

  5. Elasticsearchのセットアップをリセットしてやり直す必要がある場合は、すべてのインデックス、テンプレート、インジェストパイプラインを削除できます。

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