ES索引库的别名的使用--不停服实现索引库的重建切换

ES 的别名不停停服切换索引,线上发布

场景: 我们现在线上正在使用 ES索引库 V , 没有使用ES索引库别名
两个问题 :

  1. 现在由于字段更新, 把线上的数据重新写入了V1库, 现在如何在不断服的情况下,完美的实现 从V 切换到V1 索引库?
  2. 后续如果再次重建索引V2 , 如何从V1 切换到V2
为什么使用ES索引库别名

ES 为我们提供了别名的概念 aliases,也就是我们在生成一个索引的时候,比如叫 my_index_v1,我们是可以做一个别名 my_name 指向它。

  • 当我们在查询 my_name 的时间时,实际上查询是 my_index_v1 这个索引的数据。
  • 业务系统去查询时直接使用 my_index 去做查询,当后台字段发生变化,或者字段类型发生变化时,我们就可以再生成一个新的 my_index_v2 。
  • 把 my_index_v1 的数据 导入到 my_index_v2 中
  • 最后删除 my_index 对于 my_index_v1 的指向,
  • 重新把 my_index 指向到 my_index_v2 。

在这个过程中,应用系统在切换完成前查询的旧数据,切换后查询的是新数据,应用就可以做到不停机,完美切换

实战第一个问题 我们如何从没别名 从V索引库 切换到 V1 索引库

我们线上现在master 代码是使用的 master 代码, 而且线上库是没有 索引别名的
所以 线上是通过代码中写死索引库名 V 去实现ES的增删改查的
第一次从V 切换到 V1 如何操作?

1.1 新建V1 索引库

新建V1库, 把线上数据 全部写入 V1库, 这个是同步的, 写完后 比如现在是 8:00, 这时候数据是V1
写完上线后, 已经是 12:00了, 这期间 V1的数据是没变化的
如果线上数据有变化, 需要增量同步下 你8:00-12:00 上线期间 过程中的增量数据 也要同步到 V1库

构建V1的 mappings 结构, 构建索引库V1

PUT /my_v1
{
    "settings": {
        "number_of_shards": 3,
        "number_of_replicas": 2,
        "analysis": {
            "analyzer": {
                "ik": {
                    "tokenizer": "ik_max_word"
                }
            }
        }
    },
  "mappings": {
    "_doc": {
      "dynamic": "strict",
      "_all": {
        "enabled": false
      },
      "properties": {
        "_class": {
          "type": "keyword"
        },
        "addTime": {
          "type": "integer"
        },
        "userid": {
          "type": "keyword"
        }
        }
  }
1.2 给V1库新建别名
  • V1新建索引别名 alias_xx , 这时候 别名 alias_xx 指向了 V1索引库, 对V1新建别名对 线上master的版本 线上数据 V 是没有任何影响
  • 线上数据依旧 通过代码的 V 的索引库 写入, 所以不影响
  • 此刻我们的 代码是dev分支, dev分支已经修改,使用的es索引库的别名 my_index_name_alias
#创建别名,允许通过别名 my_index_name_alias 写入es数据
POST /_aliases 
{ 
  "actions": [ 
    { 
      "add": {  //设置 v1为索引库 创建别名 my_index_name_alias 的数据写入转发对象 
        "index": "my_v1", 
        "alias": "my_index_name_alias", 
        "is_write_index":true 
      } 
    } 
  ] 
}

# 检查 别名指向哪个索引库
GET /*/_alias/my_index_name_alias
1.3 dev开发分支 使用V1库的别名my_index_name_alias 去增删改查操作es索引库
  • 此刻 dev分支可以发布到测试环境
  • 代码分支 dev 可以通过 别名 my_index_name_alias 去操作索引库 V1 , 这个逻辑是通的, 因为 代码及索引库 都是通过别名去访问的, 所以是没问题的
  • 跟线上的 ES索引库 V 和 master代码 是没有任何关联的
  • 测试环境正常操作, 写入ES库,更新, 测试没问题后, 就可以去发布线上了
1.4 dev分支上线
  • dev分支上线 合并到master代码, master就从V 切换到 V1库了
  • master代码上线后, 测试没问题后, 此时 master 及 ES索引库 都是通过 别名访问的 V1
  • 发布后,线上测试没问题

这时 我们线上 全都使用了别名去操作ES库了, 代码中也都是通过别名去操作ES库 V1了, 别名通过 指向 V1 , 实际上操作的就是V1数据存储库

第二个问题 如何从V1 切换到V2

后续我们ES索引库 结构又变了变成V2的结构, 我们要如何从V1切换到V2

  • 新创建一个索引my_v2_xx,数据结构是新的结构
  • 将 my_v1 的数据同步到my_v2_xx
  • 删除my_v1的别名
  • 新增my_v2_xx
  • 测试无误后, 删除原索引库 my_v1
2.1 修改别名指向

ES解除索引别名指向
把 my_index_name_alias 的指向 从 V1 ES索引库删除, 然后添加 别名指向 V2索引库

#删除原名字,设置新名字
POST _aliases
{
  "actions": [
    {
      "remove": {
        "index": "my_v1",
        "alias": "my_index_name_alias"
      }
    },
    {
      "add": {
        "index": "my_v2_xx",
        "alias": "my_index_name_alias"
      }
    }
  ]
}
 
2.2 检查当前索引指向
# 检查 别名指向哪个索引库
GET /*/_alias/my_index_name_alias

你可能感兴趣的:(ElasticSearch,1024程序员节)