チュートリアル: ILMを使用したロールオーバーの自動化
Elasticsearchにタイムスタンプ付きのドキュメントを継続的にインデックスする場合、通常はデータストリームを使用して、新しいインデックスに定期的にロールオーバーします。これにより、最新のデータに対するパフォーマンス要件を満たし、コストを時間とともに管理し、保持ポリシーを強制し、データを最大限に活用するためのホット-ウォーム-コールドアーキテクチャを実装できます。
データストリームは、追加専用のユースケースに最適です。既存の時系列データを更新または削除する必要がある場合は、データストリームのバックインデックスに直接更新または削除操作を実行できます。同じ_id
を使用して複数のドキュメントを送信し、最後の書き込みが勝つことを期待する場合は、代わりに書き込みインデックスを持つインデックスエイリアスを使用することをお勧めします。それでも、ILMを使用してエイリアスのインデックスを管理し、ロールオーバーできます。データストリームなしで時系列データを管理するにスキップします。
データストリームを使用した時系列データの管理
ILMを使用してデータストリームのロールオーバーと管理を自動化するには、次の手順を実行します:
- 1. ライフサイクルポリシーを作成し、適切なフェーズとアクションを定義します。
- 2. インデックステンプレートを作成し、データストリームを作成し、ILMポリシーとバックインデックスの設定およびマッピング構成を適用します。
- 3. インデックスがライフサイクルフェーズを通過していることを確認します。
BeatsまたはLogstash Elasticsearch出力プラグインのインデックスライフサイクル管理を有効にすると、ライフサイクルポリシーは自動的に設定されます。他のアクションを実行する必要はありません。デフォルトのポリシーはKibana ManagementまたはILM APIを通じて変更できます。
ライフサイクルポリシーの作成
ライフサイクルポリシーは、インデックスライフサイクルのフェーズと各フェーズで実行するアクションを指定します。ライフサイクルには最大5つのフェーズを持つことができます: hot
, warm
, cold
, frozen
, および delete
。
たとえば、timeseries_policy
を定義することができます。これは2つのフェーズを持ちます:
hot
フェーズは、インデックスが50ギガバイトのmax_primary_shard_size
または30日のmax_age
に達したときにロールオーバーアクションを指定します。delete
フェーズは、ロールオーバー後90日でインデックスを削除するmin_age
を設定します。
Kibanaを通じてポリシーを作成するか、[ポリシーの作成または更新](/read/elasticsearch-8-15/442f4ad969cabca9.md) APIを使用して作成できます。Kibanaからポリシーを作成するには、メニューを開き、**Stack Management
> Index Lifecycle Policies**に移動します。**Create policy**をクリックします。
![ポリシー作成ページ](https://cdn.hedaai.com/projects/elasticsearch-8-15/df21fadf01c3c28b56b589b07d730399.png_big1500.jpeg)
APIの例
#### Python
``````python
resp = client.ilm.put_lifecycle(
name="timeseries_policy",
policy={
"phases": {
"hot": {
"actions": {
"rollover": {
"max_primary_shard_size": "50GB",
"max_age": "30d"
}
}
},
"delete": {
"min_age": "90d",
"actions": {
"delete": {}
}
}
}
},
)
print(resp)
`
Ruby
response = client.ilm.put_lifecycle(
policy: 'timeseries_policy',
body: {
policy: {
phases: {
hot: {
actions: {
rollover: {
max_primary_shard_size: '50GB',
max_age: '30d'
}
}
},
delete: {
min_age: '90d',
actions: {
delete: {}
}
}
}
}
}
)
puts response
Js
const response = await client.ilm.putLifecycle({
name: "timeseries_policy",
policy: {
phases: {
hot: {
actions: {
rollover: {
max_primary_shard_size: "50GB",
max_age: "30d",
},
},
},
delete: {
min_age: "90d",
actions: {
delete: {},
},
},
},
},
});
console.log(response);
コンソール
PUT _ilm/policy/timeseries_policy
{
"policy": {
"phases": {
"hot": {
"actions": {
"rollover": {
"max_primary_shard_size": "50GB",
"max_age": "30d"
}
}
},
"delete": {
"min_age": "90d",
"actions": {
"delete": {}
}
}
}
}
}
min_age のデフォルトは0ms であるため、新しいインデックスはhot フェーズにすぐに入ります。 |
|
条件のいずれかが満たされたときにrollover アクションをトリガーします。 |
|
ロールオーバー後90日でインデックスをdelete フェーズに移動します。 |
|
インデックスが削除フェーズに入るときにdelete アクションをトリガーします。 |
データストリームを作成し、ライフサイクルポリシーを適用するためのインデックステンプレートの作成
データストリームを設定するには、まずライフサイクルポリシーを指定するインデックステンプレートを作成します。テンプレートはデータストリーム用であるため、data_stream
の定義も含める必要があります。
たとえば、timeseries_template
を作成して、将来のデータストリームtimeseries
に使用することができます。
ILMがデータストリームを管理できるようにするために、テンプレートは1つのILM設定を構成します:
index.lifecycle.name
は、データストリームに適用するライフサイクルポリシーの名前を指定します。
Kibanaのテンプレート作成ウィザードを使用してテンプレートを追加できます。Kibanaからメニューを開き、**Stack Management
Index Managementに移動します。Index Templatesタブで、Create template**をクリックします。
このウィザードは、指定したオプションでインデックステンプレートを作成するためにインデックステンプレートの作成または更新APIを呼び出します。
APIの例
Python
resp = client.indices.put_index_template(
name="timeseries_template",
index_patterns=[
"timeseries"
],
data_stream={},
template={
"settings": {
"number_of_shards": 1,
"number_of_replicas": 1,
"index.lifecycle.name": "timeseries_policy"
}
},
)
print(resp)
Ruby
response = client.indices.put_index_template(
name: 'timeseries_template',
body: {
index_patterns: [
'timeseries'
],
data_stream: {},
template: {
settings: {
number_of_shards: 1,
number_of_replicas: 1,
'index.lifecycle.name' => 'timeseries_policy'
}
}
}
)
puts response
Js
const response = await client.indices.putIndexTemplate({
name: "timeseries_template",
index_patterns: ["timeseries"],
data_stream: {},
template: {
settings: {
number_of_shards: 1,
number_of_replicas: 1,
"index.lifecycle.name": "timeseries_policy",
},
},
});
console.log(response);
コンソール
PUT _index_template/timeseries_template
{
"index_patterns": ["timeseries"],
"data_stream": { },
"template": {
"settings": {
"number_of_shards": 1,
"number_of_replicas": 1,
"index.lifecycle.name": "timeseries_policy"
}
}
}
ドキュメントがtimeseries ターゲットにインデックスされるときにテンプレートを適用します。 |
|
データストリームを管理するために使用されるILMポリシーの名前。 |
データストリームの作成
まず、インデックステンプレートのindex_patterns
で定義された名前またはワイルドカードパターンにドキュメントをインデックスします。既存のデータストリーム、インデックス、またはインデックスエイリアスがすでにその名前を使用していない限り、インデックスリクエストは自動的に対応するデータストリームを作成し、単一のバックインデックスを持ちます。Elasticsearchは、リクエストのドキュメントをこのバックインデックスに自動的にインデックスし、これもストリームの書き込みインデックスとして機能します。
たとえば、次のリクエストはtimeseries
データストリームと最初の世代のバックインデックス.ds-timeseries-2099.03.08-000001
を作成します。
Python
resp = client.index(
index="timeseries",
document={
"message": "logged the request",
"@timestamp": "1591890611"
},
)
print(resp)
Ruby
response = client.index(
index: 'timeseries',
body: {
message: 'logged the request',
"@timestamp": '1591890611'
}
)
puts response
Js
const response = await client.index({
index: "timeseries",
document: {
message: "logged the request",
"@timestamp": "1591890611",
},
});
console.log(response);
コンソール
POST timeseries/_doc
{
"message": "logged the request",
"@timestamp": "1591890611"
}
ロールオーバー条件がライフサイクルポリシーで満たされると、rollover
アクションは:
- 2世代目のバックインデックス
.ds-timeseries-2099.03.08-000002
を作成します。これはtimeseries
データストリームのバックインデックスであるため、timeseries_template
インデックステンプレートからの設定が新しいインデックスに適用されます。 timeseries
データストリームの最新世代インデックスであるため、新しく作成されたバックインデックス.ds-timeseries-2099.03.08-000002
がデータストリームの書き込みインデックスになります。
このプロセスは、ロールオーバー条件が満たされるたびに繰り返されます。timeseries_policy
によって管理されるデータストリームのすべてのバックインデックスをtimeseries
データストリーム名で検索できます。書き込み操作はデータストリーム名に送信され、現在の書き込みインデックスにルーティングされます。データストリームに対する読み取り操作は、すべてのバックインデックスによって処理されます。
ライフサイクルの進行状況を確認
管理されたインデックスのステータス情報を取得するには、ILM説明APIを使用します。これにより、次のような情報を確認できます:
- インデックスがどのフェーズにあり、そのフェーズに入った時期。
- 現在のアクションと実行中のステップ。
- エラーが発生したか、進行がブロックされているか。
たとえば、次のリクエストはtimeseries
データストリームのバックインデックスに関する情報を取得します:
Python
resp = client.ilm.explain_lifecycle(
index=".ds-timeseries-*",
)
print(resp)
Ruby
response = client.ilm.explain_lifecycle(
index: '.ds-timeseries-*'
)
puts response
Js
const response = await client.ilm.explainLifecycle({
index: ".ds-timeseries-*",
});
console.log(response);
コンソール
GET .ds-timeseries-*/_ilm/explain
次のレスポンスは、データストリームの最初の世代バックインデックスがhot
フェーズのrollover
アクションを待機していることを示しています。この状態のままで、ILMはロールオーバー条件が満たされるまでcheck-rollover-ready
を呼び出し続けます。
コンソール-結果
{
"indices": {
".ds-timeseries-2099.03.07-000001": {
"index": ".ds-timeseries-2099.03.07-000001",
"index_creation_date_millis": 1538475653281,
"time_since_index_creation": "30s",
"managed": true,
"policy": "timeseries_policy",
"lifecycle_date_millis": 1538475653281,
"age": "30s",
"phase": "hot",
"phase_time_millis": 1538475653317,
"action": "rollover",
"action_time_millis": 1538475653317,
"step": "check-rollover-ready",
"step_time_millis": 1538475653317,
"phase_execution": {
"policy": "timeseries_policy",
"phase_definition": {
"min_age": "0ms",
"actions": {
"rollover": {
"max_primary_shard_size": "50gb",
"max_age": "30d"
}
}
},
"version": 1,
"modified_date_in_millis": 1539609701576
}
}
}
}
インデックスのロールオーバーを計算するために使用されるインデックスの年齢はmax_age |
|
インデックスを管理するために使用されるポリシー | |
次のフェーズに移行するためにインデックスされた年齢(この場合、インデックスの年齢と同じです)。 | |
ILMがインデックスで実行しているステップ | |
現在のフェーズの定義(hot フェーズ) |
データストリームなしで時系列データを管理
データストリームは、時系列データをスケールし管理する便利な方法ですが、追加専用に設計されています。データをその場で更新または削除する必要があるユースケースがあることを認識しており、データストリームは削除および更新リクエストを直接サポートしていないため、インデックスAPIをデータストリームのバックインデックスに直接使用する必要があります。これらのケースでも、データストリームの使用をお勧めします。
同じ_id
を使用して複数のドキュメントを送信し、最後の書き込みが勝つことを期待する場合は、データストリームの代わりにインデックスエイリアスを使用して、時系列データを含むインデックスを管理し、定期的に新しいインデックスにロールオーバーすることができます。
ILMを使用してインデックスエイリアスで時系列インデックスのロールオーバーと管理を自動化するには、次の手順を実行します:
- 1. ライフサイクルポリシーを作成し、適切なフェーズとアクションを定義します。ライフサイクルポリシーの作成を参照してください。
- 2. インデックステンプレートを作成し、ポリシーを各新しいインデックスに適用します。
- 3. インデックスをブートストラップし、初期の書き込みインデックスとして設定します。
- 4. インデックスがライフサイクルフェーズを通過していることを確認します。
ライフサイクルポリシーを適用するためのインデックステンプレートの作成
ロールオーバー時に新しい書き込みインデックスにライフサイクルポリシーを自動的に適用するには、新しいインデックスを作成するために使用されるインデックステンプレートでポリシーを指定します。
たとえば、timeseries_template
を作成して、新しいインデックスの名前がtimeseries-*
インデックスパターンに一致するように適用します。
自動ロールオーバーを有効にするために、テンプレートは2つのILM設定を構成します:
index.lifecycle.name
は、インデックスパターンに一致する新しいインデックスに適用するライフサイクルポリシーの名前を指定します。index.lifecycle.rollover_alias
は、インデックスのロールオーバーアクションがトリガーされたときにロールオーバーされるインデックスエイリアスを指定します。
Kibanaのテンプレート作成ウィザードを使用してテンプレートを追加できます。ウィザードにアクセスするには、メニューを開き、**Stack Management
Index Managementに移動します。Index Templatesタブで、Create template**をクリックします。
例のテンプレートの作成テンプレストリクエストは次のようになります:
Python
resp = client.indices.put_index_template(
name="timeseries_template",
index_patterns=[
"timeseries-*"
],
template={
"settings": {
"number_of_shards": 1,
"number_of_replicas": 1,
"index.lifecycle.name": "timeseries_policy",
"index.lifecycle.rollover_alias": "timeseries"
}
},
)
print(resp)
Js
const response = await client.indices.putIndexTemplate({
name: "timeseries_template",
index_patterns: ["timeseries-*"],
template: {
settings: {
number_of_shards: 1,
number_of_replicas: 1,
"index.lifecycle.name": "timeseries_policy",
"index.lifecycle.rollover_alias": "timeseries",
},
},
});
console.log(response);
コンソール
PUT _index_template/timeseries_template
{
"index_patterns": ["timeseries-*"],
"template": {
"settings": {
"number_of_shards": 1,
"number_of_replicas": 1,
"index.lifecycle.name": "timeseries_policy",
"index.lifecycle.rollover_alias": "timeseries"
}
}
}
インデックスの名前がtimeseries- で始まる場合、新しいインデックスにテンプレートを適用します。 |
|
各新しいインデックスに適用するライフサイクルポリシーの名前。 | |
これらのインデックスを参照するために使用されるエイリアスの名前。 必須: ロールオーバーアクションを使用するポリシーに必要です。 |
書き込みインデックスエイリアスで初期の時系列インデックスをブートストラップ
まず、初期インデックスをブートストラップし、インデックステンプレートで指定されたロールオーバーエイリアスの書き込みインデックスとして指定する必要があります。このインデックスの名前は、テンプレートのインデックスパターンと一致し、数字で終わる必要があります。ロールオーバー時に、この値はインデックスの新しい名前を生成するためにインクリメントされます。
たとえば、次のリクエストはtimeseries-000001
というインデックスを作成し、timeseries
エイリアスの書き込みインデックスにします。
Python
resp = client.indices.create(
index="timeseries-000001",
aliases={
"timeseries": {
"is_write_index": True
}
},
)
print(resp)
Js
const response = await client.indices.create({
index: "timeseries-000001",
aliases: {
timeseries: {
is_write_index: true,
},
},
});
console.log(response);
コンソール
PUT timeseries-000001
{
"aliases": {
"timeseries": {
"is_write_index": true
}
}
}
ロールオーバー条件が満たされると、rollover
アクションは:
timeseries-000002
という新しいインデックスを作成します。これはtimeseries-*
パターンに一致するため、timeseries_template
からの設定が新しいインデックスに適用されます。- 新しいインデックスを書き込みインデックスとして指定し、ブートストラップインデックスを読み取り専用にします。
このプロセスは、ロールオーバー条件が満たされるたびに繰り返されます。timeseries_policy
によって管理されるすべてのインデックスをtimeseries
エイリアスで検索できます。書き込み操作はエイリアスに送信され、現在の書き込みインデックスにルーティングされます。
ライフサイクルの進行状況を確認
管理されたインデックスのステータス情報を取得することは、データストリームの場合と非常に似ています。データストリームの進行状況を確認するセクションを参照してください。唯一の違いはインデックスの名前空間であるため、進行状況を取得するには次のAPI呼び出しが必要です:
Python
resp = client.ilm.explain_lifecycle(
index="timeseries-*",
)
print(resp)
Ruby
response = client.ilm.explain_lifecycle(
index: 'timeseries-*'
)
puts response
Js
const response = await client.ilm.explainLifecycle({
index: "timeseries-*",
});
console.log(response);
コンソール
GET timeseries-*/_ilm/explain