〈一〉ElasticSearch的介紹

發表日期:2019年9月18日java


什麼是ElasticSearch


ElasticSearch是一個集數據存儲數據搜索數據分析爲一體的系統。它是分佈式的,因此能利用分佈式來提升其處理能力,具備高可用性和高伸縮性。若是你須要一個可以提供高性能的搜索服務的系統,那麼它或許是一個好的選擇。mysql

  • 數據存儲:是指它可以以JSON格式來存儲數據。若是你不在乎數據的搜索,你甚至能夠像相似使用mongodb那樣來單純把它做爲一個數據存儲系統使用。
  • 數據搜索:是指它可以對JSON格式的數據進行全文檢索等搜索。
  • 數據分析:是指它可以利用一些算法來對JSON文檔數據進行分析,好比得出某個月的商品銷售增加量。




核心能力

ElasticSearch是一個搜索系統,搜索就是從數據集合中搜索出咱們想要的數據,例如從大量的商品數據中搜索出咱們想要的某類商品。
  如今提一個需求,例如我有一個「文章」的表,我想搜索文章表中字段content中包含有'java'的數據。
若是你不使用ES,那麼從開發角度來講,日常咱們都是使用關係型數據庫系統來存儲數據,而後使用相似select name,age,address from student where name like '%李%'的語句經過模糊匹配來搜索符合指定條件的數據的。(對應到上面的需求應該是select name,author,content from article where content like '%java%'算法

 但其實上面這種基於模糊匹配的搜索方式的效率是比較低的,由於數據庫系統的搜索一般是逐一掃描的,也就是從頭至尾的來嘗試匹配,某個字段的數據越多,可能須要嘗試匹配的次數就會越多(試想一下從4000字的文章中從上到下只爲找到一個字),這種查找就好像最低級的遍歷查找(固然並非真的就是傻傻的遍歷了,各個數據庫系統都會採用各類算法來優化)。
 
 而ElasticSearch因爲其內部創建了每一個詞的索引表,當搜索某個詞時,能夠根據這個詞從索引表中找到匹配的記錄,因此效率比較高(就好像記錄了某個詞的座標,有了座標,就能根據座標很是快地找到那個詞)。
(這裏舉個相似的栗子:相信你們都用過字典,那麼普通的數據庫搜索就好像從第一頁到最後一頁找一個詞,而ElasticSearch根據這個詞的部首結構從「部首-字的對應表」中直接查找到那個字的頁數,這個效率直接就是天差地別了!)sql

 另外,數據庫的搜索是根據指定詞直接查找的,它是很笨的!它不能查找到某些意義上「相似」的結果,好比我搜索「mother」,但若是某個記錄中包含「mom」這個詞,那這條記錄也應該被展現出來,而數據庫的普通搜索作不到。
 而這個操做ElasticSearch就能夠作到,因爲它內部有分詞器,在創建索引的過程當中,分詞器能夠把數據中的某些詞都認爲是指定的某一個詞(好比把mother,mom統統都使用mom做爲索引詞),再用這個詞來創建索引,而後在進行搜索的時候,將輸入的詞也進行一樣的轉化,再根據這個詞從索引表中查找到符合的記錄結果,這樣就能夠把那些意義相近的結果也搜索出來。mongodb

因此說,ElasticSearch解決了普通全文搜索的搜索效率低下和搜索不智能的問題。typescript




ES的搜索核心

介紹兩個搜索方法:順序掃描查找、全文搜索數據庫

上面有說到數據庫的搜索和ElasticSearch的搜索。
常見的關係型數據庫的針對某個字段中的數據的搜索是順序掃描查找,從頭至尾去嘗試匹配,也就是所謂的遍歷查找,固然算法可能沒有那麼低級。(如今一些數據庫系統也在嘗試優化全文搜索功能。)json

而ElasticSearch的搜索是全文搜索,而什麼是全文搜索?
全文搜索能夠根據必定方式把非結構化的數據對應到一種結構化的標識,從而能夠經過標識來檢索到指定的非結構化的數據記錄。
這句話可能有點難以理解,舉個例子理解,好比有一大堆食物你須要去認識,食物自己能夠被認做是非結構化的數據,由於他們都是獨特的,但若是咱們利用他們的顏色來劃分的話就能夠初步地將他們進行結構化劃分,這個就是一種簡單的將數據結構化的手段。在ElasticSearch中,這個把非結構化的數據對應到一種結構化的標識的方式就是倒排索引,下面介紹倒排索引來理解這個概念。windows

在ElasticSearch中,處理這些非結構化的數據的方式就是創建倒排索引(Inverted Index)。
什麼是倒排索引呢?
倒排索引把數據進行了拆分(好比某個字段的數據爲hello world,那麼就會被拆分紅hello和world),咱們使用這些拆分的詞來做爲索引詞來創建索引表,在以hello爲索引詞的記錄中,有對hello world的指向,world也是如此。
固然,這裏的拆分並非真實的拆分,原始的數據依然存儲在elasticsearch中,咱們另外建立了一個索引文件來存儲。

下面是一個使用倒排索引搜索的示例
1.首先,假設咱們有一個字段的數據是"I thank my mother",當咱們把這個數據存儲到ElasticSearch中,ElasticSearch內部使用分詞器進行處理數據,分詞器用於將非結構化數據中的詞進行拆分和轉換,因而把"I thank my mother"拆解成了"I"、"thank"、"my"、"mother"。

2.當把數據拆分出來後(拆分紅的數據單位咱們稱爲「詞」),就會把這些詞創建索引,ElasticSearch內部有一個索引表,用於創建詞與數據的對應,結構相似以下(真實格式還會有詞的頻率、數據長度等信息),索引表存儲了詞和詞所在記錄的ID集合,因此能夠經過某個詞來快速搜索出相關的記錄,好比搜索"I",那麼會返回1和2,而後能夠快速根據ID來獲取對應的數據。【請注意,下圖只是方便理解,並非真實的格式】

3.而後咱們搜索的時候,分詞器也先把咱們輸入的內容處理(爲了與索引表的詞統一),而後再從索引表中查找,返回對應的數據記錄集合。
例如我輸入mother,mother會先轉成mom,而後從索引表中找到mom,返回包含mom的記錄的ID,而後根據ID獲取對應數據,也就是「I like my mom」




搜索引擎選擇

Lucene也是一種搜索引擎,爲何不直接使用Lucene?
ElasticSearch實際上底層使用的就是Lucene,雖然Lucene也有不少功能,但Lucene的使用難度較大(也正是使用難度高因此ElasticSearch纔對Lucene進行封裝),並且ElasticSearc的高級功能也很強大,ES支持了多樣的數據分析。除了基本的功能,集羣能力也是一個問題,Lucene一開始沒有考慮集羣,因此對於存儲在不一樣服務器上的大量數據的交互比較麻煩,而ElasticeSearch一開始就是集羣思想的,數據存儲以一個ElasticSearch節點爲單位,多個節點的數據能夠交流。
因爲底層是Lucene,因此,對於一些elasticsearch底層的東西,有時候你徹底能夠參照Lucene,好比索引詞文件的存儲等。

爲何不是Solr?
Solr也是一個知名的搜索引擎,它與ElasticSearch各有好處,Solr適用於一些非實時搜索系統(新增的數據不要求立刻查出來的),而ElasticSearch適用於一些實時搜索要求較高的系統(電商平臺等要求新商品立刻可查的系統)。由於Solr在創建索引時,搜索效率降低,實時索引搜索效率不高,而ElasticSearch創建索引的速度較快。

ElasticSearch有一個很是顯著的特性"NRT":NRT全稱Near Real Time,近實時,意思是你插入的數據幾乎能夠「立刻」就能夠被搜索出來。這也是爲何它能使用在實時更新要求高的場景的緣由。




搜索的處理

上面提了詞的拆分,這裏提一些關於底層的搜索處理的內容。介紹一下ElasticSearch另外一個協助搜索的關鍵組件--分詞器。ElasticSearch的全文搜索離不開分詞器的幫助。

分詞器一般由分解器tokenizer和詞元過濾器token filter組成。

分詞器對數據的分詞處理:爲了提升索引的效率,ElasticSearch會數據進行處理,處理方式主要有字符過濾、詞轉換、詞拆分
字符過濾:過濾一些特殊字符,例如&||、html標籤,由於這些詞一般搜索意義不大。

詞轉換:把一些意義相同的詞統一轉成一個詞,(同詞義轉換)好比mom,mother統一轉成mom;(大小寫轉換)he,He統一歸爲He;還處理一些詞意義不大的詞(停用詞清除),好比英文的「the」,「to」,這些詞使用頻率很高,但沒有具體意義。

詞拆分:進行數據的拆分,拆分紅詞,好比把good morning,mom拆分紅good,morining,mom。另外,詞拆分並不徹底是按照數據的最小單位分解的,某一些分詞器會把一些詞進行組合,由於一些詞的組合起來纔有索引的意義,好比中文的一些詞一般要組合起來纔有意義,好比「大」和「家」要組成「你們」纔有比較具體的意義,這是爲了確保索引詞的最小單位是有意義的(好比英文mom的最小單位是m,o,m,內部的分詞器要可以區分出mom整個是有意義的才能夠確保是採用mom做爲索引,而不是採用m和o,也正是由於這個問題,因此英文分詞器不能用於中文分詞器)。【分詞器有不少個,默認的分詞器是不能適當對中文數據分詞的,它只能把一個個數據按最小的單位拆分,由於英文分詞器不能分清楚怎麼把詞拆分纔有意義,因爲配置分詞器是一個較爲靠後的知識點,因此前期將以英文數據爲測試數據。

分詞文件的存儲:
分詞文件通常包括三種文件:詞典文件,頻率文件,位置文件。
詞典文件保存了關鍵詞(索引詞),還保留了指向頻率文件和位置文件的指針。
頻率文件記錄了詞出現的頻率。
位置文件記錄了這些詞出如今哪些數據中。




補充:

  • 數據庫不是被替代,而是被補充。有時候會將數據同時存儲到數據庫和ElasticSearch中,在單個查看的時候能夠從數據庫中查詢,在搜索的時候從ElasticSearch中查詢;也有的項目因爲數據比較簡單徹底使用elasticsearch來存儲數據。
  • ElasticSearch是分佈式的,但咱們是不須要對其集羣進行部署的,它自動進行了集羣部署和節點發現等功能,咱們只需進行不多的配置就能管理集羣。在比較靠後的內容纔會講到如何深刻管理集羣。

小節總結:

  • 1.本小節簡單講述了ElasticSearch是什麼
  • 2.傳統搜索的不足
  • 3.使用ElasticSearch搜索的好處
  • 4.全文搜索和倒排索引
  • 5.與其餘搜索引擎的比較
  • 6.ElasticSearch對於索引詞的處理(這個內容是提早講的內容,是爲了幫助瞭解倒排索引如何創建索引)

基本學習環境搭建


如何操做ElasticSearch

首先要說的是,ElasticSearch是一款軟件,有點相似MySQL,咱們要操做它的時候,也要給它發送它能識別的命令,而ElasticSearch是面向restful(不知道restful的自查吧)的,因此咱們發送的命令是有點相似發送http請求的。

mysql是3306端口,而elasticsearch支持9200和9300端口操做,其中9200面向http,9300面向tcp。9200可以使用普通的http請求來操做elasticsearch,9300須要鏈接elasticsearch以後再執行命令。

  • 對於9200,由於面向http,因此咱們可使用postman發http請求來操做elasticsearch。
  • 對於9300,由於面向tcp,咱們一般使用一些elasticsearch管理工具(如kibana)進行鏈接elasticsearch以後再執行命令。(相似navicat之於mysql)


下載、安裝和運行(Based Windows)



咱們首先來搭建好學習環境,主要是ElasticSearch和Kibana。【請注意,Elasticsearch依賴Java環境】
【Kibana是可選的,下面會介紹一下基於postman的對ElasticSearch操做。】,Kibana是一款對ElasticSearch進行管理的軟件,咱們能夠在Kibana上執行ElasticSearch的命令。

下載:


  • ElasticSearch下載:ElasticSearch下載【這裏以6.2的爲例】
  • Kibana下載:Kibana下載 【兩個下載都是同一個位置,這裏下載以6.2的爲例】【Kibana的版本儘可能與ElasticSearch的一致,有些版本會鏈接錯誤】


安裝:

  • 兩個軟件都是不須要安裝的,下載後,直接解壓便可。

運行:

  • 對於ElasticSearch,能夠直接在elasticsearch-6.2.0\bin中運行elasticsearch.bat,當提示「started」時,表示運行成功。
  • 對於Kibana,能夠直接在kibana-6.2.0-windows-x86_64\bin中運行kibana.bat,當提示「Server running at http://localhost:5601」時,表示運行成功。【要先運行ElasticSearch再運行Kibana,由於它要與ElasticSearch進行鏈接】



如何操做ES

ElasticSearch默認的TCP服務端口是9300,Kibana的服務端口是5601,當咱們啓動了Kibana以後,它會默認幫咱們鏈接上9300,因此咱們能夠從http://localhost:5601中進入Kibana的管理界面來管理ElasticSearch。
若是你是第一次使用,那麼ElasticSearch會自動建立一個名爲elasticsearch的集羣,Kibana會在這個節點中初始化一個index


咱們在Kibana的DevTools中執行一些命令來看一下ElasticSearch。【從http://localhost:5601中進入】



在輸入命令GET /_cat/health?v後,點擊該行右側的執行按鈕。【GET /_cat/health?v是查看集羣的健康狀態的命令】

而後就能夠在右側的結果窗口中查看命令執行結果。

【你如今大概都是看不懂命令的意義和結果的意義的了,不過你應該知道哪裏輸入命令哪裏看執行結果了】



基於postman操做

postman是一個用來發請求的軟件,可使用restful風格的請求來操做elasticsearch。
好比上面的查看集羣的命令:GET /_cat/health?v
轉成基於restful的是:http://localhost:9200/_cat/health?vIP:9200+命令,其中9200是用於接收restful請求的es監聽端口。


補充:

上面的第一次使用並無涉及到具體的知識,只是讓你熟悉一下如何使用Kibana來操做ElasticSearch。下面講到具體知識點纔會具體使用。

小節總結

  • 1.講了ES如何提供服務:9200,9300
  • 2.講了如何下載、安裝、運行ElasticSearch和Kibana
  • 3.講述瞭如何在Kibana中操做ElasticSearch
  • 4.講述瞭如何在postman中操做ElasticSearch

須要瞭解的概念


分佈式模型相關

  • 集羣Cluster:所謂集羣,就是多個服務節點的集合,集羣意味着這些節點是可以相互交流的,否則沒法進行數據交互。集羣的默認名稱是"elasticsearch",多個提供服務的節點會根據集羣名來自動加入集羣
  • 節點Node:節點是集羣的一部分,是集羣的最小單元,是能夠提供服務的節點。
  • 分片shard:分片位於節點上,分片是elasticsearch數據存儲的單元,elasticsearch中的數據會存儲在分片中。分片能夠存儲在任意一個節點上。分片分爲主分片Primary Shard和副本分片Replica Shard。
  • 主分片Primary Shard:當存儲一個文檔document的時候,會先存儲到主分片中,而後再複製到其餘的副本分片Replica Shard中。
  • 副本分片Replica Shard:副本分片是主分片的複製(備份)。默認狀況下,主分片有一個副本分片,主分片不能修改,但副本分片能夠後續再增長。
    • 爲了保證數據的不丟失,一般來講Replica Shard不能與其對應的Primary Shard處於同一個節點中。【由於萬一這個節點損壞了,那麼存儲在這個節點上的原數據(primary shard)和備份數據(replica shard)就所有丟失了】
    • 當主分片掛掉的時候,會選擇一個副本分片做爲主分片。
    • 查詢能夠在主分片或副本分片上進行查詢,這樣能夠提供查詢效率。【但數據的修改只發生在主分片上。】
    • 一個Primary Shard能夠有多個Replica Shard,默認建立是1個。


數據存儲相關

數據存儲在shard中,shard中的數據是以文檔document爲單位的。document存儲在index和type劃分的邏輯空間中。document以json爲格式,每個key-value中key能夠稱爲域Field。

  • 索引Index:索引是存儲具備相同結構的document的集合,意義上有點相似關係型數據庫中的數據庫,用於存儲一系列數據,好比能夠說「商品」索引,通常都是個大類,小邏輯劃分由Type處理。
  • 類型Type:類型是索引的邏輯分區,意義有點相似關係型數據庫中的數據表。用來劃分索引下不一樣子類型的數據,好比商品(索引)能夠有電子產品(類型),藥品(類型)。在同一個分類下的數據通常都具備同種特徵,用來定義數據的字段的數量通常也是相同的。每個document都有一個type和一個id,在存儲文檔的時候須要指定索引、類型和ID。
  • 文檔Document:相似於關係型數據庫中的記錄,是ElasticSearch的數據存儲的基本單位,格式與JSON相同。例如:
{
  "book_id": 1,
  "book_name": "Java Core ",
  "book_desc": "A good book, you know!",
  "category_id": "1",
  "category_name": "Computer"
}
  • 域Field:相似於關係型數據庫中的字段。
  • elasticsearch是面向restful的,下面是restful請求與elasticsearch操做的對應:
請求方法 對應操做 說明
GET 讀取 獲取數據
POST 新增 新增數據
PUT 修改 修改數據或增長數據
DELETE 刪除 刪除數據
  • 索引用來存儲數據,分片也是用來存儲數據,它們是怎麼對應的?一個索引存儲在多個分片上,默認狀況下,一個索引有五個主分片,五個副本分片。主分片的數量一旦定下來就不能再修改,但副本分片的數量還能夠修改。




小節總結

  • 講了一下ElasticSearch的集羣概念,節點是集羣的基礎服務單位,節點能夠提供數據讀寫服務,數據按分片來存儲,主分片是主要數據,能夠讀取和修改數據,副本分片不支持修改數據。
  • 主分片和副本分片的互斥性(爲了保證數據不一樣時丟失)
  • elasticsearch的數據的邏輯存儲結構(索引->類型->文檔)。索引是數據的大分類,類型是數據的小分類。
  • 文檔的格式
  • 索引與分片的關係。一個索引存儲在多個分片上

Hello ElasticSearch


前面提了一下index,type,document,說了ElasticSearch的邏輯存儲空間。
下面以兩個實例:「寫document->讀document」和「寫document->搜索document「來初步演示一下如何存儲數據和獲取數據。


寫->讀

若是咱們要向ElasticSearch中寫入一份數據(document),命令的語法應該以下:

PUT /index名稱/type名稱/document的ID
{
    document的數據
}

上面的語法的意思就是向一個index的一個type中插入一個document,document用id做爲標識,後面咱們取document的數據也將以這個id爲依據。其中index,type是能夠不須要咱們預建立的,在咱們還不會如何建立index和type的時候,你能夠先隨便打個名字(若是ElasticSearch檢測到咱們輸入的index和type是不存在的,那麼它就會以默認的規則幫咱們建立出來)。

請在kibana的devtool中執行如下命令來存儲一份document:

PUT /douban/book/1
{
  "book_id":1,
  "book_name":"A Clockwork Orange",
  "author":"Anthony Burgess",
  "summary":"Fully restored edition of Anthony Burgess' original text of A Clockwork Orange, with a glossary of the teen slang 'Nadsat', explanatory notes, pages from the original typescript, interviews, articles and reviews Edited by Andrew Biswell With a Foreword by Martin Amis 'It is a horrorshow story ...' Fifteen-year-old Alex likes lashings of ultraviolence. He and his gang of friends rob, kill and rape their way through a nightmarish future, until the State puts a stop to his riotous excesses. But what will his re-education mean? A dystopian horror, a black comedy, an exploration of choice, A Clockwork Orange is also a work of exuberant invention which created a new language for its characters. This critical edition restores the text of the novel as Anthony Burgess originally wrote it, and includes a glossary of the teen slang 'Nadsat', explanatory notes, pages from the original typescript, interviews, articles and reviews, shedding light on the enduring fascination of the novel's 'sweet and juicy criminality'. Anthony Burgess was born in Manchester in 1917 and educated at Xaverian College and Manchester University. He spent six years in the British Army before becoming a schoolmaster and colonial education officer in Malaya and Brunei. After the success of his Malayan Trilogy, he became a full-time writer in 1959. His books have been published all over the world, and they include The Complete Enderby, Nothing Like the Sun, Napoleon Symphony, Tremor of Intent, Earthly Powers and A Dead Man in Deptford. Anthony Burgess died in London in 1993. Andrew Biswell is the Professor of Modern Literature at Manchester Metropolitan University and the Director of the International Anthony Burgess Foundation. His publications include a biography, The Real Life of Anthony Burgess, which won the Portico Prize in 2006. He is currently editing the letters and short stories of Anthony Burgess.",
  "press":"Penguin Classic",
  "publication_date":"2000-02-22"
}

若是要獲取ES中存儲的document,命令的語法應該以下:

GET /index名/type名/id

同樣的,請在kibana中執行下述命令來獲取咱們上面存儲的document:

GET /douban/book/1

返回結果:【返回index名稱,type名稱,id,原始文檔等數據】

很明顯地,咱們獲取到了咱們剛剛存儲進去的數據。


寫->搜索

同樣的,咱們寫多一份數據進ES中:

PUT /douban/book/2
{
  "book_id":2,
  "book_name":"Kubernetes in Action",
  "author":"Marko Luksa",
  "summary":"Kubernetes in Action teaches you to use Kubernetes to deploy container-based distributed applications. You'll start with an overview of Docker and Kubernetes before building your first Kubernetes cluster. You'll gradually expand your initial application, adding features and deepening your knowledge of Kubernetes architecture and operation. As you navigate this comprehensive guide, you'll explore high-value topics like monitoring, tuning, and scaling.Kubernetes is Greek for \"helmsman,\" your guide through unknown waters. The Kubernetes container orchestration system safely manages the structure and flow of a distributed application, organizing containers and services for maximum efficiency. Kubernetes serves as an operating system for your clusters, eliminating the need to factor the underlying network and server infrastructure into your designs.",
  "press":"Manning Publications",
  "publish_date":"2017-08-31"
}

下面將演示搜索的功能,搜索的其中一種語法是:

GET /index名/type名/_search
{
    "query":{
        "match":{
            "字段Field名稱":"用於搜索的關鍵字"
        }
    }
}

那麼,根據咱們以前存儲的數據,若是咱們要查詢summary字段有Orange的數據的話,命令以下:

GET /douban/book/_search
{
  "query": {
    "match": {
      "summary":"Orange"
    }
  }
}

返回的結果:


小節總結

  • 這小節涉及到了數據的插入,讀取,搜索,但僅僅是一個Hello ElasticSearch的例子,因此沒有講到插入數據應該有的前置知識。理論上,你只須要記得這個流程便可。後面會補充這個流程中沒有提到的內容。

--To Be Continue

相關文章
相關標籤/搜索