天天看點

Elasticsearch基礎但非常有用的功能之一:别名

題記

本文從别名分類、索引别名實踐、索引别名的好處、索引别名常見問題及坑解讀、字段别名實踐一把 五個方面進行詳細解讀。

1、别名分類

别名在Elasticsearch中有兩種分類。

1.1 索引别名

官方釋義: 索引别名可以指向一個或多個索引,并且可以在任何需要索引名稱的API中使用。 别名為我們提供了極大的靈活性。它們允許我們執行以下操作: 

1)在正在運作的叢集上的一個索引和另一個索引之間透明切換; 

2)對多個索引進行分組組合(例如,lastthreemonths的索引别名:是過去3個月索引 logstash201903, logstash201904, logstash_201905的組合);

3)在索引中的文檔子集上建立“視圖”(結合業務場景,會提升檢索效率)。

通俗解釋: 索引别名類似:windows的快捷方式,linux的軟連結,mysql的視圖。

前提:Elasitcsearch建立索引後,索引名不允許改。很多業務場景下單一索引可能無法滿足要求。

場景1:PB級别增量資料,借助rollover api實作,由基于日期的n個索引組成,顯然,對外提供服務使用别名會很便捷。

場景2:試想,線上提供服務的某個索引出了問題,比如:某字段分詞定義不準确,如何保證對外提供服務不停止(不更改業務代碼)的前提下更換索引,顯然,别名更合适。

注意:實際業務場景使用别名會很友善、靈活、快捷、業務松耦合!!

1.2 字段别名

在Elasticsearch Mapping定義的6.4+版本才有的字段類型。 

通俗解釋: 

試想一下有一種業務場景。比如在實際的業務開發中:需要對Facebook、twitter行采集,采集入庫的是兩個業務團隊。

他們對content,分别使用了兩個字段。其中一個是,content。另外一個是cont。 這時候存儲到elasticsearch會有兩個字段。

這樣如果我們在檢索、寫業務代碼的時候,是不是要寫兩個不同的字段來處理呢? 如果有可能寫成一個字段,代碼方面就很避開業務耦合,就很友善了。

我認為這是字段别名的由來。

2、索引别名實踐

2.1 假設沒有别名,如何處理多索引檢索?

方式一:多索引逗号分隔檢索。

POST visitor_logs_2017,visitor_logs_2018/_search           

方式二:通配符索引檢索。

POST visitor_logs_*/_search           

2.2 有了别名後,操作變得簡單

實戰中,我們不需要知道操作的實際索引名稱,我們可以透明地更改别名引用的索引而不會影響使用别名的使用者。

步驟1:别名關聯已有索引。

POST /_aliases?pretty    
{    
  "actions": [    
    {    
      "add": {    
        "index": "visitor_logs_2017",    
        "alias": "visitor_logs"    
      }    
    },    
    {    
      "add": {    
        "index": "visitor_logs_2018",    
        "alias": "visitor_logs"    
      }    
    }    
  ]    
}
           

步驟2:使用别名檢索

GET /visitor_logs/_search           

3、索引别名的好處

3.1 大資料量的管理

場景: 實戰中,可能需要基于時間的資料保留政策(利用rollover機制實作),并從系統中删除舊資料。 使用索引别名:

好處1:來簡化從Elasticsearch中删除資料的過程。

好處2:在沒有任何停機時間的情況下從Elasticsearch中删除最舊的資料,不會出現任何查詢中斷,也不會進行任何用戶端更改。

基于時間索引的實作機制如下:

Elasticsearch基礎但非常有用的功能之一:别名

推薦閱讀:

https://gitbook.cn/books/5c52c6923417565017a61ce0/index.html

試想一下:如果不是基于時間的索引,而使用大索引,删除曆史資料會發生什麼? 

答案:

1、删除索引資料隻能使用:deletebyquery,相比删除索引,deletebyquery删除資料隻是邏輯删除;

2、真正的删除實際是段合并後的實體删除分段,也就是deletebyquery後,有一段時間磁盤空間不降反升。此時的檢索效率會非常低。

3.2 使用者無感覺的重建索引

實戰中,索引的設計可能不是一步到位。 随着業務的擴充,可能會在開發的中後期,調整索引Mapping結構, 比如:

1)iksmart改成ikmax_word分詞以高效分詞,

2)long類型改成keyword以提升檢索效率,

3)修改索引分片數以便于機器橫向擴充,

4)索引分成更小粒度的索引等以提升性能。

通常的做法,都需要借助:reindex操作完成索引的遷移。 如果要確定線上環境的可靠運作且使用者無感覺(即無需告知使用者,不影響使用者的業務),使用别名指向更改前和更改後的索引是 絕佳方案。

實戰舉例:

POST /_aliases?pretty    
{    
  "actions": [    
    {    
      "remove": {    
        "index": "visitor_logs_2018",    
        "alias": "visitor_logs"    
      }    
    },    
    {    
      "add": {    
        "index": "visitor_logs_2018_01",    
        "alias": "visitor_logs"    
      }    
    }    
  ]    
}
           

試想一下,如果沒有索引别名呢?

 答案:

1、無法保證查詢的連續性;

2、無法保證線上業務查詢的可靠性(需要告知使用者,業務中斷一段時間)。

4、索引别名常見問題及坑解讀

問題1:ES批量插入可以使用别名插入嗎?

會報錯: 

no write index is defined for alias[xxx]....            

注意:索引别名不是在任何地方都通用。寫入或更新資料的時候需要指明實體

索引,不要向别名寫入資料。

問題2:ES怎麼擷取所有别名資訊 alias?

或者問題:如何通過索引别名查找實際索引名稱?

GET _cat/aliases
           

傳回資訊:

visitor_logs visitor_logs_2017 - - -    
.kibana      .kibana_1         - - -    
visitor_logs visitor_logs_2018 - -            

問題3:使用别名和基于索引效率一樣嗎?

是一緻的。

前提:索引和别名指向相同的資料,相同的檢索條件。

原理:索引别名隻是實體索引的軟連結名稱而已。

問題4:如何使用别名提升檢索效率?

  • 方式一:基于時間建立索引,指定多索引别名。 比如分為:近1年索引别名,近3個月索引别名,近1個月索引别名,近1周索引别名,近3天索引别名。 檢索的時候,先 敲定時間範圍,然後在指定範圍的别名下檢索。

核心原理:實體上基于時間做了分隔,再加上冷熱資料分離機制,會極大縮小了檢索樣本。

  • 方式二:使用filter 别名或者 路由别名機制,提升效率。 filter Alias上代碼,實際業務中極易被忽視,但會極大提升效率。
POST /_aliases    
{    
    "actions" : [    
        {    
            "add" : {    
                 "index" : "test1",    
                 "alias" : "alias2",    
                 "filter" : { "term" : { "user" : "kimchy" } }    
            }    
        }    
    ]    
}
           

路由機制參考官方文檔即可。

5、字段别名實踐一把

星友的問題: 

“Aliasdatatype,這個資料類型,在現實工作中的使用場景是什麼?看官方文檔,沒有很好了解?”

字段别名原理第一部分已詳細解釋,不再贅述。 這裡實踐一把,加深了解。

PUT trips    
{    
  "mappings": {    
    "_doc": {    
      "properties": {    
        "distance": {    
          "type": "long"    
        },    
        "route_length_miles": {    
          "type": "alias",    
          "path": "distance"    
        },    
        "transit_mode": {    
          "type": "keyword"    
        }    
      }    
    }    
  }    
}
           

注意: 當使用者使用檢索時,實際可以使用routelengthmile字段替代distance做檢索,以達到distance一樣的效果。

6、小結

實戰中,一般在開發 中後期才發現索引别名的妙處。正如文中分析:1、高效索引管理;2、使用者無感覺維護資料修改更新。

建議:相同索引别名的實體索引有 一緻的Mapping和資料結構,以提升檢索效率。

注意:發揮索引别名在檢索方面的優勢,在寫入和更新還得使用 實體索引。

你的實際Elasticsearch業務場景,有哪些非常基礎但實戰開發非常有用的技術點呢? 歡迎留言留下你的思考,讓我們一起精進!

參考:

https://cambium.consulting/articles/2018/2/22/our-favorite-elasticsearch-features-part-2-index-aliases
Elasticsearch基礎但非常有用的功能之一:别名

加入星球,更短時間更快習得更多幹貨