1. 程式人生 > 其它 >elasticsearch實戰與原理解析

elasticsearch實戰與原理解析

es核心概念

索引(index)=資料庫
文件(document)=每條資料
型別(type)=表結構

Elasticsearch的核心概念有Node、Cluster、Shards、Replicas、Index、Type、Document、Settings、Mapping和Analyzer
1.node: 節點
2.cluster: 叢集
Elasticsearch的叢集是由具有相同cluster.name (預設值為elasticsearch)的一個或多個Elasticsearch節點組成的,各個節點協同工作,共享資料。同一個叢集內節點的名字不能重複,但叢集名稱一定要相同。

節點的狀態有Green、Yellow和Red三種

3.shards: 分片
在Elasticsearch中,預設為一個索引建立5個主分片,並分別為每個主分片建立一個副本。

4.replics: 副本
指的是對主分片的備份,這種備份是精確複製模式。每個主分片可以有零個或多個副本,主分片和備份分片都可以對外提供資料查詢服務。當構建索引進行寫入操作時,首先在主分片上完成資料的索引,然後資料會從主分片分發到備份分片上進行索引。

5.index:索引
在Elasticsearch中,索引由一個和多個分片組成。在使用索引時,需要通過索引名稱在叢集內進行唯一標識。

6.type: 類別
類別指的是索引內部的邏輯分割槽,通過Type的名字在索引內進行唯一標識。在查詢時如果沒有該值,則表示需要在整個索引中查詢。

7.document: 文件
索引中的每一條資料叫作一個文件,與關係資料庫的使用方法類似,一條文件資料通過_id在Type內進行唯一標識

8.settings:
Settings是對叢集中索引的定義資訊,比如一個索引預設的分片數、副本數等

9.mapping:
Mapping表示中儲存了定義索引中欄位(Field)的儲存型別、分詞方式、是否儲存等資訊,有點類似於關係資料庫(如MySQL)中的表結構資訊。

在Elasticsearch中,Mapping是可以動態識別的。如果沒有特殊需求,則不需要手動建立Mapping,因為Elasticsearch會根據資料格式自動識別它的型別。當需要對某些欄位新增特殊屬性時,如定義使用其他分詞器、是否分詞、是否儲存等,就需要手動設定Mapping了。一個索引的Mapping一旦建立,若已經儲存了資料,就不可修改了。

10.analyzer:
Analyzer表示的是欄位分詞方式的定義。一個Analyzer通常由一個Tokenizer和零到多個Filter組成。在Elasticsearch中,預設的標準Analyzer包含一個標準的Tokenizer和三個Filter,即Standard Token Filter、Lower Case Token Filter和Stop Token Filter。



當我們向Elasticsearch寫入資料時,Elasticsearch根據文件識別符號ID將文件分配到多個分片上。當查詢資料時,Elasticsearch會查詢所有的分片並彙總結果。對使用者而言,這個過程是透明的,使用者並不知道資料到底存在哪個分片上。

資料寫入過程

  • 分段儲存
    索引資料在磁碟上的是以分段形式儲存的。
    索引檔案被拆分為多個子檔案,其中每個子檔案就叫作段,每個段都是一個倒排索引的小單元。

刪除資料時,由於分段不可修改的特性,Elasticsearch不會把文件從舊的段中移除,因而是新增一個.del檔案,.del檔案中會記錄這些被刪除文件的段資訊。被標記刪除的文件仍然可以被查詢匹配到,但它會在最終結果被返回前通過.del檔案將其從結果集中移除。

當更新資料時,由於分段不可修改的特性,Elasticsearch無法通過修改舊的段來反映文件的更新,於是,更新操作變成了兩個操作的結合,即先刪除、後新增。Elasticsearch會將舊的文件從.del檔案中標記刪除,然後將文件的新版本索引到一個新的段中。在查詢資料時,兩個版本的文件都會被一個查詢匹配到,但被刪除的舊版本文件在結果集返回前就會被移除。

倘若頻繁更新資料,則每次更新都是新增新的資料到新分段,並標記舊的分段中的資料,儲存空間的浪費會更多。

每當有新的資料寫入時,就將其先寫入JVM的記憶體中。在記憶體和磁碟之間是檔案系統快取,檔案快取空間使用的是作業系統的空間。當達到預設的時間或者記憶體的資料達到一定量時,會觸發一次重新整理(Refresh)操作。重新整理操作將記憶體中的資料生成到一個新的分段上並快取到檔案快取系統,稍後再被重新整理到磁碟中並生成提交點。

需要指出的是,由於新的資料會繼續寫入記憶體,而記憶體中的資料並不是以段的形式儲存的,因此不能提供檢索功能。只有當資料經由記憶體重新整理到檔案快取系統,並生成新的段後,新的段才能供搜尋使用,而不需要等到被重新整理到磁碟才可以搜尋。

在Elasticsearch中,寫入和開啟一個新段的過程叫作重新整理。在預設情況下,每個分片會每秒自動重新整理一次。這就是Elasticsearch能做到近實時搜尋的原因,因為文件的變化並不是立即對搜尋可見的,但會在一秒之內變為可見。

客戶端

  • 獲取文件索引的詞向量
    詞向量,在Elasticsearch中的英文名稱為“Term Vectors”。那麼什麼是詞向量呢?我們可以通俗地理解為:詞向量是關於詞的一些統計資訊的統稱。

  • 文件處理過程
    首先需要明確一點,寫入磁碟的倒排索引是不可變的。Elasticsearch為什麼要這樣做,主要是基於以下幾個考量:
    (1)讀寫操作輕量級,不需要鎖。如果Elasticsearch從來不需要更新一個索引,則就不必擔心多個程式同時嘗試修改索引的情況。
    (2)一旦索引被讀入檔案系統的記憶體,它就會一直在那兒,因為不會改變。
    此外,當檔案系統記憶體有足夠大的空間時,大部分的索引讀寫操作是可以直接訪問記憶體,而不是磁碟就能實現的,顯然這有助於提升Elasticsearch的效能。

Elasticsearch不是重寫整個倒排索引,而是增加額外的索引反映最近的變化。每個倒排索引都可以按順序查詢,從最“老舊”的索引開始查詢,最後把結果聚合起來。

當一個文件被刪除時,它實際上只是在.del檔案中被標記為刪除。在進行文件查詢時,被刪除的文件依然可以被匹配查詢,但是在最終返回之前會從結果中刪除。當一個文件被更新時,舊版本的文件會被標記為刪除,新版本的文件在新的段中被索引。當對文件進行查詢時,該文件的不同版本都會匹配一個查詢請求,但是較舊的版本會從結果中被刪除。被刪除的檔案越積累越多,每個段消耗的如檔案控制代碼、記憶體、CPU等資源越來越大。如果每次搜尋請求都需要依次檢查每個段,則段越多,查詢就越慢。這些勢必會影響Elasticsearch的效能,那麼Elasticsearch是如何處理的呢?Elasticsearch引入了段合併段。