Press "Enter" to skip to content

ElasticSearch中修改Field的Type

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

Leave a Reply

Your email address will not be published. Required fields are marked *