《Elasticsearch技術解析與實戰》Chapter 1.1:Elasticsearch入門和倒排索引

莊裡程式猿發表於2019-04-12

1. 簡介

Elasticsearch是一個機遇Lucene構建的開源、分散式、RESTful介面全文搜尋引擎。同時,Elasticsearch還是一個分散式文件資料庫,能夠擴充套件至數百個伺服器儲存以處理PB級資料,通常作為複雜搜尋場景的首選利器。

Elasticsearch的優點:

  1. 橫向可擴充套件性:只需要增加一臺伺服器,配置完畢即可加入叢集。
  2. 分片機制提供更好的分佈性:同一個索引分成多個分片,類似於HDFS的塊機制,分而治之的方式提升處理效率。
  3. 高可用:提供複製機制,一個分片可以設定多個副本,在某臺伺服器當機情況下,叢集依舊可以工作,並在當機伺服器重啟後恢復資料。
  4. 使用簡單:開箱即用,快速搭建搜尋服務。

Elasticsearch wiki:https://zh.wikipedia.org/wiki/Elasticsearch

2. 資料庫搜尋

在資料量少的情況下可以當做搜尋服務來使用,然而資料庫歸根結底是做持久化儲存。如果資料量大就需要做搜尋服務,底層資料還是關聯式資料庫。我司老系統中有一個訂單表,資料量已經高達兩億,客服等後臺系統通常帶有範圍或批量條件等查詢,這時資料庫基本上就無法響應了,報警根本停不下來。因此,用資料庫來實現搜尋,效能差,可用性不高。

3. Lucene

Lucene是一個開源的全文搜尋引擎工具包,其目的是為開發者提供一個簡單工具包,以快速實現全文檢索的功能。

Lucene wiki:https://zh.wikipedia.org/wiki/Lucene

4. 倒排索引

倒排索引中的索引物件是文件或者文件集合中的單詞等,用來儲存這些單詞在一個文件或者一組文件中的儲存位置,是對文件或者文件集合的一種最常用的索引機制。搜尋引擎的關鍵步驟就是建立倒排索引,下面介紹Lucene是如何建立倒排索引和相應的生成演算法。

假設有兩篇文章: 文章1:Tom lives in Guangzhou, I live in Guangzhou too. 文章2:He once lived in Shanghai.

4.1 取得關鍵詞

Lucene是基於關鍵詞索引和查詢的,首先要進行關鍵詞提取:

  • 分詞:英文單詞由空格分隔,較好處理;中文詞語由於是連在一起的,需要進行特殊的分詞處理(後面會介紹分詞器相關知識)。

  • 過濾無概念詞語:英文中“in”“once”“too”等詞沒有實際意義;中文中“的”“是”等也無實際意義,這些無概念詞語可以過濾掉。

  • 統一大小寫:“he”和“HE”表示的含義一樣,所以單詞需要統一大小寫。

  • 語義還原:通常使用者查詢“live”時希望能將“lives”和“lived”也查詢出來,所以需要將“lives”和“lived”還原成“live”。

  • 過濾標點符號

    經過以上過濾,得到如下結果: 文章1關鍵詞:tom live guangzhou i live guangzhou 文章2關鍵詞:he live shanghai

4.2 建立倒排索引

關鍵詞建立完成後,就可以進行倒排索引建立了。過濾後的關係是:“文章號“對”文章中所有關鍵詞“,倒排索引把這個關係倒過來變成:”關鍵詞“對”擁有關鍵詞的所有文章號“。

《Elasticsearch技術解析與實戰》Chapter 1.1:Elasticsearch入門和倒排索引

通常僅知道關鍵詞在哪些文章中出現還不夠,還需要知道關鍵詞在文章中出現的次數和位置,通常有兩種位置:

  1. 字元位置,即記錄該詞是文章中第幾個字元(優點是顯示並定位關鍵詞快)。
  2. 關鍵詞位置,即記錄該詞是文章中的第幾個關鍵詞(優點是節約索引空間、片語查詢快),Lucene中記錄的就是這種位置。

《Elasticsearch技術解析與實戰》Chapter 1.1:Elasticsearch入門和倒排索引

以上就是Lucene索引結構中最核心的部分,關鍵字是按字元順序排列的(Lucene沒有使用B樹結構),因此Lucene可以使用二元搜尋演算法快速定位關鍵詞。

4.3 實現

Lucene將上面三列分別作為詞典檔案(Term Dictionary)、頻率檔案(frequencies)、位置檔案(positions)儲存。其中詞典檔案不僅儲存了每個關鍵詞,還保留了指向頻率檔案和位置檔案的指標,通過指標可以找到該關鍵字的頻率資訊和位置資訊。

Lucene中使用了field的概念,用於表達資訊所在的位置(如標題中、文章中、url中),在建索引中,該field資訊也記錄在詞典檔案中,每個關鍵詞都有一個field資訊,因為每個關鍵字一定屬於一個或多個field。

