Elastic Search不停机重建索引-修改映射类型

说明

由于 ES 的 mapping 不能修改类型,所以需要这种方式实现 不停机 修改类型

创建索引并使用

  1. 创建 blog_v1
  2. 创建 blog_v1 的别名 blog
  3. java代码中都是使用 索引 别名 ,而不是使用真正的索引名

修改索引 mapping

  1. 需要修改 mapping 类型时,就新建索引 blog_v2
  2. 将 原数据迁移到 blog_v2 中
  3. 原子级 删除原别名,创建 新索引 blog_v2 的别名,新别名 与 原别名相同

准备

现有索引名为:blog_v1(索引名一般含版本号),代表索引 blog 的第一个版本,其别名为 blog

创建映射:

PUT /blog_v1
{
  "mappings": {
    "properties": {
      "title": {
        "type": "text"
      },
      "content": {
        "type": "text"
      },
      "author": {
        "type": "keyword"
      },
      "like": {
        "type": "integer"
      },
      "date": {
        "type": "date"
      }
    }
  }
}

执行结果:

{
  "acknowledged" : true,
  "shards_acknowledged" : true,
  "index" : "blog_v1"
}

添加一条测试数据

post /blog_v1/_doc
{
  "title":"java从入门到精通"
}

创建别名

PUT /blog_v1/_alias/blog

执行结果:

{
  "acknowledged" : true
}

注意

java代码中都是通过该 别名 进行增删改查操作

查询索引拥有的别名

GET /blog_v1/_alias/*

执行结果:

{
  "blog_v1" : {
    "aliases" : {
      "myblog" : { }    //别名
    }
  }
}

重建步骤

第一步

创建索引 blog_v2 (该索引的mapping需要与blog_v1基本保持一致,除了要修改的字段mapping)

PUT /blog_v2
{
  "mappings": {
    "properties": {
      "title": {
        "type": "text"
      },
      "content": {
        "type": "text"
      },
      "author": {
        "type": "text"            //将作者也修改为全文检索
      },
      "like": {
        "type": "integer"
      },
      "date": {
        "type": "date"
      }
    }
  }
}

执行结果:

{
  "acknowledged" : true,
  "shards_acknowledged" : true,
  "index" : "blog_v2"
}

第二步

把 blog_v1 的数据导入 blog_v2 索引中

POST _reindex
{
    "source":{
        "index":"blog_v1"
    },
    "dest":{
        "index":"blog_v2"
    }
}

执行结果:

{
  "took" : 8,
  "timed_out" : false,
  "total" : 1,                //总共迁移1条
  "updated" : 0,
  "created" : 1,
  "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,
  "failures" : [ ]
}

第三步

把 blog_v1 别名删除并且同时为 blog_v2 添加别名 blog(此时线上程序已经切换到 blog_v2数据源上了)

代码
POST /_aliases
{
  "actions": [
    {
      "remove": {
        "index": "blog_v1",
        "alias": "blog"
      }
    },
    {
      "add": {
        "index": "blog_v2",
        "alias": "blog"
      }
    }
  ]
}

执行结果:

{
  "acknowledged" : true
}
查看 blog_v1 索引别名
GET /blog_v1/_alias/*

结果如下:

{ }

没有别名

查看 blog_v1 索引别名
GET /blog_v2/_alias/*

结果如下:

{
  "blog_v2" : {
    "aliases" : {
      "blog" : { }
    }
  }
}

索引 blog_v2 别名是 blog

第四步

再次执行第二步骤,目的是增量同步 blog_v1 中修改但没有同步到 blog_v2 中的数据(因为在做第二、三步的时候很可能线上的 blog_v1 索引数据发生修改了)

感谢:https://blog.csdn.net/xingdianp/article/details/110994412


原文出处:/show_1IX1ogV3uEVI.html