1. 定義
Elasticsearch 是一個高度可擴充套件的開源全文搜尋和分析引擎。它允許您快速,近實時地儲存,搜尋和分析大量資料。它通常用作底層引擎、技術,為具有複雜搜尋功能和要求的應用程式提供支援。
Elasticsearch 也使用 Java 開發並使用 Lucene 作為其核心來實現所有索引和搜尋的功能,但是它的目的是通過簡單的 RESTful API 來隱藏 Lucene 的複雜性,從而讓全文搜尋變得簡單。
ES 是基於Lucene這個非常成熟的索引方案,另加上一些分散式的實現:叢集,分片,複製等。
2. 與 Lucene 的關係
Lucene 是一套用於全文檢索和搜尋的開源程式庫,由 Apache 軟體基金會支援和提供。Lucene 提供了一個簡單卻強大的應用程式介面,能夠做全文索引和搜尋。但是 Lucene 操作複雜,一般不直接利用 Lucene 作為搜尋引擎,ElasticSearch 就是利用 Java 簡化了 Lucene 的使用。
3. 優點
- 具備橫向可擴充套件性:只需要增加一臺伺服器,做些配置,啟動 ES 程式就可以快速併入叢集。'
- 分片機制:同一個索引分成多個分片(sharding),類似於 redis 中的分片,採取分而治之的思想來更好地解決問題。
- 高可用:提供複製機制,一個分片可以設定多個複製,使得某臺伺服器當機的話,叢集依舊可以正常執行,並會把丟失的複製恢復到其它可用節點上'
4. 缺點
- 節點資料的一致性問題:其預設的機制是通過多播機制,同步後設資料資訊,但是在比較繁忙的叢集中,可能會由於網路的阻塞,或者節點處理能力達到飽和導致各節點後設資料不一致——也就是所謂的腦裂問題,這樣會使叢集處於不一致狀態。目前並沒有一個徹底的解決方案來解決這個問題,但是可以通過將工作節點與後設資料節點分開的部署方案來緩解這種情況。
- 沒有細粒度的許可權管理,沒有像MySQL那樣的分各種使用者,每個使用者又有不同的許可權。
5. 解決的問題
- 更快的在大量資料中檢索相關資料,效能遠優於傳統資料庫
- 結合分詞器,根據關鍵詞返回統計結果
6. 應用場景
- 全文檢索:例如淘寶 app 搜尋 17寸電腦關鍵詞,搜尋系統將依據關鍵詞分詞查詢,按照指定的匹配度返回對應的商品。這是 ES 最核心也是最常用的功能。
- 記錄和日誌分析:圍繞Elasticsearch構建的生態系統使其成為最容易實施和擴充套件日誌記錄解決方案之一。結合Logstash,ElasticSearch 和Kibana 三個元件,可以搭建一套高效的日誌收集和分析系統,也就是我們常見的ELK系統。
- 資料視覺化:Kibana 是一款功能強大且易於使用的視覺化工具,可以結合 ES 對大量資料提供圖表選項、地理資料等視覺化元件。
7. 倒排索引(摘自Elasticsearch權威指南)
Elasticsearch 是通過 Lucene 的倒排索引技術實現比關係型資料庫更快的過濾。特別是它對多條件的過濾支援非常好。
Elasticsearch 使用一種稱為 倒排索引 的結構,它適用於快速的全文搜尋。一個倒排索引由文件中所有不重複詞的列表構成,對於其中每個詞,有一個包含它的文件列表。
例如,假設我們有兩個文件,每個文件的 content
域包含如下內容:
- The quick brown fox jumped over the lazy dog
- Quick brown foxes leap over lazy dogs in summer
為了建立倒排索引,我們首先將每個文件的 content
域拆分成單獨的 詞(我們稱它為 詞條
或 tokens
),建立一個包含所有不重複詞條的排序列表,然後列出每個詞條出現在哪個文件。結果如下所示:
Term Doc_1 Doc_2
-------------------------
Quick | | X
The | X |
brown | X | X
dog | X |
dogs | | X
fox | X |
foxes | | X
in | | X
jumped | X |
lazy | X | X
leap | | X
over | X | X
quick | X |
summer | | X
the | X |
------------------------
現在,如果我們想搜尋 quick brown
,我們只需要查詢包含每個詞條的文件:
Term Doc_1 Doc_2
-------------------------
brown | X | X
quick | X |
------------------------
Total | 2 | 1
兩個文件都匹配,但是第一個文件比第二個匹配度更高。如果我們使用僅計算匹配詞條數量的簡單 相似性演算法 ,那麼,我們可以說,對於我們查詢的相關性來講,第一個文件比第二個文件更佳。
但是,我們目前的倒排索引有一些問題:
Quick
和quick
以獨立的詞條出現,然而使用者可能認為它們是相同的詞。fox
和foxes
非常相似, 就像dog
和dogs
;他們有相同的詞根。jumped
和leap
, 儘管沒有相同的詞根,但他們的意思很相近。他們是同義詞。
使用前面的索引搜尋 +Quick +fox
不會得到任何匹配文件。(記住,+
字首表明這個詞必須存在。)只有同時出現 Quick
和 fox
的文件才滿足這個查詢條件,但是第一個文件包含 quick fox
,第二個文件包含 Quick foxes
。
我們的使用者可以合理的期望兩個文件與查詢匹配。我們可以做的更好。
如果我們將詞條規範為標準模式,那麼我們可以找到與使用者搜尋的詞條不完全一致,但具有足夠相關性的文件。例如:
Quick
可以小寫化為quick
。foxes
可以 詞幹提取 --變為詞根的格式-- 為fox
。類似的,dogs
可以為提取為dog
。jumped
和leap
是同義詞,可以索引為相同的單詞jump
。
現在索引看上去像這樣:
Term Doc_1 Doc_2
-------------------------
brown | X | X
dog | X | X
fox | X | X
in | | X
jump | X | X
lazy | X | X
over | X | X
quick | X | X
summer | | X
the | X | X
------------------------
這還遠遠不夠。我們搜尋 +Quick +fox
仍然 會失敗,因為在我們的索引中,已經沒有 Quick
了。但是,如果我們對搜尋的字串使用與 content
域相同的標準化規則,會變成查詢 +quick +fox
,這樣兩個文件都會匹配!