ブログ

Elasticsearch のインデックステンプレート: 構成可能なテンプレートの使い方

Elasticsearchでコンポーザブルおよびコンポーネントインデックステンプレートを作成する方法を探り、マッピングの一貫性を確保し、インデックス設定を自動化する方法を学びましょう。

Elasticsearch インデックスは、マッピング、設定、エイリアスを通じて構成できます。

  • マッピング定義はデータ スキーマを指定します。

  • 設定では、シャードのサイズと更新レートを設定します。

  • エイリアスは、インデックスに別の名前を付けるために使用されます。

初めてドキュメントのインデックスを作成するとき、または Create Index API を使用して空のインデックスを作成するときは、データ スキーマとエイリアスのないデフォルト設定でインデックスが作成されます。これらのデフォルトは開発環境やテスト環境では適切に機能しますが、実稼働環境の場合はインデックスをカスタマイズする必要がある場合があります。

運用環境でデフォルトのマッピングと設定を使用すると、インデックス作成と検索のパフォーマンスが低下する可能性があります。インデックスを手動でインスタンス化するのは面倒で時間のかかるプロセスです。複雑なマッピング スキーマやカスタマイズされた設定およびエイリアスがある場合、このようなインデックスをすべての環境で再作成することは特に非現実的です。

幸いなことに、Elasticsearch には、インデックステンプレートの形式でインデックスを作成するときに、事前定義された構成を自動的に適用するツールが用意されています。

インデックステンプレート

インデックス テンプレートを使用すると、ユーザー定義の構成でインデックスを作成できます。インデックスは、インスタンス化中に、これらのテンプレートから構成 (シャードとレプリカの数の設定、フィールド マッピングなど) を取得できます。テンプレートは、名前パターンといくつかの構成で定義されます。インデックスの名前がテンプレートの命名パターンと一致する場合、テンプレートで定義された構成で新しいインデックスが作成されます。

Elasticsearch はバージョン 7.8 で、コンポーザブル テンプレートを使用してテンプレート機能をアップグレードしました。この新しいバージョンでは、この記事で示されているように、より再利用可能なインデックス テンプレートが提供されます。

インデックステンプレートの種類

インデックス テンプレートは、次の 2 つのカテゴリに分類できます。

  • インデックス テンプレート (または構成可能なインデックス テンプレート) : 構成可能なインデックス テンプレートは、単独で存在することも、0 個以上のコンポーネント テンプレートで構成することもできます (2 番目のカテゴリを参照)。

  • コンポーネント テンプレート:コンポーネント テンプレートは、必要な構成を定義する、それ自体が再利用可能なテンプレートです。通常、コンポーネント テンプレートはインデックス テンプレートに関連付けられることが想定されます。各コンポーネント テンプレートには、1 つまたは複数のインデックス テンプレートを添付できます。

下の画像でわかるように、インデックス テンプレート A と B はコンポーネント テンプレート (この場合はテンプレート 3 の 1 つだけ) を共有しています。インデックス テンプレートは、0 個以上のコンポーネント テンプレートで構成でき、各コンポーネント テンプレートは、0 個以上のインデックス テンプレートに関連付けることができます。どちらのタイプのテンプレートも単独で存在できますが、コンポーネント テンプレートはインデックス テンプレートに添付されない限り役に立ちません。

Elasticsearchのインデックステンプレートとそのコンポーネント。

基本的な考え方は、組織がさまざまなニーズに合わせて使用できるコンポーネント テンプレートのカタログを開発し (たとえば、個々の環境に合わせてさまざまなコンポーネント テンプレートを指定する)、それらを構成可能なインデックス テンプレートを介してさまざまなインデックスに添付することです。

構成可能な(インデックス)テンプレートを作成する方法

Elasticsearch は、インデックス テンプレートを管理するための _index_template エンドポイントを提供します。ユーザーは、このテンプレートでインデックス名パターンとともに、必要なすべてのマッピング、設定、エイリアスを指定します。注文生成ロジックを担当するマイクロサービス アプリケーションcustomer-order-serviceのテンプレートを作成する例を見てみましょう。

ワイルドカード *orders を含むパターンで表される顧客注文のテンプレートを作成する必要があるとします。このテンプレートには、order_date フィールド、シャード、レプリカ番号などの特定のマッピングと設定が含まれている必要があります。

