Elasticsearch(1):基礎入門

奧辰發表於2020-09-22
 

1 Elasticsearch

在如今資料為王的時代,如何充分高效實現資料檢索和分析是資料應用的關鍵。以電商平臺為例,輸入一個商品名稱,那麼就要求系統以最快的速度將所有相關的商品搜尋處理。現在的資料大多儲存在mysql、Oracle或其他企業自主研發的關係型資料庫中,搜尋能力已經逐漸跟不上實際需求。例如需要檢索“格力空調”這個商品,那麼,按照關係型資料庫中的邏輯,sql語句大概應該是這樣的:

select * from table where name like "%格力空調%"

注意,因為sql語句中使用了模糊查詢,而且在“格力空調”這個關鍵詞前面也使用了萬用字元,所以索引將會失效,這將倒是檢索效能大大降低。

另外,我們必須承認,有時候,我們會將關鍵詞輸入錯誤,例如將“格力空調”輸入成了“格空調”,那麼這時候SQL語句將變成這樣:

select * from table where name like "%格空調%"

可想而知,我們查詢不出任何真正相關的結果。

另一方面,雖然目前的主流資料庫都已經能夠很好的支援分散式擴充套件,但通常需要對應用程式進行非常大的改動,才能利用上橫向擴容的新增資源。

這就是目前關係型資料庫在實際應用中的一些侷限性。為了解決這些問題,Elasticsearch應運而生。

Elasticsearch 是一個分散式的 RESTful 風格的分散式可擴充套件的準實時搜尋和分析引擎,一個建立在全文搜尋引擎 Apache Lucene(TM) 基礎上的搜尋引擎.當然 Elasticsearch 並不僅僅是 Lucene 那麼簡單,它不僅包括了全文搜尋功能(或者說倒排索引,將一段詞語進行分詞,並且將分出的單個詞語統一的放到一個分詞庫中,在搜尋時,根據關鍵字去分詞庫中檢索,找到匹配的內容),還可以進行以下工作:

  • 分散式實時檔案儲存,並將每一個欄位都編入索引,使其可以被搜尋。

  • 實時分析的分散式搜尋引擎。

  • 可以通過極其簡單配置擴充套件到上百臺伺服器實現分散式橫向擴容,處理PB級別的結構化或非結構化資料。

2 核心概念理解

2.1 索引(index)

在elasticsearch中,索引有兩種含義:

  • 一種是名詞意義上的索引。我們通常所說的索引也大多指這一種,這時候的索引就是文件(Document)的容器,是具有某種相似特性文件的集合,所以,在設計elasticsearch時,通常將相似的文件存放在同一個索引中(當然,個別document可能多一個或少一個field),這樣Elasticsearch對磁碟儲存的利用率最高。例如,對於部落格類系統,可以將文章(artical)存放為一個索引中,將作者(author)存放為一個索引。索引由一個名稱(必須全部是小寫,不能以'_', '-', 或 '+'開頭)標識,當對其中的文件執行索引、搜尋、更新和刪除操作時,該名稱用於引用索引。通常索引是由兩部分構成:Mapping和Setting。Mapping 定義該索引包含的文件的資料結構的資訊;Setting定義了該索引的資料分佈資訊。

  • 另一種索引是指動詞意義上的索引。儲存一個文件到索引(名詞)的過程,就類似於SQL語句中的 INSERT關鍵詞,當然,如果文件已存在,那就相當於資料庫的UPDATE。

2.2 型別(type)

就目前7.X版本的ES來說,再談型別(type)的概念已經不是太有意義,因為型別的概念正在被逐漸淡化拋棄。

在5.X或者更早的版本中,型別的概念確實很常用,型別是索引內部的邏輯分割槽(category/partition),然而其意義完全取決於使用者需求。因此,一個索引內部可定義一個或多個型別(type)。一般來說,型別就是為那些擁有相同的域的文件做的預定義。例如,在一個部落格系統類的索引中,可以定義一個用於儲存作者資訊的型別,一個儲存部落格文章資訊的型別,以及一個儲存評論資料的型別。類比傳統的關係型資料庫領域來說,型別相當於“表”。

然而,從6.X開始單個索引中只能有一個型別,7.X的版本中只存在一個預設的名為“_doc”的型別,官方也不建議繼續使用這一概念,甚至8.X以後完全不支援。這是為什麼呢?

許多資料指出ES中“索引”的概念和關聯式資料庫的“庫”是相似的,“型別”和“表”是對等的。 這其實是一個不正確的對比,掩蓋了一些基礎的特性。在關係型資料庫裡,"表"是相互獨立的,一個“表”裡的列和另外一個“表”的同名列沒有關係,互不影響。但在型別裡欄位不是這樣的。在一個ES索引裡,所有不同型別的同名欄位內部使用的是同一個lucene欄位儲存。也就是說,上面例子中,作者資訊型別的author_name欄位和部落格文章資訊型別的author_name欄位是儲存在一個欄位裡的,兩個型別裡的這一欄位必須有一樣的欄位定義。這可能導致一些問題,例如我們希望在型別1中的phone_number儲存為數值型別,而在型別2中的phone_number欄位儲存為字元型別,這是不可能做到的。另外,在同一個索引中,儲存僅有小部分欄位相同或者全部欄位都不相同的文件,會導致資料稀疏,影響Lucene有效壓縮資料的能力。

