時系列データストリーム (TSDS) の設定

時系列データストリーム (TSDS) を設定するには、次の手順に従います:

前提条件

  • TSDSを作成する前に、データストリームおよびTSDSの概念に精通している必要があります。
  • このチュートリアルに従うには、次の権限が必要です:
    • クラスター権限: manage_ilm および manage_index_templates.
    • インデックス権限: 作成または変換する任意のTSDSに対して create_doc および create_index. TSDSをロールオーバーするには、manage 権限が必要です。

インデックスライフサイクルポリシーの作成

オプションですが、TSDSのバックインデックスの管理を自動化するためにILMを使用することをお勧めします。ILMにはインデックスライフサイクルポリシーが必要です。

ポリシー内のmax_age基準をrolloverアクションに指定することをお勧めします。これにより、TSDSのバックインデックスの@timestamp範囲が一貫性を保ちます。たとえば、max_age1dに設定することで、rolloverアクションが実行されると、バックインデックスには常に1日のデータが含まれることが保証されます。

Python

  1. resp = client.ilm.put_lifecycle(
  2. name="my-weather-sensor-lifecycle-policy",
  3. policy={
  4. "phases": {
  5. "hot": {
  6. "actions": {
  7. "rollover": {
  8. "max_age": "1d",
  9. "max_primary_shard_size": "50gb"
  10. }
  11. }
  12. },
  13. "warm": {
  14. "min_age": "30d",
  15. "actions": {
  16. "shrink": {
  17. "number_of_shards": 1
  18. },
  19. "forcemerge": {
  20. "max_num_segments": 1
  21. }
  22. }
  23. },
  24. "cold": {
  25. "min_age": "60d",
  26. "actions": {
  27. "searchable_snapshot": {
  28. "snapshot_repository": "found-snapshots"
  29. }
  30. }
  31. },
  32. "frozen": {
  33. "min_age": "90d",
  34. "actions": {
  35. "searchable_snapshot": {
  36. "snapshot_repository": "found-snapshots"
  37. }
  38. }
  39. },
  40. "delete": {
  41. "min_age": "735d",
  42. "actions": {
  43. "delete": {}
  44. }
  45. }
  46. }
  47. },
  48. )
  49. print(resp)

Js

  1. const response = await client.ilm.putLifecycle({
  2. name: "my-weather-sensor-lifecycle-policy",
  3. policy: {
  4. phases: {
  5. hot: {
  6. actions: {
  7. rollover: {
  8. max_age: "1d",
  9. max_primary_shard_size: "50gb",
  10. },
  11. },
  12. },
  13. warm: {
  14. min_age: "30d",
  15. actions: {
  16. shrink: {
  17. number_of_shards: 1,
  18. },
  19. forcemerge: {
  20. max_num_segments: 1,
  21. },
  22. },
  23. },
  24. cold: {
  25. min_age: "60d",
  26. actions: {
  27. searchable_snapshot: {
  28. snapshot_repository: "found-snapshots",
  29. },
  30. },
  31. },
  32. frozen: {
  33. min_age: "90d",
  34. actions: {
  35. searchable_snapshot: {
  36. snapshot_repository: "found-snapshots",
  37. },
  38. },
  39. },
  40. delete: {
  41. min_age: "735d",
  42. actions: {
  43. delete: {},
  44. },
  45. },
  46. },
  47. },
  48. });
  49. console.log(response);

コンソール

  1. PUT _ilm/policy/my-weather-sensor-lifecycle-policy
  2. {
  3. "policy": {
  4. "phases": {
  5. "hot": {
  6. "actions": {
  7. "rollover": {
  8. "max_age": "1d",
  9. "max_primary_shard_size": "50gb"
  10. }
  11. }
  12. },
  13. "warm": {
  14. "min_age": "30d",
  15. "actions": {
  16. "shrink": {
  17. "number_of_shards": 1
  18. },
  19. "forcemerge": {
  20. "max_num_segments": 1
  21. }
  22. }
  23. },
  24. "cold": {
  25. "min_age": "60d",
  26. "actions": {
  27. "searchable_snapshot": {
  28. "snapshot_repository": "found-snapshots"
  29. }
  30. }
  31. },
  32. "frozen": {
  33. "min_age": "90d",
  34. "actions": {
  35. "searchable_snapshot": {
  36. "snapshot_repository": "found-snapshots"
  37. }
  38. }
  39. },
  40. "delete": {
  41. "min_age": "735d",
  42. "actions": {
  43. "delete": {}
  44. }
  45. }
  46. }
  47. }
  48. }