作成中にこのテンプレートと一致するインデックスはすべて、このテンプレートで定義された構成を継承します。たとえば、black_friday_orders インデックスには order_date フィールドがあり、シャードは 5 に設定され、レプリカは 2 に設定されます。これに加えて、このテンプレートから作成されたすべてのインデックスも単一のエイリアス名を継承します。*orders として定義されたインデックス パターンと、定義済みの日付形式 dd-MM-yyyy を持つ単一の oder_date フィールドで構成されるマッピング スキーマを使用して、この orders_template を作成しましょう。以下のコードは、このインデックス テンプレートを作成する方法を示しています。

PUT _index_template/orders_template
{
  "index_patterns": ["*orders"],
  "priority": 300,
  "template": {
    "mappings": {
      "properties": {
        "order_date": {
          "type": "date",
          "format":"dd-MM-yyyy"
        }
      }
    },
    "settings":{
      "number_of_shards":5,
      "number_of_replicas":2
    },
    "aliases":{
      "all_orders":{}
    }
  }
}

Kibana の DevTools でこのクエリを実行すると、事前定義されたマッピング、設定、エイリアスとともに、インデックス パターン *orders を使用してテンプレートが作成されます。index_patterns は一致パターンの配列です。このパターンに一致するインデックスはテンプレート構成を派生します。実行した内容を繰り返す永続テンプレートを取得するには、以下を実行します。

GET _index_template/orders_template

テンプレートに定義されたテンプレート属性を作成するときに定義される、正の数値の優先度もあります。すべてのテンプレートには優先度が定義されるため、異なるテンプレートからの競合する変更は、この値を使用して解決され、より高い優先度の値が優先されます。テンプレートの優先順位については、以下でさらに詳しく説明します。

テンプレートを使用してインデックスを作成する

これで、インデックスを作成するための設計図であるテンプレートができました。次のステップは、インデックスを作成することです。インデックスの名前が指定されたパターンと一致すると、テンプレート化された構成が自動的に適用されます。この点を証明するために、以下のコードに示すように、blackfriday_orders という名前の新しいインデックスを作成しましょう。

PUT blackfriday_orders

インデックスの名前(blackfriday_orders)はテンプレートで定義された命名パターンと一致します(つまり*orders) の場合、インデックスはテンプレートから派生したすべての構成を取得する必要があります。この新しく作成されたインデックスを取得し、次のコードを実行してこれが本当に当てはまるかどうかを確認しましょう。

GET blackfriday_orders

次のように返されます:

{
  "blackfriday_orders" : {
    "aliases" : {
      "all_orders" : { }
    },
    "mappings" : {
      "properties" : {
        "order_date" : {
          "type" : "date",
          "format" : "dd-MM-yyyy"
        }
      }
    },
    "settings" : {
      "index" : {
         ...
        "number_of_shards" : "5",
        "number_of_replicas" : "2"
      }
    }
  }
}

応答が示すように、blackfriday_orders の構成はテンプレートから継承されています。テンプレート構成を正常に継承するインデックスのさまざまな組み合わせを試すことができます。

PUT blackfriday_orders
PUT americaorders
PUT cancelled--orders
PUT undefined101orders

ただし、次のインデックスは名前がパターンと一致しないため、構成を継承しません。

PUT blackfriday_orders2
PUT open_orders_
PUT allorders_total

覚えておくべき重要な点の 1 つは、この場合、テンプレートから派生したすべてのインデックスが同じエイリアス (all_orders) を持つことです。このようなエイリアスを使用すると、複数のインデックスではなく、この単一のエイリアスに対してクエリを実行できるという利点があります。

GET blackfriday_orders,americaorders,undefined101orders/_search
GET all_orders/_search 
{
  "query": {
    "range": {
      "order_date": {
        "gte": "01-12-2021",
        "lte": "31-12-2021"
      }
    }
  }
}

*orders のテンプレートを作成する際、一致するインデックスはテンプレート構成を採用することが期待されます。通常、チームは、意識的か無意識的かを問わず、さまざまな理由でさらにいくつかのテンプレートを作成することがあります。つまり、インデックス名が 2 つの異なるテンプレート パターンと一致する場合があるということです。Elasticsearch は、これらのテンプレートからどの構成を適用する必要があるかを決定する必要があります。幸いなことに、このジレンマはテンプレートの優先順位を使用することで解決できます。

コンポーネントテンプレートの作成方法

この記事の前半でインデックス テンプレートについて学習しました。構成が組み込まれたテンプレートを作成することにはいくつかの欠点があります。その 1 つは、構成を他のテンプレートにエクスポートできないことです。たとえば顧客関連のテンプレート(*customers)に対して同様の構成を希望する場合は、テンプレート全体を再作成する必要がある場合があります。つまり、典型的な組織では数十個のコンポーネントが作成されることになります (環境によっては、さらに数個になることもあります)。

