先自上而下,後自底向上的介紹ElasticSearch的底層工做原理,試圖回答如下問題:html
*foo-bar*
沒法匹配 foo-bar
?elasticsearch版本: elasticsearch-2.2.0緩存
雲裏面的每一個白色正方形的盒子表明一個節點——Node。網絡
在一個或者多個節點直接,多個綠色小方塊組合在一塊兒造成一個ElasticSearch的索引。數據結構
在一個索引下,分佈在多個節點裏的綠色小方塊稱爲分片——Shard。elasticsearch
Shard=Lucene Index
一個ElasticSearch的Shard本質上是一個Lucene Index。這篇 ElasticSearch 詳細使用教程,內部分享時被老大表揚了性能
Lucene是一個Full Text 搜索庫(也有不少其餘形式的搜索庫),ElasticSearch是創建在Lucene之上的。接下來的故事要說的大部份內容其實是ElasticSearch如何基於Lucene工做的。超詳細 116 頁 Elasticsearch 實戰文檔!高清可下載優化
在Lucene裏面有不少小的segment,咱們能夠把它們當作Lucene內部的mini-index。spa
有着許多數據結構3d
Inverted Index主要包括兩部分:日誌
當咱們搜索的時候,首先將搜索的內容分解,而後在字典裏找到對應Term,從而查找到與搜索相關的文件內容。Elasticsearch 查詢數據的工做原理是什麼?
若是想要查找以字母「c」開頭的字母,能夠簡單的經過二分查找(Binary Search)在Inverted Index表中找到例如「choice」、「coming」這樣的詞(Term)。ElasticSearch 億級數據檢索案例實戰!
若是想要查找全部包含「our」字母的單詞,那麼系統會掃描整個Inverted Index,這是很是昂貴的。
在此種狀況下,若是想要作優化,那麼咱們面對的問題是如何生成合適的Term。
對於以上諸如此類的問題,咱們可能會有幾種可行的解決方案:
* suffix -> xiffus *
若是咱們想之後綴做爲搜索條件,能夠爲Term作反向處理。
(60.6384, 6.5017) -> u4u8gyykk
對於GEO位置信息,能夠將它轉換爲GEO Hash。
123 -> {1-hundreds, 12-tens, 123}
對於簡單的數字,能夠爲它生成多重形式的Term。
一個Python庫 爲單詞生成了一個包含錯誤拼寫信息的樹形狀態機,解決拼寫錯誤的問題。
當咱們想要查找包含某個特定標題內容的文件時,Inverted Index就不能很好的解決這個問題,因此Lucene提供了另一種數據結構Stored Fields來解決這個問題。本質上,Stored Fields是一個簡單的鍵值對key-value。默認狀況下,ElasticSearch會存儲整個文件的JSON source。
即便這樣,咱們發現以上結構仍然沒法解決諸如:排序、聚合、facet,由於咱們可能會要讀取大量不須要的信息。
因此,另外一種數據結構解決了此種問題:Document Values。這種結構本質上就是一個列式的存儲,它高度優化了具備相同類型的數據的存儲結構。
爲了提升效率,ElasticSearch能夠將索引下某一個Document Value所有讀取到內存中進行操做,這大大提高訪問速度,可是也同時會消耗掉大量的內存空間。
總之,這些數據結構Inverted Index、Stored Fields、Document Values及其緩存,都在segment內部。
搜索時,Lucene會搜索全部的segment而後將每一個segment的搜索結果返回,最後合併呈現給客戶。
Lucene的一些特性使得這個過程很是重要:
當ElasticSearch索引一個文件的時候,會爲文件創建相應的緩存,而且會按期(每秒)刷新這些數據,而後這些文件就能夠被搜索到。
隨着時間的增長,咱們會有不少segments,
因此ElasticSearch會將這些segment合併,在這個過程當中,segment會最終被刪除掉
這就是爲何增長文件可能會使索引所佔空間變小,它會引發merge,從而可能會有更多的壓縮。
有兩個segment將會merge
這兩個segment最終會被刪除,而後合併成一個新的segment
這時這個新的segment在緩存中處於cold狀態,可是大多數segment仍然保持不變,處於warm狀態。
以上場景常常在Lucene Index內部發生的。
ElasticSearch從Shard中搜索的過程與Lucene Segment中搜索的過程相似。
與在Lucene Segment中搜索不一樣的是,Shard多是分佈在不一樣Node上的,因此在搜索與返回結果時,全部的信息都會經過網絡傳輸。
須要注意的是:
1次搜索查找2個shard = 2次分別搜索shard
當咱們想搜索特定日期產生的日誌時,經過根據時間戳對日誌文件進行分塊與索引,會極大提升搜索效率。
當咱們想要刪除舊的數據時也很是方便,只需刪除老的索引便可。
在上種狀況下,每一個index有兩個shards
shard不會進行更進一步的拆分,可是shard可能會被轉移到不一樣節點上
因此,若是當集羣節點壓力增加到必定的程度,咱們可能會考慮增長新的節點,這就會要求咱們對全部數據進行從新索引,這是咱們不太但願看到的,因此咱們須要在規劃的時候就考慮清楚,如何去平衡足夠多的節點與不足節點之間的關係。
每一個節點,每一個都存留一份路由表,因此當請求到任何一個節點時,ElasticSearch都有能力將請求轉發到指望節點的shard進一步處理。
Query有一個類型filtered,以及一個multi\_match的查詢
根據做者進行聚合,獲得top10的hits的top10做者的信息
這個請求可能被分發到集羣裏的任意一個節點
這時這個節點就成爲當前請求的協調者(Coordinator),它決定:
ElasticSearch 會將Query轉換成Lucene Query
而後在全部的segment中執行計算
對於Filter條件自己也會有緩存
但queries不會被緩存,因此若是相同的Query重複執行,應用程序本身須要作緩存
因此,
搜索結束以後,結果會沿着下行的路徑向上逐層返回。
來源:https://www.cnblogs.com/richa...