elasticsearch Reindex API 异步重建索引
Reindex API
这是针对Elasticsearch官方文档的 Reindex API部分的翻译。在Elasticsearch的生产环境使用中,你存储了大量的数据,如果你需要改变某个索引里的某个字段类型,或者删除某个字段,你就不得不重建索引,但是又不能影响线上服务。官方提供了 Reindex API接口,处理这种情况。
原文地址:
https://www.elastic.co/guide/en/elasticsearch/reference/5.5/docs-reindex.html
注意
Reindex接口不提供复制源索引的设置去创建目标索引的方法。我们应该在运行_reindex操作之前,需要自己创建目标索引,并设置映射、碎片计数、副本等。
基本用法
最基本的_reindex用法只是将文档从一个索引复制到另一个索引。
下面示例:把文档从twitter索引复制到new_twitter索引:
POST _reindex
{
"source": {
"index": "twitter"
},
"dest": {
"index": "new_twitter"
}
}
这个请求将返回一下结果:
{
"took" : 147,
"timed_out": false,
"created": 120,
"updated": 0,
"deleted": 0,
"batches": 1,
"version_conflicts": 0,
"noops": 0,
"retries": {
"bulk": 0,
"search": 0
},
"throttled_millis": 0,
"requests_per_second": -1.0,
"throttled_until_millis": 0,
"total": 120,
"failures" : [ ]
}
设置version_type
设置version_type为internal
就像_update_by_query一样,_reindex
获取源索引的快照,但其目标必须是不同的索引,因此不太可能发生版本冲突。 dest元素可以像索引API一样配置,以控制乐观并发控制。 只是省略version_type
(如上所述)或将其设置为internal
,将导致Elasticsearch盲目地将文档转储到目标中,覆盖任何碰巧具有相同类型和id的文件。概括下就是全部覆盖
,示例如下:
POST _reindex
{
"source": {
"index": "twitter"
},
"dest": {
"index": "new_twitter",
"version_type": "internal"
}
}
设置version_type为external
将version_typ
e设置为external
将导致Elasticsearch保留源中的版本,创建缺少的任何文档,并更新目标索引中具有旧版本的文档而不是源索引中的任何文档。概括下就是创建没有的,更新已有的,有版本的概念
,示例如下:
POST _reindex
{
"source": {
"index": "twitter"
},
"dest": {
"index": "new_twitter",
"version_type": "external"
}
}
设置op_type
将op_type
设置为 create
将导致_reindex
仅在目标索引中创建缺少的文档。 所有现有文档都会导致版本冲突,示例如下:
POST _reindex
{
"source": {
"index": "twitter"
},
"dest": {
"index": "new_twitter",
"op_type": "create"
}
}
默认情况下,版本冲突会中止_reindex
进程,但可以在正文中设置"conflicts": "proceed"
来使重建继续,示例如下:
POST _reindex
{
"conflicts": "proceed",
"source": {
"index": "twitter"
},
"dest": {
"index": "new_twitter",
"op_type": "create"
}
}
根据限制条件重建索引
您可以通过向源添加类型或添加查询来限制文档。
根据查询限制
示例如下,这只会将kimchy制作的推文复制到new_twitter中:
POST _reindex
{
"source": {
"index": "twitter",
"type": "tweet",
"query": {
"term": {
"user": "kimchy"
}
}
},
"dest": {
"index": "new_twitter"
}
}
多index和type
源中的索引和类型都可以是多个,允许在一个请求中从许多源复制。 这将从twitter
和blog
索引中的tweet
和post
类型复制文档。 它包括twitter索引中的帖子类型和blog索引中的推文类型。 如果您想要更具体,则需要使用查询。 此时不会处理ID冲突。 目标索引将保持有效,但由于迭代顺序没有明确定义,因此不容易预测哪个文档会存活。概括下,可以从多个源重建索引到一个目标索引,但是创建索引时ID相同,后面的覆盖前面的
,示例如下
POST _reindex
{
"source": {
"index": ["twitter", "blog"],
"type": ["tweet", "post"]
},
"dest": {
"index": "all_together"
}
}
限制数量
也可以通过设置大小来限制处理文档的数量。 这只会将一个文档从twitter
复制到new_twitter
,示例如下:
POST _reindex
{
"size": 1,
"source": {
"index": "twitter"
},
"dest": {
"index": "new_twitter"
}
}
限制排序和数量
如果您需要来自twitter索引的特定文档集,则需要进行排序。 排序使滚动效率降低,但在某些情况下,它是值得的。 如果可能,请选择更具选择性的查询来进行大小和排序。概括下,可以先排序再重建部分索引
, 这会将10000个文件从twitter
复制到new_twitter
,示例如下:
POST _reindex
{
"size": 10000,
"source": {
"index": "twitter",
"sort": { "date": "desc" }
},
"dest": {
"index": "new_twitter"
}
}
重建部分字段索引
源部分支持搜索请求中支持的所有元素(The source
section supports all the elements that are supported in a search request.)。概括下,可以只重建部分字段的索引,其余字段舍弃
例如,可以使用源过滤重新索引原始文档中的一部分字段,如下所示:
POST _reindex
{
"source": {
"index": "twitter",
"_source": ["user", "tweet"]
},
"dest": {
"index": "new_twitter"
}
}
支持脚本
脚本允许修改文档元数据
与_update_by_query
一样,_reindex
支持修改文档的脚本。 与_update_by_query
不同,允许脚本修改文档的元数据。 这个例子颠覆了源文档的版本(这个脚本意思是,foo字段值为bar时,重建索引时版本加一并移除foo字段
):
POST _reindex
{
"source": {
"index": "twitter"
},
"dest": {
"index": "new_twitter",
"version_type": "external"
},
"script": {
"inline": "if (ctx._source.foo == 'bar') {ctx._version++; ctx._source.remove('foo')}",
"lang": "painless"
}
}
脚本设置ctx.op
就像在_update_by_query
中一样,您可以设置ctx.op
来更改在目标索引上执行的操作:
空操作
如果脚本确定不必在目标索引中编制索引,请设置ctx.op =“noop”
。 这种无操作将在响应机构的noop计数器中报告( This no operation will be reported in the noop
counter in the response body)。
POST _reindex
{
"source": {
"index": "irl"
},
"dest": {
"index": "docker-cluster",
"version_type": "external"
},
"script": {
"inline": "if (ctx._source.columnName == '领导活动') {ctx.op = 'noop'}",
"lang": "painless"
}
}
返回数据:
{
"took": 181,
"timed_out": false,
"total": 626,
"updated": 0,
"created": 2,
"deleted": 0,
"batches": 1,
"version_conflicts": 0,
"noops": 624,
"retries": {
"bulk": 0,
"search": 0
},
"throttled_millis": 0,
"requests_per_second": -1,
"throttled_until_millis": 0,
"failures": []
}
删除
如果脚本确定必须从目标索引中删除文档,请设置ctx.op =“delete”
。 删除将在响应正文中的已删除计数器中报告(The deletion will be reported in the deleted
counter in the response body.)。
POST _reindex
{
"source": {
"index": "irl"
},
"dest": {
"index": "docker-cluster2"
},
"script": {
"inline": "if (ctx._source.columnName == '领导活动') {ctx.op = 'delete'}",
"lang": "painless"
}
}
结果:
{
"took": 103,
"timed_out": false,
"total": 626,
"updated": 0,
"created": 2,
"deleted": 624,
"batches": 1,
"version_conflicts": 0,
"noops": 0,
"retries": {
"bulk": 0,
"search": 0
},
"throttled_millis": 0,
"requests_per_second": -1,
"throttled_until_millis": 0,
"failures": []
}
将ctx.op设置为其他任何内容都是错误的。 在ctx中设置任何其他字段是错误的。
(上面的内容概括下,ctx.op只允许设置为noop或delete,作用是重建索引时符合要求的文档不做任何操作(noop)或删除(delete),并不会重建索引,这些文档的数量会在返回值中展示
)
修改核心元数据值
想想可能性! 小心点! 影响很大… 你可以改变(Think of the possibilities! Just be careful! With great power…. You can change这段没太懂,后续再补充
):
- _id
- _type
- _index
- _version
- _routing
- _parent
将_version设置为null或从ctx映射中清除它就像不在索引请求中发送版本一样。 无论目标版本或您在_reindex请求中使用的版本类型如何,都会导致该文档被覆盖在目标索引中。
默认情况下,如果_reindex看到带有路由的文档,则除非脚本更改了路由,否则将保留路由。 您可以在dest请求上设置路由以更改此设置:
保持(keep
)
将针对每个匹配发送的批量请求的路由设置为匹配上的路由。 默认。
丢弃(discard
)
将针对每个匹配发送的批量请求的路由设置为null。
= <某些文字>(=<some text>
)
将针对每个匹配发送的批量请求的路由设置为=之后的所有文本。
例如,您可以使用以下请求将源索引source
中的所有文档与公司名称cat
复制到目标索引dest
,并将路由设置为cat
。
POST _reindex
{
"source": {
"index": "source",
"query": {
"match": {
"company": "cat"
}
}
},
"dest": {
"index": "dest",
"routing": "=cat"
}
}
默认情况下,_reindex使用1000的滚动批次。您可以使用source元素中的size字段更改批量大小:
POST _reindex
{
"source": {
"index": "source",
"size": 100
},
"dest": {
"index": "dest",
"routing": "=cat"
}
}
Reindex还可以通过指定如下管道来使用“摄取节点”功能(Reindex can also use the Ingest Node feature by specifying a pipeline like this:):
POST _reindex
{
"source": {
"index": "source"
},
"dest": {
"index": "dest",
"pipeline": "some_ingest_pipeline"
}
}
从远程地址重建索引
Reindex支持从远程Elasticsearch集群重建索引:
POST _reindex
{
"source": {
"remote": {
"host": "http://otherhost:9200",
"username": "user",
"password": "pass"
},
"index": "source",
"query": {
"match": {
"test": "data"
}
}
},
"dest": {
"index": "dest"
}
}
host参数必须包含空间,主机和端口(例如https:// otherhost:9200)。用户名和密码参数是可选的,当它们存在时,reindex
将使用基本身份验证连接到远程Elasticsearch节点。使用基本身份验证时务必使用https
,否则密码将以纯文本格式发送。
必须使用reindex.remote.whitelist
属性在elasticsearch.yaml
中将远程主机明确列入白名单。它可以设置为允许的远程主机和端口组合的逗号分隔列表(例如otherhost:9200,另一个:9200,127.0.10。:9200,localhost:)。白名单忽略Scheme - 仅使用主机和端口。
此功能适用于您可能会找到的任何Elasticsearch版本的远程集群。这应该允许您通过从旧版本的群集重新索引从任何版本的Elasticsearch升级到当前版本。
要启用发送到旧版Elasticsearch的查询,请将查询参数直接发送到远程主机,而不进行验证或修改。