私たちは常に再利用性を重視しているため、Elasticsearch は再利用性を念頭に置いてテンプレートを再設計しました。コンポーネント テンプレートはまさにその要件を満たしています。DevOps の経験がある場合、環境ごとに事前設定された構成でインデックスを作成する必要がある可能性が高くなります。これらの各構成を手動で面倒に適用するのではなく、環境ごとにコンポーネント テンプレートを作成できます。

コンポーネント テンプレートは、より多くのインデックス テンプレートを作成するために使用できる再利用可能な構成ブロックです。コンポーネント テンプレートは、インデックス テンプレートと組み合わせない限り価値がないことに注意してください。これらは _component_template エンドポイントを介して公開されます。これらすべてがどのように組み合わさるかを見てみましょう。

インデックステンプレート内の設定

先ほどインデックス テンプレートで定義した設定を抽出し、そこからコンポーネント テンプレートを作成しましょう。settings_component_template には、プライマリ シャードごとに 2 つのレプリカを持つ 5 つのプライマリ シャードがあることが想定されています。最初のステップは、以下のコード リストに示すように、この構成でコンポーネント テンプレートを宣言して実行することです。

PUT _component_template/settings_component_template
{
  "template":{
    "settings":{
      "number_of_shards":5,
      "number_of_replicas":2
    }
  }
}

上記のコードが示すように、_component_template エンドポイントを使用してコンポーネント テンプレートを作成します。リクエストの本文には、テンプレート オブジェクト内のテンプレート情報が保持されます。これで、settings_component_template はインデックス テンプレートの他の場所でも使用できるようになりました。注目すべき違いの 1 つは、このテンプレートではインデックス パターンが定義されていないことです。これは、いくつかのプロパティを構成する単なるコード ブロックです。

マッピングテンプレート

同じように、もう一つテンプレートを作成しましょう。今回は、スタンドアロン インデックス テンプレートで以前に定義したマッピング スキーマを抽出しましょう。以下のコードはスクリプトを示しています。

PUT _component_template/mappings_component_template
{
  "template": {
    "mappings": {
      "properties": {
        "order_date": {
          "type": "date",
          "format":"dd-MM-yyyy"
        }
      }
    }
  }
}

エイリアステンプレート

同じフローで、エイリアス(2 つのエイリアス(all_orders と sales_orders))を持つコンポーネント テンプレートも作成できます。

PUT _component_template/aliases_component_template
{
  "template": {
    "aliases": {
      "all_orders": {},
      "sales_orders":{}
    }
  }
}

構成可能なインデックステンプレート

これで 3 つのコンポーネント テンプレートができたので、次のステップではそれらを使用します。これを実現するには、たとえば christmas_orders のインデックス テンプレートでこれを使用できるようにします。

PUT _index_template/composed_orders_template
{
  "index_patterns": [
    "*orders"
  ],
  "priority": 500,
  "composed_of": [
    "settings_component_template",
    "mappings_component_template",
    "aliases_component_template"
  ]
}

compose_of タグは、このテンプレートを構成するすべてのコンポーネント テンプレートのコレクションです。この場合は、設定、マッピング、エイリアスのコンポーネント テンプレートを選択します。また、このテンプレートが他のテンプレートよりも優先されるように、優先順位を上げています。テンプレートの準備が整うと、*orders パターンに一致するすべてのインデックスは、これら 3 つのコンポーネント テンプレートから構成を継承します。

そうは言っても、既存のテンプレート (settings_component_template) と新しく作成したエイリアス テンプレート (aliases_component_template – 以下を参照) のいずれか 1 つを使用して、新しいテンプレート (たとえば、顧客) を作成したい場合は、次のようにします。

PUT _component_template/aliases_component_template2
{
  "template": {
    "aliases": {
      "all_customers": {}
    }
  }
}

インデックス テンプレートは次のようになります。

PUT _index_template/composed_customers_template
{
  "index_patterns": [
    "*customers*"
  ],
  "priority": 200,
  "composed_of": [
    "settings_component_template",
    "aliases_component_template2"
  ]
}

settings_component_template が 2 つの異なるテンプレートで (再) 使用されていることに気付きましたか?それがコンポーネント テンプレートの力です。

インデックステンプレートの優先度

開発者が既存のストックを確認せずに複数のインデックス テンプレートを作成する可能性があります。これらのテンプレートそれぞれに優先順位を設定し、優先順位の高いテンプレートが使用されるようにすることが重要です。たとえば、次のコード スニペットでは、my_orders_template_1 が my_orders_template_2 をオーバーライドします。

