Elasticsearch索引別名、Filtered索引別名、Template
在使用elasticsearch的時候,經常會遇到需要淘汰掉歷史資料的場景。
為了方便資料淘汰,並使得資料管理更加靈活,我們經常會以時間為粒度建立索引,例如:
- 每個月建立一個索引:monthly-201709、monthly-201710、monthly-201711
- 每天建立一個索引:daily-20171015、daily-20171016、daily-20171017、daily-20171018
當不需要再繼續使用歷史資料的時候,我們就可以將索引刪除,釋放資源。
為了很好的支撐這個場景,需要使用到Elasticsearch裡的兩個東西,索引別名和Template。
- 索引別名:建立索引對外的統一檢視
例如,如果建立了上述類似的索引時間序列,在查詢的時候以wildcards的方式指定索引,例如index=monthly-*,或者index=daily-201710*。當然也可以使用索引別名index=monthly。
- Template:修改建立索引的預設配置
例如,你不想承擔定期去維護索引的風險和工作量,可以在插入資料時自動建立索引,Template可以提供自動建立索引時候的預設配置。
下面詳細解釋一下。
1、索引別名
一個索引別名就好比一個快捷方式(Shortcut)或一個符號連結(Symbolic Link),索引別名可以指向一個或者多個索引,可以在任何需要索引名的API中使用。使用別名可以給我們非常多的靈活性。它能夠讓我們:
- 在一個執行的叢集中透明地從一個索引切換到另一個索引
- 讓多個索引形成一個組,比如
last_three_months
- 為一個索引中的一部分文件建立一個檢視(View)
如何建立索引別名呢?
1)建立索引
我這裡建立audit-201710、audit-201711兩個索引
curl -XPOST "http://10.93.21.21:8049/kangaroo-201710?pretty"
curl -XPOST "http://10.93.21.21:8049/kangaroo-201711?pretty"
如果安裝了head,你可以在視覺化頁面看到
從索引資訊可以看到,我們沒有配置mapping和alias,shards和replicas也使用的預設值。
2)建立索引別名
curl -XPOST 'http://10.93.21.21:8049/_aliases' -d ' { "actions": [ {"add": {"index": "kangaroo-201710", "alias": "kangaroo"}}, {"add": {"index": "kangaroo-201711", "alias": "kangaroo"}} ] }'
這樣就對kangaroo-201710和kangaroo-201711建立了索引別名kangaroo,再看head視覺化
可以看到索引別名已經建立。
3)注意
寫:不能直接對索引別名進行寫入。所以在寫資料的時候,要直接使用普通索引。
讀:查詢,對索引別名進行查詢,查詢會透明的下發到別名下掛的所有索引執行,設定的路由也會隨之下發。
2、帶filtered的索引別名
對於同一個索引,例如zoo,我們如何給不同人看到不同的資料,即,所謂的多租戶。
假設索引zoo的資料有個欄位是group,group欄位記錄了該資料是那個“租戶”的。多租戶之間的資料應該是不可見的。
我們模擬一下這個場景
1)建立索引zoo
curl -XPOST "http://10.93.21.21:8049/zoo?pretty"
2)設定mappings
curl -XPOST "http://10.93.21.21:8049/zoo/animal/_mapping?pretty" -d '
{
"animal": {
"properties": {
"name": {"type": "string", index: "not_analyzed"},
"group": {"type": "string", index: "not_analyzed"}
}
}
}'
3)設定帶filter的別名
curl -XPOST "http://10.93.21.21:8049/_aliases?pretty" -d '
{
"actions": [
{
"add": {
"index": "zoo",
"alias": "zoo_animal_vegetarian",
"filter":{
"term":{
"group":"vegetarian"
}
}
}
},
{
"add": {
"index": "zoo",
"alias": "zoo_animal_carnivorous",
"filter":{
"term":{
"group":"carnivorous"
}
}
}
}
]
}'
通過head看一下
我們索引兩條資料進去
老虎-肉食
curl -XPUT 'http://10.93.21.21:8049/zoo/animal/1' -d '{
"name" : "tiger",
"group" : "carnivorous"
}'
兔子-素食
curl -XPUT 'http://10.93.21.21:8049/zoo/animal/2' -d '{
"name" : "rabbit",
"group" : "vegetarian"
}'
使用帶filter的索引查一下
素食的只有兔子
curl -XGET "http://10.93.21.21:8049/zoo_animal_vegetarian/_search?pretty"
{
"took" : 32,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"failed" : 0
},
"hits" : {
"total" : 1,
"max_score" : 1.0,
"hits" : [ {
"_index" : "zoo",
"_type" : "animal",
"_id" : "2",
"_score" : 1.0,
"_source":{
"name" : "rabbit",
"group" : "vegetarian"
}
} ]
}
}
肉食的只有老虎
curl -XGET "http://10.93.21.21:8049/zoo_animal_carnivorous/_search?pretty"
{
"took" : 33,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"failed" : 0
},
"hits" : {
"total" : 1,
"max_score" : 1.0,
"hits" : [ {
"_index" : "zoo",
"_type" : "animal",
"_id" : "1",
"_score" : 1.0,
"_source":{
"name" : "tiger",
"group" : "carnivorous"
}
} ]
}
}
當你建立索引時間序列的時候,遇到的問題是,需要不斷的建立新索引,例如到了11月份,你可以需要新建kangaroo-201711這個索引。
當然,如果不建立索引,直接寫入資料的話,ES會為你分析你寫入的document的欄位型別,並使用預設配置建立索引。
但是預設配置可能並不是你想要的。例如ES對string型別預設是分析的,即,對string型別會進行分詞,但是你的資料中可能有一些string型別的欄位不希望被分析。
那麼怎麼修改預設配置呢?可以建立一個template。
3、Template
template可以修改索引的預設配置。我們以下面這個template為例說明一下。
1)我們建立了一個template名稱為kangaroo_template
2)"template": "kangaroo*",表示對於所有以kangaroo*開頭的索引,預設配置使用template中的配置。
3)"settings","mappings","aliases",可以修改這些型別的預設配置
4)禁用了_source,對name欄位設定string型別且不分析,索引別名設定為kangaroo
curl -XPUT "http://10.93.21.21:8049/_template/kangaroo_template?pretty" -d '{
"template": "kangaroo*",
"settings": {
"number_of_shards": 10
},
"mappings": {
"data": {
"_source": {
"enabled": false
},
"properties": {
"name": {
"type": "string",
"index": "not_analyzed"
},
"id": {
"type": "long"
}
}
}
},
"aliases": {"kangaroo":{}}
}'
執行生效後,看一下template生效的內容,這裡注意有一個"order"欄位,該欄位跟多template合併有關,後面我們會講。
curl -XGET "http://10.93.21.21:8049/_template/kangaroo_template?pretty"
{
"kangaroo_template" : {
"order" : 0,
"template" : "kangaroo*",
"settings" : {
"index" : {
"number_of_shards" : "10"
}
},
"mappings" : {
"data" : {
"_source" : {
"enabled" : false
},
"properties" : {
"name" : {
"index" : "not_analyzed",
"type" : "string"
},
"id" : {
"type" : "long"
}
}
}
},
"aliases" : {
"kangaroo" : { }
}
}
}
我們可以向一個不存在的索引寫入資料,這個操作會使用預設配置,如果索引名稱命中template中的規則,就會使用template的配置建立索引。
這裡我們向kangaroo-201712寫入資料,會命中之前建立的kangaroo_template。
curl -XPUT 'http://10.93.21.21:8049/kangaroo-201712/data/1' -d '{
"name" : "yang",
"id" : "1001",
"weight" : "70 kg"
}'
通過head看一下,可以看到,索引別名已經建立,分片數=10,source禁用生效,name不分析。這就是我們想要的結果。
多個template配置的合併
這個場景是這樣的,一個索引命中了多個template配置,例如:有兩個template配置分別為:a*, ab*,那麼如果有一個索引名字是abc,就會命中了兩個template,這時候會怎麼樣呢?
配置會merge,merge的法則可以參見官方文件,簡單來說,就是跟order值有關,較小order值的配置會先生效,較大order值的配置會繼而覆蓋。