[TOC]

elasticsearch使用时间长了后,总是有各种原因重建索引,但是ES是不支持索引字段类型变更的,原因是一个字段的类型进行修改之后,ES会重新建立对这个字段的索引信息,影响到ES对该字段分词方式,相关度,TF/IDF倒排创建等。网上有很多不停止服务的情况下使得ES索引字段类型变更的文章,本文基于elasticsearch 7.12的版本记录下重建索引的步骤

索引重建的步骤

  1. 创建oldindex
  2. 给索引创建别名
  3. 向oldindex中插入9条数据
  4. 创建新的索引newindex
  5. 重建索引
  6. 实现不重启服务索引的切换

创建oldindex

curl -H "Content-type: application/json" -XPUT "http://localhost:9200/oldindex" -d'
{
    "mappings": {
        "properties": {
            "name" : {
                "type": "text"
            },
            "price" : {
                "type": "double"
            }
        }
    }
}'

给索引创建别名

curl -H "Content-type: application/json" -XPUT "http://localhost:9200/oldindex/_alias/alias_oldindex"

向oldindex中插入9条数据

curl -H "Content-type: application/json" -XPOST "http://localhost:9200/alias_oldindex/_doc/_bulk" -d'
{"create":{"_id":1}}
{"name":"name 01","price":1}
{"create":{"_id":2}}
{"name":"name 02","price":2}
{"create":{"_id":3}}
{"name":"name 03","price":3}
{"create":{"_id":4}}
{"name":"name 04","price":4}
{"create":{"_id":5}}
{"name":"name 05","price":5}
{"create":{"_id":6}}
{"name":"name 06","price":6}
{"create":{"_id":7}}
{"name":"name 07","price":7}
{"create":{"_id":8}}
{"name":"name 08","price":8}
{"create":{"_id":9}}
{"name":"name 09","price":9}
'

创建新的索引newindex

curl -H "Content-type: application/json" -XPUT "http://localhost:9200/newindex" -d'
{
    "mappings": {
        "properties": {
            "name" : {
                "type": "text"
            },
            "price" : {
                "type": "double"
            }
        }
    }
}'

重建索引

  • 数据量大的话可以异步执⾏,如果 reindex 时间过⻓,建议加上 wait_for_completion=false 的参数条件,这样 reindex 将直接返回 taskId

    curl -H "Content-type: application/json" -XPOST "http://localhost:9200/_reindex?wait_for_completion=false" -d'
    {  
      "size": 5, // 表示只获取5条数据插入到新的索引中
      "conflicts": "proceed", // 如果新的索引中数据冲突,程序继续往下执行,删除程序会终止
      "source": {
          "size": 2, // 默认情况下,_reindex使用1000进行批量操作,调整批量插入2条
          "index": "oldindex", // 表示从oldindex,类型product中查询出price字段的值
          "_source": ["price"],
          "query": {
              "range": {
                  "price": {
                      "gte": 2,
                      "lte": 8
                  }
              }
          }
      }, 
      "dest": {
          "index": "item_new_index", // 表示数据插入新索引newindex中
          "op_type": "create", // 数据插入的类型为创建,如果存在就会版本冲突
          "routing": "=routingvalue" // 数据插入时以什么值做路由
      }
    }'
  • 通过返回taskId,查询reIndex进度

    # {"task":"lJu4zixnS46ezdyKi8vqKw:630107100"}
    # 从异步获取taskid为lJu4zixnS46ezdyKi8vqKw:630107100
    # GET _tasks?actions=*reindex&wait_for_completion=true&timeout=10s
    curl "http://localhost:9200/_tasks/lJu4zixnS46ezdyKi8vqKw:630107100"
  • 取消reIndex任务

    # POST _tasks/_cancel?nodes=nodeId1,nodeId2&actions=*reindex
    curl -H "Content-type: application/json" -XPOST "http://localhost:9200/_tasks/lJu4zixnS46ezdyKi8vqKw:630107100/_cancel"

实现不重启服务索引的切换

curl -H "Content-type: application/json" -XPOST "http://localhost:9200/_aliases" -d'
{
  "actions": [
    {
      "remove": {
        "index": "oldindex",
        "alias": "alias_oldindex"
      }
    },
    {
      "add": {
        "index": "newindex",
        "alias": "alias_oldindex"
      }
    }
  ]
}'

删除旧索引

curl  -XDELETE "http://localhost:9200/oldindex"

通过给item_index索引增加新字段的方式实现索引字段类型变更

1.执行一下语句给item_index新增字段itemNo

PUT item_index/_mapping/_doc

{

    "properties": {

        "itemNo": {

            "type":   "keyword"

        }

    }

}

2.使用代码程序初始化字段itemNo,即将老的索引字段itemId值刷新到itemNo中

3.修改代码程序,使用itemNo代替itemId

4.itemId字段废弃不使用了但是会保留在item_index索引中

针对以上修改索引字段类型的方法修改考虑的点

1.进行以上操作的时候,建议先对索引建立快照备份。

2.如果item_index索引中文档很多,reindex操作会耗时比较久,耗费ES服务的资源,影响ES服务的的性能。

3.查询ES的磁盘空间是否足够reindex新的索引。

3.reindex过程中,原索引新增的数据,是没有被reindex过去,考虑到是否由数据丢失。

5.在reindex索引代价比较大的时候可以使用给索引新增字段的方式实现索引字段类型的变更。


m20082008m
5 声望2 粉丝