在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裏面別名的功能和做用並講解了如何使用別名,若是咱們的索引不肯定將來如何使用時,給索引加一個別名是一個不錯的選擇。