Elasticsearch Index Templateについて

GettyImages-1249879063-copy-1

はじめに

本文書はElasticsearchのIndex Templateについて説明しています。

本文書は2023年1月時点の情報を基に作成しております。今後リリースされる新しいバージョンによって仕様が異なる可能性がありますので、予めご了承ください。

想定読者はElasticsearchの管理者です。

ElasticsearchとはElastic社が提供する分散型データベースです。Orchestratorは既定値では実行ログをSQL Serverに格納しますが、設定変更によりElasticsearchに格納することも可能です。大量のログデータを扱う場合はSQL Serverの負荷低減のため、ログデータをElasticsearchのみに保存することを推奨します。

Elasticsearchを利用するケースにおいて、Index Templateを活用することでElasticsearchの動作の安定化や、ディスクの節約に繋がります。

ElasticsearchにおけるIndexとは

ElasticsearchではデータをIndexとして保存します。IndexとはRDB(リレーショナルデータベース)のテーブルと同じような役割です。 1件1件のデータをDocument、Documentの要素のことをFieldと呼びます。

elasticsearch-index-template

Orchestratorから送付されたロボット実行ログは、既定値でテナント名に年月が付与された形式で作成されたIndexに格納されます。テナントが複数ある場合、各テナントごとに実行ログのIndexが作成されます。

例:default-2022.12

Indexを月ごとに分けることで、古いデータの削除が容易になります。Elasticsearchは、Indexを消す処理は高速に行えますが、Indexの中の一部を何らかの条件(日付が指定日より前のもの、など)で削除する処理は負荷の高い処理となるためです。

なお、Kibanaでデータを可視化する際には、Index名のパターン(Index pattern)を「default-*」のように指定してデータを取り扱うことができます。そのためKibanaの利用の際にはIndexが月ごとに分かれていることを意識することはありません。

Indexの設定

ElasticseacrhのIndexには、以下のような構成要素があります。

  • シャードの構成(Primary Shards、Replica Shards)

  • 言語処理の定義(Analyzers、Char Filters)

  • フィールドマッピングの定義(Mappings)

各項目の詳細は後述の章で解説します。

これらは、原則としてIndexの作成時に設定するもので、Indexの作成後には変更できません。

またElasticsearchには、Indexの作成を明示的に行わなくても、新しいIndexにデータを投入することができる機能があります。その場合は、上記の各種項目は全てデフォルトの値で設定されます。

Orchestratorから送信されるログが月ごとに新しいIndexに格納される場合、月が切り替わって最初のログがElasticsearchに入るタイミングでIndexが自動的に作成されることになります。

Indexの設定は全てデフォルトのままでも基本的には利用可能ですが、一部の設定の変更により、Elasticsearchの動作の安定化やディスク使用量の削減につながることが期待できます。

Elasticsearchには、新しいIndex名を指定してデータ投入した際の、「デフォルトのIndex設定」をカスタマイズする、Index Template という機能があるため、Orchestratorからデータを投入する際はIndex Templateを使うのが便利です。 そうすることで、Indexの設定を変更したい場合も、手動であらかじめIndexを作成する必要がなくなります。

Index Templateとは

Index Templateとは環境に合わせてカスタマイズしたIndexの設定内容を、テンプレート化する機能です。Index Templateを作成することでOrchestratorから定期的に作成されるIndexに対して、カスタマイズした設定内容を自動的に適用することができます。

注意点としてIndex TemplateはIndexが作成されたタイミングで適用されるため、作成済みのIndexには適用されません。Orchestratorから作成されるIndexの場合、Index Templateを作成した翌月以降に新規作成されるIndexから適用されます。既存のIndexに設定を適用したい場合は、Index Templateを作成した後に同じデータのIndexをReindex等で再作成し、元々のIndexを削除するといった対応をする必要があります。

ご参考:Component Templateとは

Elasticsearchバージョン7.8以降でリリースされた新機能です。Index Templateで設定できる項目をさらにテンプレート化、部品化することで、Index Template適用時にComponent Templateを呼び出すことができます。