4.4 壓縮演算法

為了減小索引檔案的大小,Lucene對索引還是用了壓縮技術。 首先,對詞典檔案中的關鍵詞進行壓縮,關鍵詞壓縮為<字首長度,字尾>,例如:當前詞為”阿拉伯語“,上一個詞為”阿拉伯“,那麼”阿拉伯語“壓縮為<3,語>。 其次大量用到的是對數字的壓縮,數字只儲存與上一個值的差值(這樣可以減少數字的長度,進而減少儲存該數字需要的位元組數)。例如當前文章號是16389(不壓縮要用3個位元組),上一文章號是16382,壓縮後儲存7(只用一個位元組)。

壓縮演算法推薦閱讀:https://www.cnblogs.com/dreamroute/p/8484457.html

4.5 實戰

查詢單詞”live“,Lucene先對詞典二元查詢,找到該詞,通過指向頻率檔案的指標讀出所有文章號,然後返回結果。詞典通常非常小,可以達到毫秒級返回。而用普通的順序匹配演算法,不建立索引,而是對所有文章的內容進行字串匹配,過程是很緩慢的,當資料量很大時,耗時更加嚴重。

5. 基礎概念

5.1 索引詞(term)

Elasticsearch中能夠被索引的精確值。foo、Foo、FOO幾個單詞是不同的索引詞。索引詞可以通過term查詢進行準確的搜尋。

5.2 文字(text)

文字會被拆分成一個個索引詞儲存在索引庫中,為後續搜尋提供支援。

5.3 分析(analysis)

分析是將文字轉換為索引詞的過程,其結果依賴於分詞器。

5.4 叢集(cluster)

叢集由一個或多個節點組成,對外提供服務。Elasticsearch節點如果有相同的叢集名稱會自動加入到同一個叢集,因此如果你擁有多個獨立叢集,每個叢集都要設定不同的名稱。

5.5 節點(node)

節點是一個邏輯上獨立的服務,是叢集的一部分,可以儲存資料,並參與叢集的索引和搜尋功能。

5.6 路由(routing)

文件儲存時是通過雜湊值進行計算,最終選擇儲存在主分片中,這個值預設是由文件的ID生成。

5.7 分片(shard)

分片是單個Lucene例項,是Elasticsearch管理的比較底層的功能。當索引佔用空間很大超過一個節點的物理儲存,Elasticsearch將索引切分成多個分片,分散在不同的物理節點上,以解決單物理節點儲存空間有限的問題。

5.8 主分片(primary shard)

每個文件都儲存在一個分片中,儲存文件時系統會首先儲存在主分片中,然後複製到不同的副本中。預設情況下一個索引擁有5個主分片,分片一旦建立,主分片數量就無法修改。

5.9 副本分片(replica shard)

每個主分片有零個或多個副本,是主分片的複製,其主要目的是:

  1. 增加高可用性:當主分片失敗時,某一副本分片提升為主分片
  2. 提高效能:副本分片數量可以動態配置,可以為主分片分擔查詢壓力。
  3. 允許水平分割擴充套件資料
  4. 允許分配和並行操作,從而提高效能和吞吐量。

5.10 複製(replica)

主分片的資料會複製到副本分片中,這樣避免了單點問題,當某個節點發生故障,複製可以對故障進行轉移,保證系統的高可用。

5.11 索引(index)

索引是具有相同結構的文件合集。

5.12 型別(type)

一個索引可以定義一個或多個型別,型別是索引的邏輯分割槽。

5.13 文件(document)

文件是儲存在Elasticsearch中的一個JSON格式的字串,就像關聯式資料庫中表的一行記錄。

5.14 對映(mapping)

對映像關聯式資料庫中的表結構,每個索引都有一個對映,它定義了索引中的每一個欄位型別。對映可以事先被定義,也可以在第一次儲存文件時被自動識別。

5.15 欄位(field)

文件中包含零個或多個欄位,欄位可以是一個簡單的值,也可以是一個陣列或物件的巢狀結構。欄位類似於關聯式資料庫中表的列,每個欄位都對應一個欄位型別。

5.16 來源欄位(source field)

預設情況下源文件將被儲存在_source欄位中,查詢時返回該欄位。

5.17 主鍵(ID)

ID是檔案的唯一標識,如果未指定,系統會自動生成一個ID,文件的index/type/id必須是唯一的。

5.18 Elasticsearch核心概念 vs. 資料庫核心概念

Elasticsearch 資料庫
Document row 行
Type table 表
Index database 庫

Tips

本文同步發表在公眾號,歡迎大家關注!? 後續筆記歡迎關注獲取第一時間更新!

《Elasticsearch技術解析與實戰》Chapter 1.1:Elasticsearch入門和倒排索引

相關文章