ElasticSearch中的Index一旦建立, 里面的Field类型就不可以再更改. 例如, 你不能把一个int类型的字段, 改为string类型. 否则该字段中的数据将失效. 那么如何解决这个问题呢? 答案就是重新建立索引(Reindex).
本文演示一下如何将以下旧的index中的数据以零停机的方式迁移到新的Index中.
旧Index: mail-w3svc1-2020.06.09
新Index: mail-w3svc1-2020.06.09-v2
1, 创建一个template, 指定新Index的mapping内容
curl -XPUT 127.0.0.1:9200/_template/mail-test -H 'Content-Type: application/json' -d'{ "index_patterns": ["mail-w3svc1-2020.06.09-v2"], "settings" : { "index.refresh_interval": "10s", "number_of_shards": 1, "number_of_replicas": 0, "index.translog.durability": "request", "index.translog.sync_interval": "30s" }, "mappings": { "properties": { "rt": { "type": "integer" }, "status": { "type": "integer" }, "sub_status": { "type": "integer" } } }, "order" : 5 }'
2, 创建新Index
curl -XPUT 127.0.0.1:9200/mail-w3svc1-2020.06.09-v2 # 查看之 curl -XGET 127.0.0.1:9200/mail-w3svc1-2020.06.09-v2?pretty=true
3, 创建alias指向旧的Index(本例中的alias名为mail-w3svc1-2020.06.09-alt)
curl -XPOST localhost:9200/_aliases -H 'Content-Type: application/json' -d '{ "actions": [ { "add": { "index": "mail-w3svc1-2020.06.09", "alias": "mail-w3svc1-2020.06.09-alt" } } ] }'
4, 将logstash中的数据output指向alias的名称
此部分内容略过.
5, 执行REINDEX操作, 将旧Index的数据导入新Index
curl -X POST "localhost:9200/_reindex?pretty" -H 'Content-Type: application/json' -d'{ "source": { "index": "mail-w3svc1-2020.06.09" }, "dest": { "index": "mail-w3svc1-2020.06.09-v2" } }'
如果数据量比较大, 可能要导入较久的时间, 此时就等着吧.
6, 修改alias, 将alias指向新Index
curl -X POST "localhost:9200/_aliases" -H 'Content-Type: application/json' -d'{ "actions": [ { "remove": { "index": "mail-w3svc1-2020.06.09", "alias": "mail-w3svc1-2020.06.09-alt" }}, { "add": { "index": "mail-w3svc1-2020.06.09-v2", "alias": "mail-w3svc1-2020.06.09-alt" }} ] }'
参考文档:
https://www.elastic.co/cn/blog/changing-mapping-with-zero-downtime