従来のIndex Templateは適用したいIndex Patternを指定して適用できますが、各Index Patternに対して一つずつ適用をする必要がありました。

Orchetratorは既定値で複数テナントを作成した場合、それぞれのテナントごとに異なるIndexが作成されます。全てのIndexに同じようなIndexテンプレートを適用する場合には通常一つずつIndex Templateを適用しますが、異なるデータが入る違うIndexであっても、同じフィールドがある場合は同じ設定にしたほうが分析をする際に便利なことがあります。Component Templateを利用することでその後の一括変更も容易となります。

詳しくはElastic社のドキュメントを参照ください。

https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-component-template.html

Index Templateで設定できる項目例

以下にOrchestratorから送付されるログを格納する上で、考慮が必要となる可能性のある項目例を紹介します。

・index_patterns(必須)

Templateを適用するIndexをindexPatternsとして指定します。通常はOrchestratorから出力されるIndex名に適用させるため、ワイルドカードを利用して「default-*」のように設定します。

・numberofshards

Indexのプライマリシャード数を指定できます。

シャードとは、Indexを小さく分割したものを指します。例えばプライマリシャードを2に設定した場合、Indexを2つのシャードに分けてElasticsearch上で管理します。Elasticsearchを複数台で構成されている場合はシャードを分散して処理することで、処理速度の向上が見込めます。Elasticsearchをシングル構成で運用している場合はシャードを分ける意味が無いため、Indexがあまりに大きくなければプライマリシャードは1に設定します。

プライマリシャードの既定値はElasticsearchのバージョンによって異なり、バージョン6.x以前は5、バージョン7.x以降は1と設定されています。

・numberofreplicas

Indexのレプリカシャード数を指定できます。

レプリカシャードとは、プライマリシャードのコピーであり、クラスタ構成のElasticsearch環境で、1台のノードに障害が発生した場合も運用を継続できるようにする目的で作成されます。

Elasticsearchをシングル構成で運用している場合は、レプリカシャードを設定するとプライマリシャードと同じサーバー内に作成を試みますが、実際には仕様上作成ができません。この時にレプリカシャードが作成されないため、該当IndexのステータスがYellowになります。仮に作成されたとしてもノード自体の障害に対応できず作成する必要が無いため、レプリカシャードは0に設定します。

冗長構成の場合は基本的に1に設定します。

またプライマリシャード、レプリカシャードの設計についてはその他に下記2つの注意が必要です。

1. 1つのシャードのサイズが大きくなりすぎないようにすること 処理が遅くなることを防ぐために、40GBを超えない程度にすることが推奨されています。1ヶ月分のIndexのサイズが40GBを超える場合は、プライマリシャード数を2以上に増やすか、日単位でIndexを作成することを検討してください。

2. Elasticsearchクラスタ全体のシャード数が多くなりすぎないようにすること 1とは逆に、シャードを細かく分けすぎないことも必要です。シャードの数に比例してヒープメモリの使用量が増えるため、シャードの数が多すぎるとクラスタの挙動が不安定になります。 バージョン8.2以前ではヒープメモリ1GBあたりのシャード数を20以下にすることを目安としてください。バージョン8.3以降では1シャードあたりのヒープ使用量が劇的に減少したことに伴い、Indexの1 Fieldあたり1KBを目安とするよう変更されました。

詳しくはElastic社のドキュメントを参照ください。

https://www.elastic.co/jp/blog/how-many-shards-should-i-have-in-my-elasticsearch-cluster

・mappings

フィールドごとにデータをどのように扱うかを指定することができます。Elasticsearch v8.5では27項目が存在します。詳しくはElastic社のドキュメントを参照ください。

https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-params.html

FieldのTypeとは、データの形式であり、TypeによってKibanaで可視化を行った際の用途が変わります。例えば時系列のデータを扱う場合、日時を表すFieldはdate型である必要があります。

