Elastic Stack 6.0 已经正式发布了,包含了很多激动人心的特性,相信有一些特性也是你非常感兴趣的,所以要不要考虑升级到最新的 6.0 版本呢?
关于版本升级,有很多种办法可以做到,这次 Advent 活动的第一篇,Mark Walkom 已有提及。原地升级固然速度很快,但是索引格式还是旧格式,数据结构依然还是旧的,无法应用新的特性,故无法发挥新版本的威力,
迁移任务
所以今天我就来说说如果使用 reindex
API 来进行 Elasticsearch 集群数据的迁移。假设新的集群 IP 为 127.0.0.1
,旧数据所在集群为: 192.168.3.213
,我们要迁移的索引名是:medcl
,里面有一些数据,今天的任务就是将这些数据从旧集群迁移到新的集群。
首先,假设我们已经部署好了新的 Elasticsearch 6.0 的集群,具体部署的细节这里就不展开了,这里有详细的文档。
前提准备
因为我们的新集群需要访问旧集群的数据,首先需要修改新集群的 Elasticsearch 配置文件,设置我们要访问的集群的白名单,打开 Elasticsearch (127.0.0.1:9200
) 的配置文件:config/elasticsearch.yml
,新增一行配置:
reindex.remote.whitelist: ["192.168.3.213:9200"]
新的集群每个节点都进行同样的修改,我们这里只有一个节点,修改并重启 Elasticsearch 使配置文件生效即可。
设置新索引
将一个索引从旧的集群迁移到新的集群,需要考虑的因素很多,强烈建议使用升级助手(Upgrade Assistant)进行更加详细的检测,你需要安装 Kibana 和 X-Pack 插件,这里就不具体介绍了。
关于新的 6.0 接口是否兼容你之前的旧的业务调用代码,请进一步进行测试,在这里只考虑数据的迁移。
导入数据之前,你需要手动配置好新索引的 settings
和 mapping
信息,这里有个小技巧就是可以先从旧的索引里面获得旧的索引设置,然后再创建到新的索引里面。
在 192.168.3.213:9200
上执行
GET medcl/_settings
返回的内容是:
{
"medcl": {
"settings": {
"index": {
"number_of_shards": "5",
"provided_name": "medcl",
"creation_date": "1512449188767",
"analysis": {
"analyzer": {
"pinyin_analyzer": {
"tokenizer": "my_pinyin"
}
},
"tokenizer": {
"my_pinyin": {
"lowercase": "true",
"keep_original": "true",
"remove_duplicated_term": "true",
"keep_separate_first_letter": "false",
"type": "pinyin",
"limit_first_letter_length": "16",
"keep_full_pinyin": "true"
}
}
},
"number_of_replicas": "1",
"uuid": "Rs0tTFibQSuqBVQ5xokyPQ",
"version": {
"created": "6000099"
}
}
}
}
}
我们可以返回的结果基础上,移除最为层的 medcl
节点,去除 UID
等版本信息,保留 analysis
信息。
同时为了提高速度,我们还可以将分片数的设置大一点,后面可以执行 shrink
操作合并分片,另外再设置副本是为0
,同时可以禁用refresh
,目的都是为了提高索引速度。
然后在最新的集群上面执行下面的索引创建操作,如下:
在 127.0.0.1:9200
上执行
PUT medcl
{
"settings": {
"index": {
"number_of_shards": 10,
"analysis": {
"analyzer": {
"pinyin_analyzer": {
"tokenizer": "my_pinyin"
}
},
"tokenizer": {
"my_pinyin": {
"lowercase": "true",
"keep_original": "true",
"remove_duplicated_term": "true",
"keep_separate_first_letter": "false",
"type": "pinyin",
"limit_first_letter_length": "16",
"keep_full_pinyin": "true"
}
}
},
"number_of_replicas": 0,
"refresh_interval":-1
}
}
}
当然还有一些其他层面关于索引的优化,这里就不展开了,感兴趣的可以进一步了解。
下面继续进行 mapping
的导入。
在 192.168.3.213:9200
上执行
GET medcl/_mapping
返回结果为即为 mapping
信息。
{
"medcl": {
"mappings": {
"folks": {
"properties": {
"name": {
"type": "keyword",
"fields": {
"pinyin": {
"type": "text",
"boost": 10,
"term_vector": "with_offsets",
"analyzer": "pinyin_analyzer"
}
}
}
}
}
}
}
}
从 6.0 开始,我们只允许一个 type 了,我们可以随手重命名新的 type 为 doc
,如果你的查询里面使用了_type
字段,也需要注意进行相应的调整,我们现在基于旧的 mapping (这里只需要保留 properties
节点)修改之后的新的 mapping 在新的集群上面 127.0.0.1
创建 mapping:
在 127.0.0.1:9200
上执行
PUT medcl/doc/_mapping
{
"properties": {
"name": {
"type": "keyword",
"fields": {
"pinyin": {
"type": "text",
"boost": 10,
"term_vector": "with_offsets",
"analyzer": "pinyin_analyzer"
}
}
}
}
}
开始导入
新的 settings
和 mapping
导入好了之后,就可以开始进行数据的导入了,这里自然就要用到我们的 reindex
API 了。
在 127.0.0.1:9200
上执行
POST _reindex
{
"source": {
"remote": {
"host": "http://192.168.3.213:9200"
},
"index": "medcl"
},
"dest": {
"index": "medcl",
"type":"doc"
}
}
注意,如果旧索引服务器需要身份认证(比如安装了 X-Pack),记得加上对应的用户名和密码信息,source
和 target
即分别是旧索引和新索引的名称,假如你愿意,完全可以相同,这里都是 medcl
。
如果你的数据比较多,这里有个小技巧,就是在 URL 的参数里面加上 wait_for_completion=false
,这样 reindex 会在后台继续执行任务。
处理多个 Type
Elasticsearch 从 6.0 开始,不支持多个 type
了,所以如果你的旧索引有多个 type
的话,这样直接 reindex 会失败的。
怎么解决呢?这里有个小技巧就是可以分别按 type
来进行导入,reindex 支持查询条件来过滤要导入的数据,也就是一个 type
一个新索引,同样记得先创建好索引并进行相应的 setting 和 mapping 设置。
POST _reindex
{
"source": {
"remote": {
"host": "http://192.168.3.213:9200",
"username": "user",
"password": "pass"
},
"index": "source",
"query": {
"match": {
"_type": "type1"
}
}
},
"dest": {
"index": "new-index-type1"
}
}
最后的操作
OK, 到这里我们的数据就导入完毕了,你还需要开启 refresh
和恢复副本等操作。
在 127.0.0.1:9200
上执行
PUT medcl/_settings
{
"settings": {
"index": {
"number_of_replicas": 1,
"refresh_interval":"1s"
}
}
}
reindex 还有一些阈值等参数可以通过设置,具体的可以参照 reindex
API 的文档。
另外你可能还希望执行 shrink
操作合并分片数,这里是文档。
写在最后
本文是 Elastic Advent Calendar 的第 8 篇,主要介绍了如果使用 reindex
API 来进行数据的迁移,将旧集群的数据迁移到最新的 6.0 集群,希望对你有帮助。