所以,在一個索引中,最好只擁有一個型別,如果有多種實體資料,那就分別儲存在多個索引中。

2.3 文件(document)

在索引中儲存的每一個目標資料稱為文件,ES中的文件可以類比關係型資料庫中的每一行記錄來理解。ES是面向文件的搜尋,文件是ES所有可搜尋資料的最小單元。在ES中文件會被序列化成json格式進行儲存,每個文件都會有一個Unique ID,這個ID可以有使用者在建立文件的時候指定,在使用者未指定時則由ES自己生成,這個ID中在查詢結果中以_id這個後設資料表示。除了_id外,文件中還包括一下這些後設資料:

  • _index:文件所屬索引名稱。

  • _type:文件所屬型別名。

  • _id:文件的ID值。

  • _version:文件的版本資訊。ES通過使用version來保證對文件的變更能以正確的順序執行,避免亂序造成的資料丟失。

  • _seq_no:嚴格遞增的順序號,每個文件一個,Shard級別嚴格遞增,保證後寫入的Doc的_seq_no大於先寫入的Doc的_seq_no。

  • primary_term:primary_term也和_seq_no一樣是一個整數,每當Primary Shard發生重新分配時,比如重啟,Primary選舉等,_primary_term會遞增1

  • found:查詢的ID正確那麼ture, 如果 Id 不正確,就查不到資料,found欄位就是false。

  • _source:文件的原始JSON資料,這才是我們儲存在ES中的業務資料。

2.4 對映(mapping)

ES中中的對映(Mapping)用來定義一個文件,類似於關係型資料庫中的表結構的概念,但卻比表結構具有更加強大的功能,如下圖所示,具體來說主要包含以下功能:

  • 文件中哪些欄位需要定義成全文索引欄位。
  • 文件中哪些欄位定義為精確值,例如日期,數字、地理位置等。
  • 文件中哪些欄位需要被索引(能通過該欄位的值查詢文件)。
  • 日期值的格式。
  • 動態新增欄位的規則定義等。

對映可以分為動態對映和靜態對映:

靜態對映:若在資料寫入索引前,對映(mapping)已經建立,那麼在寫入資料時,ES會根據對映和寫入資料的key進行對比,然後寫入相應的對映中;

動態對映:如果mapping沒有建立,elasticsearch將會根據寫入的資料的key自行建立相應的mapping,並寫入資料。

2.5 叢集(cluster)

叢集是一個或多個節點(伺服器)的集合,它們共同儲存你的整個資料,並提供跨所有節點的聯合索引和搜尋功能。一個叢集由一個唯一的名稱標識,預設這個唯一標識的名稱是"elasticsearch"(可修改)。這個名稱很重要,因為如果節點被設定為按其名稱加入叢集,那麼節點只能是叢集的一部分。

注意,在同一環境中用最好使用不同的叢集名稱,否則可能導致節點加入到錯誤的叢集中。例如,你可以使用"logging-dev", "logging-test", "logging-prod"分別用於開發、測試和正式叢集的名字。

ES叢集實際上是一個分散式系統,這是ES的一大優勢,它需要具備兩個特性:

  1)高可用性

    a)服務可用性:允許有節點停止服務;

    b)資料可用性:部分節點丟失,不會丟失資料;

  2)可擴充套件性

    隨著請求量的不斷提升,資料量的不斷增長,系統可以將資料分佈到其他節點,實現水平擴充套件;

ES叢集有三種健康狀態:

  • green:所有主要分片和複製分片都可用

  • yellow:所有主要分片可用,但不是所有複製分片都可用

  • red:不是所有的主要分片都可用

我們可以通過查詢語句對健康狀態進行查詢,關注和提升ES叢集的健康狀態對保證資料安全性、高效查詢十分有必要。

2.6 節點(node)

節點是一個ElasticSearch的例項,其本質就是一個Java程式,負責進行資料儲存,並且參與叢集的索引和搜尋功能;一臺機器上可以執行多個ElasticSearch例項,但是建議在生產環境中一臺機器上只執行一個ElasticSearch例項。

與叢集一樣,節點由一個名稱標識,預設情況下,該名稱是在啟動時分配給節點的隨機通用唯一識別符號(UUID)。如果不希望使用預設值,則可以定義所需的任何節點名稱。

一個叢集可以有任意數量的節點。此外,如果在網路上當前沒有執行任何節點,那麼此時啟動一個節點將預設形成一個單節點的名字叫"elasticsearch"的叢集。一個節點可以通過配置叢集名稱來加入到一個特定的叢集中。預設情況下,每個節點都被設定加入到一個名字叫"elasticsearch"的叢集中,這就意味著如果你啟動了很多個節點,並且假設它們彼此可以互相發現,那麼它們將自動形成並加入到一個名為"elasticsearch"的叢集中。