FieldのTypeを指定しない場合、Elasticsearchは最初に入ったデータを基に各FieldのTypeを決定します。つまり文章のような文字列が最初に入ればそのフィールドのTypeは「text」、「keyword」となり、日付のような文字列("2022-12-01T00:00:00Z")が入れば「date」となります。

一度FieldのTypeが決まると、後からFieldのTypeを変更することはできません。予期せぬTypeに設定された場合、Indexを新たに作り直す必要があります。こうした事故を防ぐためIndexに予めTypeを決定することが可能です。ただしTypeを指定し、そのTypeに合わない値がログとして送られてきた場合、エラーとなりElasticsearchはログを破棄します。

Orchestratorを利用する上では基本的に設定をしなくとも問題はありませんが、同じFieldに日付の形式や文字列などが混在して入る場合は予め、任意の文字列を格納できるtext型やKeyword型にしておくことを推奨します。

・date_detection

mappings内の一つの設定です。Field Typeがdate型に自動的に設定されることを防ぎます。

前述の通り、ElasticsearchはIndexが作成されてから初めて入ったデータを基に、各フィールドのTypeを決定します。Typeは一つ、または複数のTypeが割り当てられます。

例えばAddLogFieldsアクティビティを利用し、追加したフィールドに日付のような表記(例:"2022-12-01T00:00:00Z")が入った場合には自動でそのFieldはdate型と認識されますが、以降に追加されるログでそのフィールドに日付の型に合った表記以外のデータが挿入された場合、エラーとなり、ドキュメント自体が全く入りません。

たまたま最初にdate型のようなデータが入ってしまって自動的にdate型になることを防ぎたい際に、date_detectionをfalseにすることで自動でdate型にしない設定にすることができます。

ただし分析時にdate型として扱えないため、このフィールドをTimeStampとして利用したい場合はこの設定をせず規定値のtrueの状態にするか、別途mappingsの設定を利用してdate型を指定します。

・ignore_malformed

元々Fieldに設定されていたTypeとは異なるTypeのデータが送付された際に、既定値ではドキュメント自体が切り捨てられ、何も保存がされませんが、ignore-malformedオプションをtrueに設定することで、該当FieldをNullとして、該当のField以外のデータを保存しドキュメント自体は追加保存されます。

Typeによるエラーがあった際に、不完全でも良いのでドキュメントを残したいというケースではignore_malformedをtrueに設定します。不完全なデータを残したくないケースではデフォルトのままにします。

・ignore_above

keyword typeに対する設定です。この設定値で指定した文字数よりも長い文字列が来た場合に、そのFieldが無視されて、keyword typeの索引が作られなくなります。

keyword typeは、文字列の分かち書きなどをせず、そのまま索引を作るデータタイプです。

keyword typeは、terms aggregationなどでも用いられます。

通常、あまり長い文字数のデータが入る可能性があるFieldは、terms aggregationの対象として使わないため、ディスクサイズとヒープメモリの節約のために一定以上の長さのFieldは無視されます。規定値は256文字です。

ですが、例えば「過去に発生したエラーメッセージを集計して発生回数Top 100を出したい」といった分析を行う場合などは、256文字を超えるメッセージが無視され、分析したい内容が正しく出ないことがあります。そのような使い方も想定する場合は、ignore_aboveを大きくすることを検討してください。最大で8191文字まで増やすことが可能です。

Document Typeについて

Document Typeは、Elasticsearchバージョン5まで使われていた機能で、一つのIndexの中に複数のmapping定義を持たせることができるものでした。例えば、あるIndexに対し、

type1・・・「message」Fieldはtext型、「level」Fieldは整数型

type2・・・「message」Fieldはtext型、「level」Fieldはkeyword型

というように、異なる設定のデータセットを定義することが可能でした。

しかし、このような仕組みはとても分かりづらく、「違うField typeを指定したデータを持たせたいならそもそもIndexを分ければよい」と考えられるようになり、Document Typeの機能は廃止されることになりました。

