既然你點進來了,說明你了解過ES或者是對ES感興趣,這一篇目的在於掃盲,主要以概念理解為主,可能會比較枯燥,但是天將降大任於斯人也,必先...
這篇我以ElasticSearch是什麼、底層原理、特點和應用場景三部分來讓大家入門ElasticSearch
文章末尾白嫖es學習腦圖,要個關注不過分吧?
了解ElasticSearch
先看看排名,很強的位置吧,學起來,讓你薪資翻啊翻,一個月因為學會了一門技術多領個幾千塊薪資難道不香嗎?
ElasticSearch,大家可能都是聽說過它是個用於做搜索的,也有可能是可能沒聽過,不知道大家對它的認知達到什麼程度呢?如果你是沒聽說過或者是只是了解,這篇文章正好適合你,帶你真正學習ElasticSearch,如果你用的比較多,也可以讀讀,查漏補缺,廢話少說,我們開始吧
1、ElasticSearch是什麼?
ElasticSearch是一個實時的分布式存儲、搜索和分析的引擎
Elasticsearch is a real-time, distributed storage, search, and analytics engine什麼是搜尋引擎?所謂搜尋引擎,就是根據用戶需求和一定的算法,運用特定策略從網際網路檢索出制定信息反饋給用戶的一種搜索技術
國內搜尋引擎有百度、360、搜狗等,國外的有谷歌、雅虎、Yandex這些
ElasticSearch是用Java語言編寫的,基於Restful接口的,使用Json格式存儲數據(屬於文檔存儲)的一款分布式全文檢索框架。千言萬語不如一張圖,這是es和mysql的對比(大家應該對mysql很熟悉了吧!)
索引index:可以把索引index比作mysql中的資料庫,索引名稱必須為小寫,索引是一個邏輯命名空間映射到一個或多個主要的分片,可以有零個或多個副本分片
類型type:把類型type比作比作mysql中的一張表,但是從es6.0版本默認type是log,後續版本將不再使用type這個概念
文檔document:可以被檢索的最小單元,類似於資料庫mysql中的一條記錄,可以包含多個欄位,使用json格式和服務端交互
除了上面三個主要的,還有一些ElasticSearch中的名詞,一起理解下
欄位Field:類似於mysql中的column,文檔中包含的一組欄位或者是鍵值對,欄位的值可以是一個簡單的(標量)值(如字符串,整數,日期),或者一個嵌套的結構就像一個數組或對象
映射Mapping:像是mysql中的模式定義,每個索引有一個映射,定義了索引中各個Field的類型,映射可以自己定義,也可以自動生成
DSL:相當於資料庫的SQL,可用來查詢讀取數據
集群Cluster:一個集群包含一個或多個分配了相同的集群名稱的節點。每個集群都有一個主節點是集群自動選擇產生,並且可以決定如果當前主節點失敗,哪些可以替換
節點Node:節點是屬於elasticsearch群集的運行實例。測試的時候,在一臺伺服器可以啟動多個節點,但通常情況下應該在一臺伺服器運行一個節點。在啟動時,節點將使用單播(或組播,但是必須指定)來發現使用相同的群集名稱的群集,並會嘗試加入集群
切片Shards:即把一個大文件分割成多個小文件然後分散到集群中的多個節點上,可以類比mysql中的分庫和分表,這樣做好處就是可以把索引較大的數據分散到多臺伺服器上,減少壓力,可以調動整個集群的資源,處理效率也會提高,默認情況下es會將用戶的index拆分成5個shard,也可以在創建索引的時候通過number_of_shards參數指定shard的數量(注意:索引一旦創建,shard值是不可變的)
副本Replicas:即某個文件的拷貝,就是備份數據,兩個文件一模一樣,保證數據不會因為誤刪而導致丟失,查詢的時候兩個都可以查看,也可以提高查詢效率
replica是相對與shard而言的,一般成對使用,比如你有一個索引,shard設置為5,replica設置為1,那麼總的切片數為shard(5) + shard(5) * replicas(1) = total(10);如果有5臺data節點,每臺節點上都會存儲兩個不相同的shard,這樣某臺data節點壞掉集群能從其它節點上保存了整個index的5個shard,所以不影響正常使用;一旦有新的節點加入,集群可以從其它節點將shard再次存儲在該節點,從而保證集群高可用性
replica可在index創建後更改,其值越大搜索效率越高,但寫入性能越低(一條數據寫入操作需要做(1+replicas)遍),具體值與集群data節點數量相關,不宜超過【data節點數-1】
2、ElasticSearch底層原理
我們可能聽過es底層是採用Lucene設計的,也聽過倒排索引這種名詞,或許你也可能聽過什麼分詞、中文分詞器這些,到底怎麼一回事呢?
接下來我們從倒排索引、分詞這兩部分來了解es到底是如何設計的
倒排索引VS正排索引
舉一個例子,現在有ID為1、2、3、4的四個文檔
ID
VALUE
1
一個程式設計師2一個公眾號程序控3
程式設計師瀏覽程序控的文章4程式設計師關注公眾號程序控我們有上面幾條數據,如果是正排索引存儲會以ID作為索引,來查詢相應的數據,假如我想查詢含有程序控的數據,底層需要遍歷所有的數據,判斷是否符合標準,如果數據量很大,則會導致經常性的全表掃描,有人是不是要說,我把這個欄位設置成索引就可以加速查詢了?
告訴你不是的,你想想在mysql中我要是用like進行模糊查詢一定會走索引嗎,不一定,如果你用前導模糊查詢"%程序控"這種則不會走索引,如果用非前導模糊查詢"程序控%"則會走索引,你可以去用explain去實踐下,實踐出真知
正排索引會導致全表掃描,效率低下,於是倒排索引登場了,還是看上面例子,就會變成
詞條
ID
一個
1、2程式設計師
1、3、4
關注
4瀏覽
3公眾號
2、3、4
程序控
2、3、4
的
3
文章
3我相信你應該已經明白一二了這個時候,倒排表以字或詞為關鍵字進行索引,表中關鍵字所對應的記錄表項記錄了出現這個字或詞的所有文檔,一個表項就是一個字表段,它記錄該文檔的ID和字符在該文檔中出現的位置情況
由於每個字或詞對應的文檔數量在動態變化,所以倒排表的建立和維護都較為複雜,但是在查詢的時候由於可以一次得到查詢關鍵字所對應的所有文檔,所以效率高於正排表。在全文檢索中,檢索的快速響應是一個最為關鍵的性能,而索引建立由於在後臺進行,儘管效率相對低一些,但不會影響整個搜尋引擎的效率
正排索引是從文檔到關鍵字的映射(已知文檔求關鍵字),倒排索引是從關鍵字到文檔的映射(已知關鍵字求文檔)分詞
在上面的倒排索引中你可能會存在一個問題,我怎麼知道它是關注、程式設計師、公眾號這樣分詞的呢?為什麼不能是關注程這樣分詞?
es裡面可以指定分詞器,根據大量的數據算法來對中文進行分詞,讓es可以更聰明的知道如何對中文分詞,es默認的標準分詞器對中文的分詞不是很友好,會將中文詞語拆分成一個個中文的漢字,因此這裡引入別的中文分詞器,應用最多的是ik中文分詞器,而且我們也可以自己配置特定的詞庫
es的數據結構
es會根據分詞器對我們的內容進行分詞,也就是上圖中的Ada、Allen、Sara、Selena這些,這些分詞彙總起來叫做Term Dictionary裡面,每一個分詞對應的文檔ID則存儲在PostingList中,由於Term Dictionary中的詞會越來越多,所以這裡會對Term Dictionary進行排序,查找的時候則根據二分法來查找,不需要遍歷整個Dictionary
正是由於Dictionary中詞很多,我們不能把所有詞都放在內存中,於是es又加了一層Term index,這裡可以存儲詞語的前綴,Term Index這塊會存儲在內存中,所以速度會很快,Term Index在內存中是以FST(Finite State Transducers)形式保存的,會很節省內存
FST的兩個優點:
PostingList也有對應的優化,PostingList使用FOR編碼技術對裡邊的數據進行壓縮,節約磁碟空間
PostingList裡邊存的是文檔ID,檢索的時候經常需要對文檔的ID進行交集和併集的操作,比如多個條件檢索,PostingList使用Roaring Bitmaps來對文檔ID進行交併集操作,
使用Roaring Bitmaps(一種基於BitMaori的數據結構和壓縮算法)的好處是可以節省空間和快速得出交併集的結果,感興趣的可以去研究一波
3、特點和應用場景
其實我覺得看了上面那些,特點應該大家也能知道個七七八八了,接下來我來總結下
支持快速的全文檢索引擎和數據分析引擎(倒排索引和分詞技術)
可以作為一個大型分布式集群,處理PB級數據,也可以運行單機服務小公司
底層是基於Lucene封裝的,使用json格式存儲數據
同義詞處理、相關度排名、海量數據的近實時處理
不支持事務,還有各種聯機事務型的操作
場景一:使用ElasticSearch作為主要的後端,作為搜尋引擎
在傳統的項目中,搜尋引擎是部署在成熟的數據存儲的頂部,因為早期的搜尋引擎不能提供存儲或者其他的功能,我們只是為了提高快速檢索能力引入
Es提供持久存儲、統計等多項強大的功能,是一款現代的搜尋引擎,如果你剛開始一個新項目,可以考慮用es作為唯一數據存儲,這樣設計會更簡單,但是這種情況需要個人斟酌是否符合應用場景,場景不支持頻繁更新、事務等操作
舉個例子:新建的一個博客系統使用es作為存儲,我們可以向es提交新的博文存儲,使用es進行檢索、統計數據等
場景二:在現有系統增加ElasticSearch
由於ES不能提供存儲的所有功能,一些場景下需要在現有系統數據存儲的基礎上新增ES支持
場景三:使用ElasticSearch和現有的工具
在一些使用情況下,您不必寫一行代碼就能通過elasticssearch完成一項工作。很多工具都可以與Elasticsearch一起工作,所以你不必到你從頭開始編寫。
白嫖
例如,假設要部署一個大規模的日誌框架存儲,搜索,並分析了大量的事件。
如圖下圖,處理日誌和輸出到Elasticsearch,您可以使用日誌記錄工具,如rsyslog,Logstash,或Apache Flume(http://flume.apache.org),搜索和可視化界面分析這些日誌,你可以使用Kibana白嫖一時爽,一直白嫖一直爽
(來源https://blog.csdn.net/laoyang360/article/details/89716974)