在使用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值的配置會繼而覆蓋。