Elasticsearchのデータの持ち方に対する大きな変更だったため、後方互換性の維持のため、Document Typeの廃止は以下の段階を踏むことになりました。

バージョン6: 一つのIndexにDocument Typeは一つしか定義できない

バージョン7: Document Typeを指定しなくてもIndexが作れるようになった。ただし、Document Typeを明示的に指定してIndexを作成することもできる

バージョン8: Document Typeは完全に廃止

なお、バージョン7では、Document Typeを明示的に指定してIndexを作成した場合は、そのIndexにデータを投入する際に必ずそのDocument Typeを指定する必要があります。

Orchestratorのバージョン22.4以前の古いバージョンでは、Elasticsearchに合わせてDocument Typeを既定で指定する仕様となっていました。UiPath.Orchestrator.dll.config内のElasticsearchに関する設定で、以下のようにlogEventという値で既定で設定されます。

documentType="logEvent"

Orchestrator バージョン22.10以降では、インストール時にElasticsearchバージョン8以降を利用する場合のオプションが追加され、このオプションを選択した場合はDocument Typeが指定されません。

注意点として、Elasticsearch、OrchestratorでDocument Typeを設定した場合、設定を合わせる必要があります。片方だけ設定をしている場合や、異なる設定になっている場合、まったくログが格納されません。

Document Type設定の違いによる障害を防ぐため、Elasticsearchバージョン7を利用している場合、Elasticsearch、OrchestratorともにDocument Typeを設定しないことを推奨します。

Elasticsearchバージョン8を利用している場合、Document Typeは廃止となっているバージョンである為、Document Typeを何も指定しないことを推奨します。

UiPath.Orchestrator.dll.config内は下記のように何も指定しないことを推奨します。

<target xsi:type="ElasticSearch" name="robotElastic" requireAuth="false" username="" password="" index="${event-properties:item=indexName}-${date:format=yyyy.MM}" documentType="" includeAllProperties="true" layout="${message}" excludedProperties="agentSessionId,tenantId,indexName" uri="https://elasticsearch.local" />

サポートが終了したバージョンではありますが、Elasticsearchバージョン6以前を利用している場合は、何らかのDocument Typeを指定する必要があります。Index TemplateでもDocumentTypeを指定することが必要です。

<target xsi:type="ElasticSearch" name="robotElastic" requireAuth="false" username="" password="" index="${event-properties:item=indexName}-${date:format=yyyy.MM}" documentType="logEvent" includeAllProperties="true" layout="${message}" excludedProperties="agentSessionId,tenantId,indexName" uri="https://elasticsearch.local" />

Index Templateの設定例

下記はシングル構成を前提としたIndex Templateの設定です。

PUT _index_template/uipath { "index_patterns": [ "default-*" ], "template": { "settings": { "index": { "number_of_shards": "1", "number_of_replicas": "0", "mapping": { "ignore_malformed": true } } }, "mappings": { "date_detection": false, "properties": { "@timestamp": { "type": "date", "ignore_malformed": false }, "timeStamp": { "type": "date" }, "rawMessage": { "type": "text", "index": false }, "message": { "type": "text", "fields": { "keyword": { "type": "keyword", "ignore_above": 8191 } } } } } } }

(ご参考)Document Typeを指定する場合

Document Typeを指定する場合、PUT _index_templateクエリを利用することができません。

代わりにPUT _templateクエリを利用します。

PUT _template/test1?include_type_name=true { "index_patterns": [ "default-*" ], "settings": { "index": { "number_of_shards": "1", "number_of_replicas": "0" } }, "mappings": { "logEvent": { "properties": { "rawMessage": { "type": "text", "index": false } } } } }

参考

Orchestrator側の設定方法は弊社ドキュメントを参照してください。

https://docs.uipath.com/ja/orchestrator/standalone/2022.10/installation-guide/uipath-orchestrator-dll-config#additional-settings-elasticsearch