1. 程式人生 > 其它 >Elasticsearch索引別名、Filtered索引別名、Template

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