在一個ES的叢集中包含著多個ES的節點,往往每個節點所扮演的角色也不盡相同,ES的節點型別主要包含以下幾類:

  • Master-eligible Node:每個節點啟動後,預設是一個 Master-eligible 節點,Master-eligible的節點可參加選主流程,成為Master節點,通過配置項 node.master:falase 可以禁用節點的Master-eligible職責,禁止後當前節點就不會參加選主流程;

  • Master Node:ES叢集中雖然每個節點都儲存了叢集狀態,但是隻有Master節點才有修改叢集狀態的許可權,叢集狀態包括:叢集中節點資訊、所有索引和其相關的Mapping和Setting資訊、分片的路由資訊。在叢集啟動時,第一個啟動的Master-eligible節點會將自己選舉為主節點;

  • Data Node:儲存資料的節點,負責儲存分片資料,對資料擴充套件有重要作用;

  • Coordinating Node:負責接受Client請求,將請求分發到合適的節點獲取響應後,將結果最終彙集在一起,每個節點預設都有Coordinating節點的職責;

  • Machine Learning Node:負責執行機器學習的Job,用來做異常檢測;

  • Ingest Node:資料預處理的節點,支援Pipeline管道設定,可以使用Ingest對資料進行過濾、轉換等操作。

注意,每個ES節點可以承擔多個職責。

2.7 分片(shard)

ES的shard(分片)機制可將一個索引內部的資料分佈地儲存於多個節點,它通過將一個索引切分為多個底層物理的Lucene索引完成索引資料的分割儲存功能,這每一個物理的Lucene索引稱為一個分片(shard)。每個分片其內部都是一個全功能且獨立的索引,因此可由叢集中的任何主機儲存。建立索引時,使用者可指定其分片的數量,預設數量為5個。

Shard有兩種型別:primary和replica,即主分片及副本分片。主分片用於文件儲存,每個新的索引會自動建立5個主分片,當然此數量可在索引建立之前通過配置自行定義,不過,一旦建立完成,其主分片的數量將不可更改。Replica分片是主分片的副本,用於冗餘資料及提高搜尋效能,為保證副本分片的有效性,主分片絕不會被建立在同一節點上。每個主分片預設配置了一個副本,但也可以配置多個,且其數量可動態更改。ES會根據需要自動增加或減少這些Replica shard的數量。

ES叢集可由多個節點組成,各分片分散式地儲存於這些節點上。ES可自動在節點間按需要移動分片,例如增加節點或節點故障時。簡而言之,分片實現了叢集的分散式儲存,而副本實現了其分散式處理及冗餘功能。

3 安裝

3.1 ES 安裝

官方下載地址:

https://www.elastic.co/cn/downloads/elasticsearch

在ES官網有很詳細的安裝說明:

https://www.elastic.co/guide/en/elastic-stack-get-started/current/get-started-elastic-stack.html#install-elasticsearch

這裡繼續給出當前版本linux系統下elasticsearch安裝方法,首先下載安裝包:

curl -L -O https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.9.0-linux-x86_64.tar.gz

解壓:

tar -xzvf elasticsearch-7.9.0-linux-x86_64.tar.gz

解壓後elasticsearch目錄內結構如下:

其中bin目錄時指令碼檔案,config目錄存放的是ES的相關配置。

為了使區域網其他機器能夠訪問ES,在啟動前,稍微修改一下配置:

cd elasticsearch-7.9.0

vim ./config/elasticsearch.yml

新增以下內容後儲存退出:

http.host: 0.0.0.0

啟動:

./bin/elasticsearch

若是啟動成功,可在區域網內任何機器訪問,預設埠是9200,我的伺服器ip是192.168.31.221,所以訪問地址為:http://192.168.31.221:9200 ,成功訪問後,出現以下介面:

3.2 Kibana安裝

Kibana 是一個免費且開放的使用者介面,通過Kibana,我們能夠對 Elasticsearch 資料進行視覺化,並在 Elastic Stack 中進行導航。並且可以進行各種操作,從跟蹤查詢負載,到理解請求如何流經您的整個應用,都能輕鬆完成。

  • Kibana是ElasticSearch的一個工具,用來分析ES中的資料並以各種圖形介面顯示出來
  • 可以作為ElasticSearch的一個客戶端,在Kibana中可以很輕鬆的呼叫ES的RESTful介面

Kibana下載地址:

https://www.elastic.co/cn/downloads/kibana

注意,一定要下載與elasticsearch對應的Kibana版本。

下載好後,解壓,目錄結構如下:

配置Kibana,允許其他機器訪問,並新增ES的訪問地址:

cd kibana-7.9.0-linux-x86_64/

vim ./config/kibana.yml

新增以下內容:

server.host: "0.0.0.0"

elasticsearch.hosts: ["http://192.168.31.221:9200"]

啟動Kibana:

./bin/kibana

在瀏覽器中訪問:http://192.168.31.221:5601/ , 出現一下介面證明成功。

嘗試使用Kibana進行查詢,按如下方式開啟開發工具:

點選切換後介面的三角形按鈕可執行查詢:

具體查詢語法,我們後續在具體學習。

到這一步,我們已經將ES基礎概念和ES安裝、Kibana安裝完成。後續可正式開始學習ES。

相關文章