インデックステンプレートの作成

TSDSを設定するには、次の詳細を持つインデックステンプレートを作成します:

  • TSDSの名前に一致する1つ以上のインデックスパターン。私たちのデータストリーム命名スキームを使用することをお勧めします。
  • データストリームを有効にします。
  • 次のように、次元とメトリックを定義するマッピングを指定します:
    • time_series_dimensionの値がtrueの1つ以上の次元フィールド。これらの次元のうち少なくとも1つは、通常のkeywordフィールドである必要があります。
    • time_series_metricマッピングパラメータを使用してマークされた1つ以上のメトリックフィールド
    • オプション: dateまたはdate_nanosマッピングを@timestampフィールドに対して指定します。マッピングを指定しない場合、Elasticsearchは@timestampdateフィールドとしてデフォルトオプションでマッピングします。
  • インデックス設定を定義します:
    • index.mode設定をtime_seriesに設定します。
    • index.lifecycle.nameインデックス設定内のライフサイクルポリシー。
    • オプション: TSDSのバックインデックスに対するindex.number_of_replicasなどの他のインデックス設定。
  • 組み込みテンプレートとの衝突を避けるために、200よりも高い優先度を設定します。インデックスパターンの衝突を避けるを参照してください。
  • オプション: マッピングや他のインデックス設定を含むコンポーネントテンプレート。

Python

  1. resp = client.indices.put_index_template(
  2. name="my-weather-sensor-index-template",
  3. index_patterns=[
  4. "metrics-weather_sensors-*"
  5. ],
  6. data_stream={},
  7. template={
  8. "settings": {
  9. "index.mode": "time_series",
  10. "index.lifecycle.name": "my-lifecycle-policy"
  11. },
  12. "mappings": {
  13. "properties": {
  14. "sensor_id": {
  15. "type": "keyword",
  16. "time_series_dimension": True
  17. },
  18. "location": {
  19. "type": "keyword",
  20. "time_series_dimension": True
  21. },
  22. "temperature": {
  23. "type": "half_float",
  24. "time_series_metric": "gauge"
  25. },
  26. "humidity": {
  27. "type": "half_float",
  28. "time_series_metric": "gauge"
  29. },
  30. "@timestamp": {
  31. "type": "date"
  32. }
  33. }
  34. }
  35. },
  36. priority=500,
  37. meta={
  38. "description": "Template for my weather sensor data"
  39. },
  40. )
  41. print(resp)

Ruby

  1. response = client.indices.put_index_template(
  2. name: 'my-weather-sensor-index-template',
  3. body: {
  4. index_patterns: [
  5. 'metrics-weather_sensors-*'
  6. ],
  7. data_stream: {},
  8. template: {
  9. settings: {
  10. 'index.mode' => 'time_series',
  11. 'index.lifecycle.name' => 'my-lifecycle-policy'
  12. },
  13. mappings: {
  14. properties: {
  15. sensor_id: {
  16. type: 'keyword',
  17. time_series_dimension: true
  18. },
  19. location: {
  20. type: 'keyword',
  21. time_series_dimension: true
  22. },
  23. temperature: {
  24. type: 'half_float',
  25. time_series_metric: 'gauge'
  26. },
  27. humidity: {
  28. type: 'half_float',
  29. time_series_metric: 'gauge'
  30. },
  31. "@timestamp": {
  32. type: 'date'
  33. }
  34. }
  35. }
  36. },
  37. priority: 500,
  38. _meta: {
  39. description: 'Template for my weather sensor data'
  40. }
  41. }
  42. )
  43. puts response

