对时间序列数据流 (TSDS) 进行重建

编辑

对时间序列数据流 (TSDS) 进行重建编辑

简介编辑

通过重建索引,您可以将文档从旧的时间序列数据流 (TSDS) 复制到新的时间序列数据流。数据流通常支持重建索引,但有一些 限制。 尽管如此,时间序列数据流由于对其包含的每个后备索引的接受时间戳范围有严格控制,因此会带来额外的挑战。直接使用重建索引 API 可能会出错,因为它会尝试插入时间戳超出当前接受窗口的文档。

为避免这些限制,请使用以下概述的过程

  1. 为将包含重建索引数据的目标数据流创建一个索引模板。
  2. 更新模板以

    1. index.time_series.start_timeindex.time_series.end_time 索引设置设置为与旧数据流中最低和最高的 @timestamp 值相匹配。
    2. index.number_of_shards 索引设置设置为旧数据流的所有后备索引的所有主分片的总和。
    3. index.number_of_replicas 设置为零,并取消设置 index.lifecycle.name 索引设置。
  3. 运行重建索引操作直至完成。
  4. 在目标索引模板中还原覆盖的索引设置。
  5. 调用 rollover API 以创建一个可以接收新文档的新后备索引。

此过程仅适用于没有 降采样 配置的时间序列数据流。 具有降采样的数据流只能通过分别重建其后备索引并将它们添加到空的目标数据流来重建索引。

在下文中,我们将通过示例详细说明该过程的每个步骤。

创建 TSDS 模板以接受旧文档编辑

考虑一个具有以下模板的 TSDS

response = client.cluster.put_component_template(
  name: 'source_template',
  body: {
    template: {
      settings: {
        index: {
          number_of_replicas: 2,
          number_of_shards: 2,
          mode: 'time_series',
          routing_path: [
            'metricset'
          ]
        }
      },
      mappings: {
        properties: {
          "@timestamp": {
            type: 'date'
          },
          metricset: {
            type: 'keyword',
            time_series_dimension: true
          },
          "k8s": {
            properties: {
              tx: {
                type: 'long'
              },
              rx: {
                type: 'long'
              }
            }
          }
        }
      }
    }
  }
)
puts response

response = client.indices.put_index_template(
  name: 1,
  body: {
    index_patterns: [
      'k8s*'
    ],
    composed_of: [
      'source_template'
    ],
    data_stream: {}
  }
)
puts response
POST /_component_template/source_template
{
  "template": {
    "settings": {
      "index": {
        "number_of_replicas": 2,
        "number_of_shards": 2,
        "mode": "time_series",
        "routing_path": [ "metricset" ]
      }
    },
    "mappings": {
      "properties": {
        "@timestamp": { "type": "date" },
        "metricset": {
          "type": "keyword",
          "time_series_dimension": true
        },
        "k8s": {
          "properties": {
            "tx": { "type": "long" },
            "rx": { "type": "long" }
          }
        }
      }
    }
  }
}

POST /_index_template/1
{
  "index_patterns": [
    "k8s*"
  ],
  "composed_of": [
    "source_template"
  ],
  "data_stream": {}
}

/k8s/_settings 的可能输出如下所示

{
  ".ds-k8s-2023.09.01-000002": {
    "settings": {
      "index": {
        "mode": "time_series",
        "routing": {
          "allocation": {
            "include": {
              "_tier_preference": "data_hot"
            }
          }
        },
        "hidden": "true",
        "number_of_shards": "2",
        "time_series": {
          "end_time": "2023-09-01T14:00:00.000Z",
          "start_time": "2023-09-01T10:00:00.000Z"
        },
        "provided_name": ".ds-k9s-2023.09.01-000002",
        "creation_date": "1694439857608",
        "number_of_replicas": "2",
        "routing_path": [
          "metricset"
        ],
        ...
      }
    }
  },
  ".ds-k8s-2023.09.01-000001": {
    "settings": {
      "index": {
        "mode": "time_series",
        "routing": {
          "allocation": {
            "include": {
              "_tier_preference": "data_hot"
            }
          }
        },
        "hidden": "true",
        "number_of_shards": "2",
        "time_series": {
          "end_time": "2023-09-01T10:00:00.000Z",
          "start_time": "2023-09-01T06:00:00.000Z"
        },
        "provided_name": ".ds-k9s-2023.09.01-000001",
        "creation_date": "1694439837126",
        "number_of_replicas": "2",
        "routing_path": [
          "metricset"
        ],
        ...
      }
    }
  }
}

