在elasticsearch里面给index起一个aliases(别名)能很是优雅的解决两个索引无缝切换的问题,这个功能在某些场景下很是使用。java
好比电商的核心商品索引库,除了实时增量数据外,天天都要重建一遍索引,避免index里面的数据和db里面的数据不一致,由于index分shard了,因此要一个一个的shard作全量替换,直到全部的shard替换完毕,才能宣布重建成功。整个过程其实仍是风险挺大的,虽然每次只替换一个shard把风险量降到最低,但若是第3个或第4个shard重建有问题,有可能要回滚整个索引,这个问题其实用索引别名的问题就能比较优雅的解决。数据库
旧索引称为a,新索引称为b,他们拥有共同的别名c,而dao层查询的索引名也是c,当新的全量索引b重建完成以后,只须要解除旧索引a与别名c关系,而后添加新索引b与别名c的关系,就能完成无缝切换,中间对用户是无感知的,若是b有问题,那么随时均可以从新解除b的关系并恢复a,这就完成了所谓的回滚操做,很是简单优雅。api
在es里面index aliases就像是软链接同样,它能够映射一个或多个索引,提供了很是灵活的特性,使用它咱们能够作到:elasticsearch
(1)在一个运行中的es集群中无缝的切换一个索引到另外一个索引上ui
(2)分组多个索引,好比按月建立的索引,咱们能够经过别名构造出一个最近3个月的索引code
(3)查询一个索引里面的部分数据构成一个相似数据库的视图(views)索引
es里面操做索引别名的有两个api命令:rem
_alias 执行单个别名操做 _aliases 原子的执行多个别名操做
如何使用?io
假设咱们有两个索引分别是my_index_v1和my_index_v2如今想经过索引别名来实现无缝切换,他们对外的索引别名叫my_index。ast
首先咱们先建立第一个old index并给你添加aliases
PUT /my_index_v1 //构建索引 PUT /my_index_v1/_alias/my_index //给索引添加别名
建立完成以后,咱们能够查询一下他们的关系:
GET /*/_alias/my_index //查某个别名映射的全部index GET /my_index_v1/_alias/* //查询某个index拥有的别名
返回结果以下:
{ "my_index_v1" : { "aliases" : { "my_index" : { } } } }
如今咱们构建new index:
PUT /my_index_v2 //构建索引
新索引构建完毕以后,咱们就能够执行切换操做命令了:
POST /_aliases { "actions": [ { "remove": { "index": "my_index_v1", "alias": "my_index" }}, { "add": { "index": "my_index_v2", "alias": "my_index" }} ] }
上面的操做是顺序的执行的,先接触old index的别名,而后给new index 添加新的别名,这样以来 索引就透明的别切换了,用户不会感受任何变化,并且也不须要停机操做。
下面看下java api里面如何操做:
(1)添加别名
client.admin().indices().prepareAliases().addAlias("my_index_v1","my_index");
(2)移除别名
client.admin().indices().prepareAliases().removeAlias("my_index_v1","my_index");
(3)删除一个别名后再添加一个
client.admin().indices().prepareAliases().removeAlias("my_index_v1","my_index") .addAlias("my_index_v2","my_index").execute().actionGet();
当别名添加完毕后,咱们在删除,搜索,更新均可以直接使用:
SearchRequestBuilder search=client.prepareSearch("my_index");
有一点须要注意使用别名后,type类型的值不须要在填写,若是你填写了es是会抛异常的,由于它认为你这别名是一个新的索引,因此咱们只写index name便可,es服务端知道它的类型。
总结:
本文介绍了es里面别名的功能和做用并讲解了如何使用别名,若是咱们的索引不肯定将来如何使用时,给索引加一个别名是一个不错的选择。