Js

  1. const response = await client.indices.putIndexTemplate({
  2. name: "my-weather-sensor-index-template",
  3. index_patterns: ["metrics-weather_sensors-*"],
  4. data_stream: {},
  5. template: {
  6. settings: {
  7. "index.mode": "time_series",
  8. "index.lifecycle.name": "my-lifecycle-policy",
  9. },
  10. mappings: {
  11. properties: {
  12. sensor_id: {
  13. type: "keyword",
  14. time_series_dimension: true,
  15. },
  16. location: {
  17. type: "keyword",
  18. time_series_dimension: true,
  19. },
  20. temperature: {
  21. type: "half_float",
  22. time_series_metric: "gauge",
  23. },
  24. humidity: {
  25. type: "half_float",
  26. time_series_metric: "gauge",
  27. },
  28. "@timestamp": {
  29. type: "date",
  30. },
  31. },
  32. },
  33. },
  34. priority: 500,
  35. _meta: {
  36. description: "Template for my weather sensor data",
  37. },
  38. });
  39. console.log(response);

コンソール

  1. PUT _index_template/my-weather-sensor-index-template
  2. {
  3. "index_patterns": ["metrics-weather_sensors-*"],
  4. "data_stream": { },
  5. "template": {
  6. "settings": {
  7. "index.mode": "time_series",
  8. "index.lifecycle.name": "my-lifecycle-policy"
  9. },
  10. "mappings": {
  11. "properties": {
  12. "sensor_id": {
  13. "type": "keyword",
  14. "time_series_dimension": true
  15. },
  16. "location": {
  17. "type": "keyword",
  18. "time_series_dimension": true
  19. },
  20. "temperature": {
  21. "type": "half_float",
  22. "time_series_metric": "gauge"
  23. },
  24. "humidity": {
  25. "type": "half_float",
  26. "time_series_metric": "gauge"
  27. },
  28. "@timestamp": {
  29. "type": "date"
  30. }
  31. }
  32. }
  33. },
  34. "priority": 500,
  35. "_meta": {
  36. "description": "Template for my weather sensor data"
  37. }
  38. }

TSDSの作成

インデックスリクエストは、TSDSにドキュメントを追加します。TSDS内のドキュメントには次が含まれている必要があります:

  • @timestampフィールド
  • 1つ以上の次元フィールド。少なくとも1つの次元は、指定されている場合はindex.routing_pathインデックス設定に一致するkeywordフィールドである必要があります。明示的に指定されていない場合、index.routing_pathtrueに設定されているマッピングに自動的に設定されます。

TSDSを自動的に作成するには、TSDSの名前をターゲットにしたインデックスリクエストを送信します。この名前は、インデックステンプレートのインデックスパターンの1つと一致する必要があります。

次の例をテストするには、タイムスタンプを現在の時間の3時間以内に更新します。TSDSに追加されるデータは常に受け入れられた時間範囲内に収まる必要があります。

Python

  1. resp = client.bulk(
  2. index="metrics-weather_sensors-dev",
  3. operations=[
  4. {
  5. "create": {}
  6. },
  7. {
  8. "@timestamp": "2099-05-06T16:21:15.000Z",
  9. "sensor_id": "HAL-000001",
  10. "location": "plains",
  11. "temperature": 26.7,
  12. "humidity": 49.9
  13. },
  14. {
  15. "create": {}
  16. },
  17. {
  18. "@timestamp": "2099-05-06T16:25:42.000Z",
  19. "sensor_id": "SYKENET-000001",
  20. "location": "swamp",
  21. "temperature": 32.4,
  22. "humidity": 88.9
  23. }
  24. ],
  25. )
  26. print(resp)
  27. resp1 = client.index(
  28. index="metrics-weather_sensors-dev",
  29. document={
  30. "@timestamp": "2099-05-06T16:21:15.000Z",
  31. "sensor_id": "SYKENET-000001",
  32. "location": "swamp",
  33. "temperature": 32.4,
  34. "humidity": 88.9
  35. },
  36. )
  37. print(resp1)

Js

  1. const response = await client.bulk({
  2. index: "metrics-weather_sensors-dev",
  3. operations: [
  4. {
  5. create: {},
  6. },
  7. {
  8. "@timestamp": "2099-05-06T16:21:15.000Z",
  9. sensor_id: "HAL-000001",
  10. location: "plains",
  11. temperature: 26.7,
  12. humidity: 49.9,
  13. },
  14. {
  15. create: {},
  16. },
  17. {
  18. "@timestamp": "2099-05-06T16:25:42.000Z",
  19. sensor_id: "SYKENET-000001",
  20. location: "swamp",
  21. temperature: 32.4,
  22. humidity: 88.9,
  23. },
  24. ],
  25. });
  26. console.log(response);
  27. const response1 = await client.index({
  28. index: "metrics-weather_sensors-dev",
  29. document: {
  30. "@timestamp": "2099-05-06T16:21:15.000Z",
  31. sensor_id: "SYKENET-000001",
  32. location: "swamp",
  33. temperature: 32.4,
  34. humidity: 88.9,
  35. },
  36. });
  37. console.log(response1);