要重建此 TSDS 的索引,请勿在目标数据流中重复使用其索引模板,以避免影响其功能。 而是克隆源 TSDS 的模板并应用以下修改

  • 显式设置 index.time_series.start_timeindex.time_series.end_time 索引设置。 它们的值应基于要重建索引的数据流中的最低和最高 @timestamp 值。 这样,初始后备索引就可以加载源数据流中包含的所有数据。
  • index.number_of_shards 索引设置设置为源数据流的所有后备索引的所有主分片的总和。 这有助于保持相同级别的搜索并行度,因为每个分片都在一个单独的线程(或更多线程)中处理。
  • 取消设置 index.lifecycle.name 索引设置(如果有)。 这可以防止 ILM 在重建索引期间修改目标数据流。
  • (可选)将 index.number_of_replicas 设置为零。 这有助于加快重建索引操作。 由于数据已复制,因此由于缺少副本而导致数据丢失的风险有限。

使用上面的示例作为源 TSDS,目标 TSDS 的模板将是

POST /_component_template/destination_template
{
  "template": {
    "settings": {
      "index": {
        "number_of_replicas": 0,
        "number_of_shards": 4,
        "mode": "time_series",
        "routing_path": [ "metricset" ],
        "time_series": {
          "end_time": "2023-09-01T14:00:00.000Z",
          "start_time": "2023-09-01T06:00:00.000Z"
        }
      }
    },
    "mappings": {
      "properties": {
        "@timestamp": { "type": "date" },
        "metricset": {
          "type": "keyword",
          "time_series_dimension": true
        },
        "k8s": {
          "properties": {
            "tx": { "type": "long" },
            "rx": { "type": "long" }
          }
        }
      }
    }
  }
}

POST /_index_template/2
{
  "index_patterns": [
    "k8s*"
  ],
  "composed_of": [
    "destination_template"
  ],
  "data_stream": {}
}

重建索引编辑

调用重建索引 API,例如

response = client.reindex(
  body: {
    source: {
      index: 'k8s'
    },
    dest: {
      index: 'k9s',
      op_type: 'create'
    }
  }
)
puts response
POST /_reindex
{
  "source": {
    "index": "k8s"
  },
  "dest": {
    "index": "k9s",
    "op_type": "create"
  }
}

还原目标索引模板编辑

重建索引操作完成后,按如下方式还原目标 TSDS 的索引模板

  • 删除 index.time_series.start_timeindex.time_series.end_time 的覆盖。
  • 根据需要还原 index.number_of_shardsindex.number_of_replicasindex.lifecycle.name 的值。

使用前面的示例,目标模板修改如下

response = client.cluster.put_component_template(
  name: 'destination_template',
  body: {
    template: {
      settings: {
        index: {
          number_of_replicas: 2,
          number_of_shards: 2,
          mode: 'time_series',
          routing_path: [
            'metricset'
          ]
        }
      },
      mappings: {
        properties: {
          "@timestamp": {
            type: 'date'
          },
          metricset: {
            type: 'keyword',
            time_series_dimension: true
          },
          "k8s": {
            properties: {
              tx: {
                type: 'long'
              },
              rx: {
                type: 'long'
              }
            }
          }
        }
      }
    }
  }
)
puts response
POST /_component_template/destination_template
{
  "template": {
    "settings": {
      "index": {
        "number_of_replicas": 2,
        "number_of_shards": 2,
        "mode": "time_series",
        "routing_path": [ "metricset" ]
      }
    },
    "mappings": {
      "properties": {
        "@timestamp": { "type": "date" },
        "metricset": {
          "type": "keyword",
          "time_series_dimension": true
        },
        "k8s": {
          "properties": {
            "tx": { "type": "long" },
            "rx": { "type": "long" }
          }
        }
      }
    }
  }
}

接下来,在目标数据流上调用 rollover API,而不设置任何条件。

response = client.indices.rollover(
  alias: 'k9s'
)
puts response
POST /k9s/_rollover/

这将创建一个具有更新索引设置的新后备索引。 目标数据流现在可以接受新文档了。

请注意,初始后备索引仍然可以接受源数据流派生的时间戳范围内的文档。 如果不需要这样做,请将其显式标记为 只读