Elasticsearch是一個機遇Lucene構建的開源、分佈式、RESTful接口全文搜索引擎。同時,Elasticsearch仍是一個分佈式文檔數據庫,可以擴展至數百個服務器存儲以處理PB級數據,一般做爲複雜搜索場景的首選利器。html
Elasticsearch的優勢:node
Elasticsearch wiki:https://zh.wikipedia.org/wiki/Elasticsearchgit
在數據量少的狀況下能夠當作搜索服務來使用,然而數據庫歸根結底是作持久化存儲。若是數據量大就須要作搜索服務,底層數據仍是關係數據庫。我司老系統中有一個訂單表,數據量已經高達兩億,客服等後臺系統一般帶有範圍或批量條件等查詢,這時數據庫基本上就沒法響應了,報警根本停不下來。所以,用數據庫來實現搜索,性能差,可用性不高。github
Lucene是一個開源的全文搜索引擎工具包,其目的是爲開發者提供一個簡單工具包,以快速實現全文檢索的功能。算法
Lucene wiki:https://zh.wikipedia.org/wiki/Lucene數據庫
倒排索引中的索引對象是文檔或者文檔集合中的單詞等,用來存儲這些單詞在一個文檔或者一組文檔中的存儲位置,是對文檔或者文檔集合的一種最經常使用的索引機制。搜索引擎的關鍵步驟就是創建倒排索引,下面介紹Lucene是如何創建倒排索引和相應的生成算法。數組
假設有兩篇文章: 文章1:Tom lives in Guangzhou, I live in Guangzhou too. 文章2:He once lived in Shanghai.服務器
Lucene是基於關鍵詞索引和查詢的,首先要進行關鍵詞提取:app
分詞:英文單詞由空格分隔,較好處理;中文詞語因爲是連在一塊兒的,須要進行特殊的分詞處理(後面會介紹分詞器相關知識)。分佈式
過濾無概念詞語:英文中「in」「once」「too」等詞沒有實際意義;中文中「的」「是」等也無實際意義,這些無概念詞語能夠過濾掉。
統一大小寫:「he」和「HE」表示的含義同樣,因此單詞須要統一大小寫。
語義還原:一般用戶查詢「live」時但願能將「lives」和「lived」也查詢出來,因此須要將「lives」和「lived」還原成「live」。
過濾標點符號
通過以上過濾,獲得以下結果: 文章1關鍵詞:tom live guangzhou i live guangzhou 文章2關鍵詞:he live shanghai
關鍵詞創建完成後,就能夠進行倒排索引創建了。過濾後的關係是:「文章號「對」文章中全部關鍵詞「,倒排索引把這個關係倒過來變成:」關鍵詞「對」擁有關鍵詞的全部文章號「。
一般僅知道關鍵詞在哪些文章中出現還不夠,還須要知道關鍵詞在文章中出現的次數和位置,一般有兩種位置:
以上就是Lucene索引結構中最核心的部分,關鍵字是按字符順序排列的(Lucene沒有使用B樹結構),所以Lucene可使用二元搜索算法快速定位關鍵詞。
Lucene將上面三列分別做爲詞典文件(Term Dictionary)、頻率文件(frequencies)、位置文件(positions)保存。其中詞典文件不只保存了每一個關鍵詞,還保留了指向頻率文件和位置文件的指針,經過指針能夠找到該關鍵字的頻率信息和位置信息。
Lucene中使用了field的概念,用於表達信息所在的位置(如標題中、文章中、url中),在建索引中,該field信息也記錄在詞典文件中,每一個關鍵詞都有一個field信息,由於每一個關鍵字必定屬於一個或多個field。
爲了減少索引文件的大小,Lucene對索引仍是用了壓縮技術。 首先,對詞典文件中的關鍵詞進行壓縮,關鍵詞壓縮爲<前綴長度,後綴>,例如:當前詞爲」阿拉伯語「,上一個詞爲」阿拉伯「,那麼」阿拉伯語「壓縮爲<3,語>。 其次大量用到的是對數字的壓縮,數字只保存與上一個值的差值(這樣能夠減小數字的長度,進而減小保存該數字須要的字節數)。例如當前文章號是16389(不壓縮要用3個字節),上一文章號是16382,壓縮後保存7(只用一個字節)。
壓縮算法推薦閱讀:https://www.cnblogs.com/dreamroute/p/8484457.html
查詢單詞」live「,Lucene先對詞典二元查找,找到該詞,經過指向頻率文件的指針讀出全部文章號,而後返回結果。詞典一般很是小,能夠達到毫秒級返回。而用普通的順序匹配算法,不創建索引,而是對全部文章的內容進行字符串匹配,過程是很緩慢的,當數據量很大時,耗時更加嚴重。
Elasticsearch中可以被索引的精確值。foo、Foo、FOO幾個單詞是不一樣的索引詞。索引詞能夠經過term查詢進行準確的搜索。
文本會被拆分紅一個個索引詞存儲在索引庫中,爲後續搜索提供支持。
分析是將文本轉換爲索引詞的過程,其結果依賴於分詞器。
集羣由一個或多個節點組成,對外提供服務。Elasticsearch節點若是有相同的集羣名稱會自動加入到同一個集羣,所以若是你擁有多個獨立集羣,每一個集羣都要設置不一樣的名稱。
節點是一個邏輯上獨立的服務,是集羣的一部分,能夠存儲數據,並參與集羣的索引和搜索功能。
文檔存儲時是經過散列值進行計算,最終選擇存儲在主分片中,這個值默認是由文檔的ID生成。
分片是單個Lucene實例,是Elasticsearch管理的比較底層的功能。當索引佔用空間很大超過一個節點的物理存儲,Elasticsearch將索引切分紅多個分片,分散在不一樣的物理節點上,以解決單物理節點存儲空間有限的問題。
每一個文檔都存儲在一個分片中,存儲文檔時系統會首先存儲在主分片中,而後複製到不一樣的副本中。默認狀況下一個索引擁有5個主分片,分片一旦創建,主分片數量就沒法修改。
每一個主分片有零個或多個副本,是主分片的複製,其主要目的是:
主分片的數據會複製到副本分片中,這樣避免了單點問題,當某個節點發生故障,複製能夠對故障進行轉移,保證系統的高可用。
索引是具備相同結構的文檔合集。
一個索引能夠定義一個或多個類型,類型是索引的邏輯分區。
文檔是存儲在Elasticsearch中的一個JSON格式的字符串,就像關係數據庫中表的一行記錄。
映射像關係數據庫中的表結構,每一個索引都有一個映射,它定義了索引中的每個字段類型。映射能夠事先被定義,也能夠在第一次存儲文檔時被自動識別。
文檔中包含零個或多個字段,字段能夠是一個簡單的值,也能夠是一個數組或對象的嵌套結構。字段相似於關係數據庫中表的列,每一個字段都對應一個字段類型。
默認狀況下源文檔將被存儲在_source字段中,查詢時返回該字段。
ID是文件的惟一標識,若是未指定,系統會自動生成一個ID,文檔的index/type/id必須是惟一的。
Elasticsearch | 數據庫 |
---|---|
Document | row 行 |
Type | table 表 |
Index | database 庫 |
本文同步發表在公衆號,歡迎你們關注!😁 後續筆記歡迎關注獲取第一時間更新!