コンソール

  1. PUT metrics-weather_sensors-dev/_bulk
  2. { "create":{ } }
  3. { "@timestamp": "2099-05-06T16:21:15.000Z", "sensor_id": "HAL-000001", "location": "plains", "temperature": 26.7,"humidity": 49.9 }
  4. { "create":{ } }
  5. { "@timestamp": "2099-05-06T16:25:42.000Z", "sensor_id": "SYKENET-000001", "location": "swamp", "temperature": 32.4, "humidity": 88.9 }
  6. POST metrics-weather_sensors-dev/_doc
  7. {
  8. "@timestamp": "2099-05-06T16:21:15.000Z",
  9. "sensor_id": "SYKENET-000001",
  10. "location": "swamp",
  11. "temperature": 32.4,
  12. "humidity": 88.9
  13. }

データストリームAPIを使用して、TSDSを手動で作成することもできます。TSDSの名前は、テンプレートのインデックスパターンの1つと一致する必要があります。

Python

  1. resp = client.indices.create_data_stream(
  2. name="metrics-weather_sensors-dev",
  3. )
  4. print(resp)

Ruby

  1. response = client.indices.create_data_stream(
  2. name: 'metrics-weather_sensors-dev'
  3. )
  4. puts response

Js

  1. const response = await client.indices.createDataStream({
  2. name: "metrics-weather_sensors-dev",
  3. });
  4. console.log(response);

コンソール

  1. PUT _data_stream/metrics-weather_sensors-dev

TSDSの保護

インデックス権限を使用して、TSDSへのアクセスを制御します。TSDSに権限を付与すると、そのバックインデックスにも同じ権限が付与されます。

例については、データストリーム権限を参照してください。

既存のデータストリームをTSDSに変換

上記の手順を使用して、既存の通常のデータストリームをTSDSに変換することもできます。この場合、次のことを行う必要があります:

  • 新しいものを作成するのではなく、既存のインデックスライフサイクルポリシー、コンポーネントテンプレート、およびインデックステンプレートを編集します。
  • TSDSを作成するのではなく、その書き込みインデックスを手動でロールオーバーします。これにより、現在の書き込みインデックスと新しいバックインデックスがindex.modetime_series条件を満たすことが保証されます。
    書き込みインデックスを手動でロールオーバーするには、ロールオーバーAPIを使用します。

Python

  1. resp = client.indices.rollover(
  2. alias="metrics-weather_sensors-dev",
  3. )
  4. print(resp)

Ruby

  1. response = client.indices.rollover(
  2. alias: 'metrics-weather_sensors-dev'
  3. )
  4. puts response

Js

  1. const response = await client.indices.rollover({
  2. alias: "metrics-weather_sensors-dev",
  3. });
  4. console.log(response);

コンソール

  1. POST metrics-weather_sensors-dev/_rollover

コンポーネントテンプレートとインデックス.mode設定に関する注意

コンポーネントテンプレートを使用するインデックステンプレートを介してTSDSを構成するのは、少し複雑です。通常、コンポーネントテンプレートでは、マッピングと設定が複数のコンポーネントテンプレートに散らばります。コンポーネントテンプレート内でindex.mode設定を構成する場合、index.routing_path設定は同じコンポーネントテンプレート内で定義する必要があります。さらに、index.routing_pathで言及されているフィールドも、time_series_dimension属性が有効になっている同じコンポーネントテンプレート内で定義する必要があります。

その理由は、各コンポーネントテンプレートが独自に有効である必要があり、時系列インデックスモードがindex.routing_path設定を必要とするためです。インデックステンプレート内でindex.mode設定を構成する場合、index.routing_path設定は自動的に構成されます。これは、time_series_dimension属性が有効になっているフィールドマッピングから派生します。

次は何ですか?

TSDSを設定したので、通常のデータストリームのように管理および使用できます。詳細については、次を参照してください: