ElasticSearch 筆記-別名

年終了,清理一下自己的OneNote,把筆記遷移到博客上來。

索引別名Aliases問題

業務問題

業務需求是不斷變化迭代的,也許我們之前寫的某個業務邏輯在下個版本就變化了,我們可能需要修改原來的設計,例如數據庫能需要需要添加或刪減一個字段,而在搜索中也會發生這件事,即使你認爲現在的索引設計已經很完美了,在生產環境彙總,還是有可能需要做一些修改的,需要添加映射字段或者需要修改字段類型等等。
數據庫中我們可以直接修改原來的表設計語句,前提是需要做好數據遷移。但是在Elasticsearch中就沒有那麼簡單了。儘管可以增加新的類型到索引中,或者增加新的字段到類型中,但是不能添加新的分析器或者對現有的字段做改動。如果你那麼做的話,結果就是那些已經被索引的數據就不正確,搜索也不能正常工作。針對這個問題必須重新建立索引。

別名定義

重新建立索引的問題是必須更新應用中的索引名稱,索引別名就是用來解決這個問題的!
假設我們有個學生的原始索引 student_index_v1,我們給它起個別名 student_index,程序中也是用別名 student_index 進行搜索,當我們的業務需求發生改變需要修改索引的時候,我們重新創建個索引 student_index_v2,同時將別名 student_index 指向新的索引 student_index_v2,同時將 student_index_v1 的數據遷移到新的 student_index_v2,這樣我們就可以做到在零停機下從舊索引切換到新索引。
索引別名就像一個快捷方式或軟連接,可以指向一個或多個索引,也可以給任何一個需要索引名的API來使用,而且別名不能與索引同名。
別名帶給我們極大的靈活性,允許我們做下面這些:
• 在運行的集羣中可以無縫的從一個索引切換到另一個索引。
• 給多個索引分組。
• 給索引的一個子集創建視圖。

別名管理

別名還可以映射到某個索引也可以映射到多個索引。別名還可以與篩選器關聯,篩選器將在搜索和路由值時自動應用,別名不能與索引同名。
Elasticsearch 中有兩種方式管理別名: _alias 用於單個操作, _aliases 用於執行多個原子級操作。

單個索引別名

POST /_aliases { "actions" : [ { "add" : { "index" : "test1", "alias" : "alias1" } } ] }

刪除別名

POST /_aliases { "actions" : [ { "remove" : { "index" : "test1", "alias" : "alias1" } } ] }

重命名別名

POST /_aliases { "actions" : [ { "remove" : { "index" : "test1", "alias" : "alias1" } }, { "add" : { "index" : "test2", "alias" : "alias1" } } ] }

重命名別名是一個簡單的刪除然後指向新的索引。這個操作是原子性的,因此不需要擔心短時間內的別名不指向一個索引。

將別名與多個索引關聯

POST /_aliases { "actions" : [ { "add" : { "index" : "test1", "alias" : "alias1" } }, { "add" : { "index" : "test2", "alias" : "alias1" } } ] }

也可以通過索引數組的方式來實現

POST /_aliases { "actions" : [ { "add" : { "indices" : ["test1", "test2"], "alias" : "alias1" } } ] }

對於上面的示例,還可以使 glob pattern 將別名關聯到擁有公共名稱的多個索引:

POST /_aliases { "actions" : [ { "add" : { "index" : "test*", "alias" : "all_test_indices" } } ] }

Filtered Aliases
過濾器別名提供了一個簡單的方法對同一個索引來創建不同的“視圖”。過濾器能夠使用Query DSL來定義並且被應用到所有的搜索,統計,通過查詢刪除和其它類似的行爲。
爲了創建一個帶過濾器的別名,首先需要確保映射的字段已經存在於mapping中。

PUT /test1 { "mappings": { "_doc": { "properties": { "user" : { "type": "keyword" } } } } }

然後我們可以創建一個在user字段上帶過濾器的別名。

POST /_aliases { "actions" : [ { "add" : { "index" : "test1", "alias" : "alias2", "filter" : { "term" : { "user" : "kimchy" } } } } ] }

這樣設置之後,我們通過 test1 這個 index 直接進行搜索可以看到索引的全部文檔,但是通過 alias2 這個別名就只能看到符合過濾器過濾後的結果了,即只有一個 user 爲 "kimchy" 的結果。
Routing
可以將路由值與別名關聯。這個特性可以與過濾別名一起使用,以避免不必要的碎片操作。
何爲路由?
所有的文檔 API( get 、 index 、 delete 、 bulk 、 update 以及 mget )都接受一個叫做 routing 的路由參數 ,通過這個參數我們可以自定義文檔到分片的映射。一個自定義的路由參數可以用來確保所有相關的文檔—例如所有屬於同一個用戶的文檔都被存儲到同一個分片中。

以下命令創建一個指向索引 test 的新別名 alias1。創建 alias1 後,所有具有此別名的操作將自動修改爲使用值 1 進行路由:

POST /_aliases { "actions" : [ { "add" : { "index" : "test", "alias" : "alias1", "routing" : "1" } } ] }

還可以爲搜索和索引操作指定不同的路由值
如上例所示,搜索路由(search_routing)可能包含幾個用逗號分隔的多個值,但是 索引路由(index_routing)就只能包含一個值。
如果使用路由別名的搜索操作也有路由參數,則使用搜索別名路由和參數中指定的路由的交集。例如,下面的命令將使用“2”作爲路由值。因爲搜索操作中有路由參數2,3,而搜索路由設置的是1,2,所以取交集即爲2。

別名示例
仍然以上面學生的例子, student_index 是一個指向當前真實索引的別名。真實索引包含一個版本號: student_index_v1 , student_index_v2 等等。
首先,創建索引 student_index_v1 ,然後將別名 student_index 指向它:

// 創建索引 student_index_v1 。 PUT /student_index_v1 
//設置別名 student_index 指向 student_index_v1 。 PUT /student_index_v1/_alias/student_index 

你可以檢測這個別名指向哪一個索引:

GET /*/_alias/student_index

GET /student_index_v1/_alias/*

然後,我們決定修改索引中一個字段的映射。當然,我們不能修改現存的映射,所以我們必須重新索引數據。 首先, 我們用新映射創建索引 student_index_v2 :

PUT /student_index_v2 { "mappings": { "my_type": { "properties": { "tags": { "type": "string", "index": "not_analyzed" } } } } }

然後我們將數據從 student_index_v1 索引到 student_index_v2 ,下面的過程在重新索引你的數據 中已經描述過。一旦我們確定文檔已經被正確地重索引了,我們就將別名指向新的索引。
一個別名可以指向多個索引,所以我們在添加別名到新索引的同時必須從舊的索引中刪除它。這個操作需要原子化,這意味着我們需要使用 _aliases 操作:

POST /_aliases { "actions": [ { "remove": { "index": "student_index_v1", "alias": "student_index" }}, { "add": { "index": "student_index_v2", "alias": "student_index" }} ] }

經過以上幾步操作,你的應用就成功在零停機的情況下從舊索引遷移到新索引了。其實別名還有更多管理的語法。
文檔遷移
對於新舊索引的文檔數據遷移,字段 _source 的一個優點是在Elasticsearch中已經有整個文檔。你不必從源數據中重建索引,而且那樣通常比較慢。
爲了有效的重新索引所有在舊的索引中的文檔,用 scroll 從舊的索引檢索批量文檔 , 然後用 bulk API 把文檔推送到新的索引中。
對現有數據的這類改變最簡單的辦法就是重新索引:用新的setting創建新的索引並把文檔從舊的索引複製到新的索引。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章