【Elasticsearch】reindex
Elasticsearch 的 Reindex API 是一个强大的工具,用于将文档从一个源索引复制到另一个目标索引。它不仅可以用于简单的数据迁移,还可以在重新索引的过程中修改文档内容、过滤文档、并行化处理,甚至从远程集群重新索引数据。以下是 Reindex API 的详细功能和使用场景总结:
---
Elasticsearch Reindex API 详解
1\.基本功能
1.1 从一个索引复制到另一个索引
Reindex API 的核心功能是将文档从一个源索引复制到目标索引。源可以是任何现有的索引、别名或数据流,而目标必须与源不同。例如:
```http
POST _reindex
{
"source": {
"index": "my-old-index"
},
"dest": {
"index": "my-new-index"
}
}
```
1.2 支持从多个源索引复制
你可以通过在`source`中指定多个索引,一次性从多个源索引中复制文档:
```http
POST _reindex
{
"source": {
"index": ["my-old-index-1", "my-old-index-2"]
},
"dest": {
"index": "my-new-index"
}
}
```
1.3 支持数据流(Data Streams)
Reindex API 还支持将文档重新索引到数据流中。如果目标是数据流,`op_type`必须设置为`create`,以确保只添加新文档,而不会更新已存在的文档。
---
2\.高级功能
2.1 使用查询过滤文档
你可以通过在`source`中添加查询,仅重新索引满足条件的文档。例如,仅复制`user.id`为`kimchy`的文档:
```http
POST _reindex
{
"source": {
"index": "my-old-index",
"query": {
"term": {
"user.id": "kimchy"
}
}
},
"dest": {
"index": "my-new-index"
}
}
```
2.2 使用脚本修改文档
Reindex API 支持在重新索引过程中通过脚本修改文档内容。例如,你可以重命名字段或删除字段:
```http
POST _reindex
{
"source": {
"index": "my-old-index"
},
"dest": {
"index": "my-new-index"
},
"script": {
"source": "ctx._source.new_field = ctx._source.remove('old_field')"
}
}
```
2.3 并行化处理(Sliced Scroll)
为了提高效率,Reindex API 支持将任务切分成多个子任务并行处理。你可以手动指定切片数量,或者让 Elasticsearch 自动选择切片数量:
```http
POST _reindex
{
"source": {
"index": "my-old-index"
},
"dest": {
"index": "my-new-index"
},
"slices": "auto"
}
```
---
3\.特殊场景
3.1 从远程集群重新索引
Reindex API 支持从远程 Elasticsearch 集群重新索引数据。你需要在`source`中指定远程集群的地址,并确保远程主机已在`elasticsearch.yml`文件中配置到`reindex.remote.whitelist`中:
```http
POST _reindex
{
"source": {
"remote": {
"host": "http://remote-cluster:9200"
},
"index": "my-old-index"
},
"dest": {
"index": "my-new-index"
}
}
```
3.2 重新索引到 Ingest Pipeline
你可以将文档重新索引到一个带有 Ingest Pipeline 的目标索引,以便在索引过程中进一步处理文档:
```http
POST _reindex
{
"source": {
"index": "my-old-index"
},
"dest": {
"index": "my-new-index",
"pipeline": "my-ingest-pipeline"
}
}
```
3.3 处理版本冲突
默认情况下,版本冲突会终止 Reindex 操作。你可以通过设置`conflicts`参数为`proceed`,让操作继续执行:
```http
POST _reindex
{
"source": {
"index": "my-old-index"
},
"dest": {
"index": "my-new-index"
},
"conflicts": "proceed"
}
```
---
4\.性能优化
4.1 节流(Throttling)
你可以通过`requests_per_second`参数限制 Reindex API 的请求速率,以避免对集群造成过大压力:
```http
POST _reindex
{
"source": {
"index": "my-old-index"
},
"dest": {
"index": "my-new-index"
},
"requests_per_second": 100
}
```
4.2 批量大小(Batch Size)
通过调整`size`参数,可以控制每次批量处理的文档数量。较小的批次可以减少内存占用:
```http
POST _reindex
{
"source": {
"index": "my-old-index",
"size": 500
},
"dest": {
"index": "my-new-index"
}
}
```
4.3 异步执行
如果数据量较大,可以将 Reindex API 设置为异步执行,通过`wait_for_completion=false`参数返回一个任务 ID,用于后续查询或取消任务:
```http
POST _reindex?wait_for_completion=false
{
"source": {
"index": "my-old-index"
},
"dest": {
"index": "my-new-index"
}
}
```
---
5\.常见用例
5.1 数据迁移
Reindex API 是将数据从旧索引迁移到新索引的理想工具,尤其是在需要更改索引设置(如分片数量、副本数量)或映射时。
5.2 数据清理
通过脚本或查询,你可以仅重新索引需要的文档,从而清理不需要的数据。
5.3 数据流的重新索引
如果你需要将旧索引中的数据迁移到新的数据流中,Reindex API 可以确保数据的追加操作符合数据流的特性。
5.4 跨集群数据迁移
Reindex API 支持从远程集群重新索引数据,这使得跨集群迁移数据变得简单高效。
---
6\.注意事项
• 版本兼容性:Reindex API 不支持跨主版本的正向兼容性。例如,你不能从 7.x 集群重新索引到 6.x 集群。
• 索引设置:目标索引的设置(如分片数量、副本数量、映射)必须在重新索引之前配置好。
• 权限要求:如果启用了安全功能,你需要具备源索引的`read`权限和目标索引的`write`权限。
• 远程集群配置:如果从远程集群重新索引,远程主机必须在`elasticsearch.yml`文件中显式允许。
---
总结
Elasticsearch 的 Reindex API 是一个功能强大且灵活的工具,适用于多种场景,包括数据迁移、数据清理、跨集群迁移等。通过合理配置和优化,你可以高效地完成复杂的重新索引任务,同时避免对集群性能造成过大影响。
以下是 Elasticsearch Reindex API 的一个完整示例,展示了所有可能的参数及其解释。这个示例涵盖了从源索引到目标索引的重新索引操作,包括查询过滤、脚本处理、并行化处理、节流、版本冲突处理等高级功能。
---
完整的 Reindex API 示例
```http
POST _reindex
{
"source": {
"index": "my-old-index", <!-- 源索引名称 -->
"query": { <!-- 查询过滤,仅重新索引满足条件的文档 -->
"match": {
"user.id": "kimchy"
}
},
"remote": { <!-- 从远程集群重新索引 -->
"host": "http://remote-cluster:9200",
"username": "remote-user",
"password": "remote-password"
},
"size": 500, <!-- 每批次处理的文档数量 -->
"slice": { <!-- 手动切片 -->
"id": 0,
"max": 5
},
"_source": ["field1", "field2"] <!-- 仅重新索引指定字段 -->
},
"dest": {
"index": "my-new-index", <!-- 目标索引名称 -->
"version_type": "external", <!-- 版本控制类型 -->
"op_type": "create", <!-- 操作类型,确保目标索引中不存在相同 ID 的文档 -->
"pipeline": "my-ingest-pipeline", <!-- 使用的 Ingest Pipeline -->
"routing": "=some-routing-value" <!-- 目标索引的路由值 -->
},
"script": { <!-- 在重新索引过程中运行的脚本 -->
"source": "ctx._source.new_field = ctx._source.remove('old_field')",
"lang": "painless"
},
"refresh": true, <!-- 是否刷新目标索引 -->
"timeout": "2m", <!-- 等待操作完成的超时时间 -->
"wait_for_active_shards": "all", <!-- 等待活动分片的数量 -->
"wait_for_completion": false, <!-- 是否等待操作完成 -->
"requests_per_second": 100, <!-- 每秒请求速率限制 -->
"require_alias": false, <!-- 目标是否必须是别名 -->
"scroll": "10m", <!-- 滚动搜索保持一致视图的时间长度 -->
"slices": "auto", <!-- 自动选择切片数量 -->
"max_docs": 10000, <!-- 最大处理的文档数量 -->
"conflicts": "proceed" <!-- 是否继续处理版本冲突 -->
}
```
---
参数解释
1.`source`参数
• `index`:源索引的名称,可以是单个索引、别名或数据流,也可以是逗号分隔的多个索引。
• `query`:使用 Query DSL 指定要重新索引的文档子集。如果没有指定,则重新索引所有文档。
• `remote`:用于从远程集群重新索引的配置,包括:
• `host`:远程集群的地址。
• `username`和`password`:用于远程集群的身份验证。
• `size`:每批次处理的文档数量,默认为 1000。
• `slice`:手动切片参数,用于并行化处理。`id`是当前切片的 ID,`max`是总切片数量。
• `_source`:指定要重新索引的字段,可以是布尔值或字段列表。如果设置为`false`,则不包含`_source`字段。
2.`dest`参数
• `index`:目标索引的名称。
• `version_type`:版本控制类型,可选值为`internal`、`external`、`external_gt`和`external_gte`。
• `op_type`:操作类型,可选值为`index`或`create`。如果目标是数据流,则必须设置为`create`。
• `pipeline`:指定使用的 Ingest Pipeline。
• `routing`:目标索引的路由值,可以是`keep`、`discard`或自定义值。
3.脚本参数
• `script`:在重新索引过程中运行的脚本,用于修改文档内容或元数据。支持 Painless、Expression 等脚本语言。
• `source`:脚本内容。
• `lang`:脚本语言,默认为`painless`。
4.其他参数
• `refresh`:是否刷新目标索引,使文档立即可见。默认值为`false`。
• `timeout`:等待操作完成的超时时间,默认为 1 分钟。
• `wait_for_active_shards`:等待活动分片的数量,可选值为`all`或非负整数。
• `wait_for_completion`:是否等待操作完成。如果设置为`false`,操作将异步执行,并返回一个任务 ID。
• `requests_per_second`:每秒请求速率限制,默认值为`-1`(不限制)。
• `require_alias`:目标是否必须是别名,默认值为`false`。
• `scroll`:滚动搜索保持一致视图的时间长度,默认为 5 分钟。
• `slices`:切片数量,用于并行化处理。可以设置为整数或`auto`。
• `max_docs`:最大处理的文档数量,默认为所有文档。
• `conflicts`:是否继续处理版本冲突,可选值为`abort`或`proceed`。
---
响应示例
Reindex API 的响应包含以下信息:
```json
{
"took": 1234, <!-- 操作所花费的总时间(毫秒) -->
"timed_out": false, <!-- 是否超时 -->
"total": 10000, <!-- 成功处理的文档数量 -->
"updated": 5000, <!-- 成功更新的文档数量 -->
"created": 5000, <!-- 成功创建的文档数量 -->
"deleted": 0, <!-- 成功删除的文档数量 -->
"batches": 20, <!-- 滚动响应的数量 -->
"noops": 0, <!-- 被忽略的文档数量 -->
"version_conflicts": 0, <!-- 版本冲突的数量 -->
"retries": { <!-- 重试次数 -->
"bulk": 0,
"search": 0
},
"throttled_millis": 0, <!-- 为符合速率限制而睡眠的时间 -->
"failures": [] <!-- 失败信息数组 -->
}
```
---
注意事项
1. 版本兼容性:Reindex API 不支持跨主版本的正向兼容性。例如,不能从 7.x 集群重新索引到 6.x 集群。
2. 索引设置:目标索引的设置(如分片数量、副本数量、映射)必须在重新索引之前配置好。
3. 权限要求:如果启用了安全功能,需要具备源索引的`read`权限和目标索引的`write`权限。
4. 远程集群配置:如果从远程集群重新索引,远程主机必须在`elasticsearch.yml`文件中显式允许。
通过合理配置这些参数,你可以灵活地控制 Reindex API 的行为,满足不同的数据迁移和处理需求。