PUT _index_template/my_orders_template_1
{
  "index_patterns": ["*orders"],
  "priority": 1000,
  "template": { ... }
}
PUT _index_template/my_orders_template2
{
  "index_patterns": ["*orders"],
  "priority": 300,
  "template": { ... }
}

作成中のインデックスに一致するテンプレートが複数ある場合、Elasticsearch は一致するすべてのテンプレートのすべての設定を適用しますが、優先度の高い設定は上書きします。

テンプレートの優先順位

最後に、テンプレートの優先順位について疑問に思われるかもしれません。コンポーネント テンプレートで定義された構成は、メイン インデックス テンプレート自体で定義された構成を上書きするのでしょうか。それとも逆でしょうか?まあ、いくつかルールがあります:

  • 明示的に構成を作成して作成したインデックスは、すべてに優先します。つまり、明示的に構成を作成してインデックスを作成した場合、テンプレートによってそのインデックスが上書きされることは想定しないでください。

  • レガシー テンプレート (バージョン 7.8 より前に作成されたテンプレート) は、コンポーザブル テンプレートよりも優先順位が低くなります。

まとめ

  • インデックスには、マッピング、設定、エイリアスが含まれます。マッピングはフィールド スキーマを定義し、設定はシャードやレプリカの数などのインデックス パラメータを設定し、エイリアスはインデックスに別名を与えます。

  • テンプレートを使用すると、事前定義された構成でインデックスを作成できます。特定のテンプレート内で定義されたインデックス パターンと一致する名前でインデックスに名前を付けると、そのインデックスはテンプレートに従って自動的に構成されます。

  • Elasticsearch はバージョン 7.8 で構成可能なインデックス テンプレートを導入しました。構成可能なインデックス テンプレートにより、テンプレートのモジュール化とバージョン管理が可能になります。

  • 構成可能なテンプレートは、0 個以上のコンポーネント テンプレートで構成されます。

  • インデックス テンプレートにも独自の構成を定義することができます。

  • コンポーネント テンプレートは、コンポーザブル インデックス テンプレートと同様に、事前定義された構成を持つ再利用可能なテンプレートです。

  • ただし、コンポーネント テンプレートはインデックス テンプレートの一部であることが想定されており、インデックス テンプレートに「構成」されていない場合は役に立ちません。

  • コンポーネント テンプレートにはインデックス パターンが定義されていません。これが、コンポーネント テンプレートがインデックス テンプレートの一部であると「想定」されるもう 1 つの理由です。

  • 各テンプレートには優先度(正の数字)があります。数値が大きいほど、そのテンプレートが適用される優先順位が高くなります。

よくあるご質問

Elasticsearchのインデックステンプレートとは何ですか?

これらは、新しいインデックスに事前定義された設定(マッピング、設定、およびエイリアス)を自動的に適用するブループリントです。インデックス名がテンプレートのパターン(例:*orders)と一致する場合、その設定を自動的に継承し、時間を節約して一貫性を確保します。

コンポーザブルテンプレートとコンポーネントテンプレートの違いは?

コンポーネントテンプレートは、小さな再利用可能な構成要素(特定の「マッピング」や「シャード設定」など)で、インデックスパターンは持っていません。コンポーザブルインデックステンプレートは、インデックスパターンを持ち、複数のコンポーネントテンプレートを「構成」またはグループ化した最終的なテンプレートです。

インデックスが複数のテンプレートと一致する場合、Elasticsearchはどのようにして競合を解決しますか?

優先システムを採用しています。各テンプレートには数値の優先度が割り当てられています。インデックスが複数のパターンと一致する場合、優先度の数値が最も高いテンプレートが優先され、その設定が他のテンプレートの設定を上書きします。

関連記事

Elasticsearchインデックスのフィールドを表示する

Kofi Bartlett

Kafka 経由で Elasticsearch にデータを取り込む方法

Andre Luiz

LogstashでのRubyスクリプト

Dai Sugimori

Elasticsearchインデックスのフィールドを表示する方法

JD Armada

LlamaIndex 経由で Elasticsearch にデータを取り込む方法

Andre Luiz

最先端の検索体験を構築する準備はできましたか?

十分に高度な検索は 1 人の努力だけでは実現できません。Elasticsearch は、データ サイエンティスト、ML オペレーター、エンジニアなど、あなたと同じように検索に情熱を傾ける多くの人々によって支えられています。ぜひつながり、協力して、希望する結果が得られる魔法の検索エクスペリエンスを構築しましょう。

はじめましょう