1. 程式人生 > >Elasticsearch教程-從入門到精通

Elasticsearch教程-從入門到精通

各位運維同行朋友們,大家好,非常高興能有這麼個機會與大家一起交流一些技術問題。此前的各位分享達人們在技術領域或管理領域均有十分精彩的分享,他們帶給我們的是多個領域中研究或實踐的最前沿知識。這使我本人獲益良多,首先要鄭重感謝他們。

   開始之前,本人首先做一下自我介紹。

   馬永亮,馬哥Linux運維培訓創始人,已直接培養Linux運維工程師一千多人,他們絕大多數從事Linux運維和相關管理崗位,就業公司包括但不限於阿里、騰訊、百度、京東、網易、新浪、搜狐、大眾點評、餓了麼等。課程的間接受益者數萬人。

   這些一線的運維或運維開發工程師不斷地將知識、經驗或應用趨勢等反饋給我們,也因此,我們的課程體系也發展為了快速迭代和演進的模式。另外,不斷地通過各種渠道指導他們解決實踐中的問題的經驗也成為課堂中案例的組成部分。

   比如今天的分享,沿用我們的一貫方式,初衷是為那些不甚瞭解、即將或剛用到ELK stack的朋友們提供一個可落地的思路和實踐方法。而ELK達人們還請多批評指正。

   下面進入正題。今天的分享共分為如下幾個組成部分。不過,如果時間上來不及,可能只會聊前兩個而不及其餘。

    1、搜尋引擎元件介紹;
    2ElasticSearch工作原理、查詢及常用外掛;
    3、日誌收集器Logstash及常見的同類工具;
    4、視覺化工具Kibina
    5、使用案例及優化思路;

一、關於搜尋引擎

   各位知道,搜尋程式一般由索引鏈及搜尋元件組成。

   索引鏈功能的實現需要按照幾個獨立的步驟依次完成:檢索原始內容、根據原始內容來建立對應的文件、對建立的文件進行索引。

   搜尋元件用於接收使用者的查詢請求並返回相應結果,一般由使用者介面、構建可程式設計查詢語句的方法、查詢語句執行引擎及結果展示元件組成。

   如圖所示。

wKiom1ZMnkiTRk5LAAD-r_io_HQ515.jpg

   著名的開源程式Lucene是為索引元件,它提供了搜尋程式的核心索引和搜尋模組,例如圖中的“Index”及下面的部分;而ElasticSearch則更像一款搜尋元件,它利用Lucene進行文件索引,並向用戶提供搜尋元件,例如“Index”上面的部分。二者結合起來組成了一個完整的搜尋引擎。

二、索引元件

   索引是一種資料結構,它允許對儲存在其中的單詞進行快速隨機訪問。當需要從大量文字中快速檢索文字目標時,必須首先將文字內容轉換成能夠進行快速搜尋的格式,以建立針對文字的索引資料結構,此即為索引過程。

   它通常由邏輯上互不相關的幾個步驟組成。

   第一步:獲取內容。

   過網路爬蟲或蜘蛛程式等來蒐集及界定需要索引的內容。Lucene並不提供任何獲取內容的元件,因此,需要由其它應用程式負責完成這一功能,例如著名的開源爬蟲程式SolrNutchGrubAperture等。必要時,還可以自行開發相關程式以高效獲取自有的特定環境中的資料。獲取到的內容需要建立為小資料塊,即文件(Document)

   第二步:建立文件。

   獲取的原始內容需要轉換成專用部件(文件)才能供搜尋引擎使用。

   一般來說,一個網頁、一個PDF文件、一封郵件或一條日誌資訊可以作為一個文件。文件由帶(Value)”(Field)”組成,例如標題(Title)、正文(body)、摘要(abstract)、作者(Author)和連結(url)等。不過,二進位制格式的文件處理起來要麻煩一些,例如PDF檔案。

對於建立文件的過程來說有一個常見操作:向單個的文件和域中插入加權值,以便在搜尋結果中對其進行排序。權值可在索引操作前靜態生成,也可在搜尋期間才動態生成。權值決定了其搜尋相關度。

   第三步:文件分析。

   搜尋引擎不能直接對文字進行索引,確切地說,必須首先將文字分割成一系列被稱為語彙單元(token)的獨立原子元素,此過程即為文件分析。每個token大致能與自然語言中的單詞對應起來,文件分析就是用於確定文件中的文字域如何分割成token序列。

   此即為切詞,或分詞。

   文件分析中要解決的問題包括如何處理連線一體的各個單詞、是否需要語法修正(例如原始內容存在錯別字)、是否需要向原始token中插入同義詞(例如laptopnotebook)、是否需要將大寫字元統一轉換為小寫字元,以及是否將單數和複數格式的單詞合併成同一個token等。這通常需要詞幹分析器等來完成此類工作,Lucene提供了大量內嵌的分析器,也支援使用者自定義分析器,甚至聯合Lucenetoken工具和過濾器建立自定義的分析鏈。

   第四步:文件索引

   在索引步驟中,文件將被加入到索引列表。事實上,Lucene為此僅提供了一個非常簡單的API,而後自行內生地完成了此步驟的所有功能。

   接下來,我們說搜尋元件。

   索引處理就是從索引中查詢單詞,從而找到包含該單詞的文件的過程。搜尋質量主要由查準率(Precision)和查全率(Recall)兩個指標進行衡量。查準率用來衡量搜尋系列過濾非相關文件的能力,而查全率用來衡量搜尋系統查詢相關文件的能力。

   另外,除了快速搜尋大量文字和搜尋速度之後,搜尋過程還涉及到了許多其它問題,例如單項查詢、多項查詢、短語查詢、萬用字元查詢、結果ranking和排序,以及友好的查詢輸入方式等。這些問題的解決,通常需要多個元件協作完成。

     1、使用者搜尋介面

   UI(User Interface)是搜尋引擎的重要組成部分,使用者通過搜尋引擎介面進行搜尋互動時,他們會提交一個搜尋請求,該請求需要先轉換成合適的查詢物件格式,以便搜尋引擎能執行查詢。

     2、建立查詢

   戶提交的搜尋請求通常以HTML表單或Ajax請求的形式由瀏覽器提交到搜尋引擎伺服器,因此,需要事先由查詢解析器一類的元件將這個請求轉換成搜尋引擎使用的查詢物件格式。

     3、搜尋查詢

   當查詢請求建立完成後,就需要查詢檢索索引並返回與查詢語句匹配的並根據請求排好序的文件。搜尋查詢元件有著複雜的工作機制,它們通常根據搜尋理論模型執行查詢操作。常見的搜尋理論模型有純布林模型、向量空間模型及概率模型三種。Lucene採用了向量空間模型和純布林模型。

     4、展現結果

   查詢獲得匹配查詢語句並排好序的文件結果集後,需要用直觀、經濟的方式為使用者展現結果。UI也需要為後續的搜尋或操作提供清晰的嚮導,如完善搜尋結果、尋找與匹配結果相似的文件、進入下一頁面等。

三、Lucene

   Lucene是一款高效能的、可擴充套件的資訊檢索(IR)工具庫,是由Java語言開發的成熟、自由開源的搜尋類庫,基於Apache協議授權。Lucene只是一個軟體類庫,如果要發揮Lucene的功能,還需要開發一個呼叫Lucene類庫的應用程式。

   文件是Lucene索引和搜尋的原子單位,它是包含了一個或多個域的容器,而域的值則是真正被搜尋的內容。每個域都有其標識名稱,通常為一個文字值或二進位制值。將文件加入索引中時,需要首先將資料轉換成Lucene能識別的文件和域,域值是被搜尋的物件。例如,使用者輸入搜尋內容“title:elasticsearch”時,則表示搜尋標題域值中包含單詞“elasticsearch”的所有文件。

   都是文字,大家可能看的眼花。參考一幅從網際網路上獲取的圖片吧。

wKioL1ZMn4ix8Z1WAACYYV0yiYc686.jpg

   如前所述,ElasticSearch在底層利用Lucene完成其索引功能,因此其許多基本概念源於Lucene

四、ES的基本概念

 索引(Index)

   ES將資料儲存於一個或多個索引中,索引是具有類似特性的文件的集合。類比傳統的關係型資料庫領域來說,索引相當於SQL中的一個數據庫,或者一個數據儲存方案(schema)。索引由其名稱(必須為全小寫字元)進行標識,並通過引用此名稱完成文件的建立、搜尋、更新及刪除操作。一個ES叢集中可以按需建立任意數目的索引。

 型別(Type)

   型別是索引內部的邏輯分割槽(category/partition),然而其意義完全取決於使用者需求。因此,一個索引內部可定義一個或多個型別(type)。一般來說,型別就是為那些擁有相同的域的文件做的預定義。例如,在索引中,可以定義一個用於儲存使用者資料的型別,一個儲存日誌資料的型別,以及一個儲存評論資料的型別。類比傳統的關係型資料庫領域來說,型別相當於

 文件(Document)

   文件是Lucene索引和搜尋的原子單位,它是包含了一個或多個域的容器,基於JSON格式進行表示。文件由一個或多個域組成,每個域擁有一個名字及一個或多個值,有多個值的域通常稱為多值域。每個文件可以儲存不同的域集,但同一型別下的文件至應該有某種程度上的相似之處。

wKioL1ZMn7GzUl7gAACDX9Q8RfI251.jpg

   三者關係,如圖中所示。

 對映(Mapping)

   ES中,所有的文件在儲存之前都要首先進行分析。使用者可根據需要定義如何將文字分割成token、哪些token應該被過濾掉,以及哪些文字需要進行額外處理等等。另外,ES還提供了額外功能,例如將域中的內容按需排序。事實上,ES也能自動根據其值確定域的型別。

wKioL1ZMn8XgIKUxAACLaBiFO1o097.jpg

 節點(Node)
   運行了單個例項的ES主機稱為節點,它是叢集的一個成員,可以儲存資料、參與叢集索引及搜尋操作。類似於叢集,節點靠其名稱進行標識,預設為啟動時自動生成的隨機Marvel字元名稱。使用者可以按需要自定義任何希望使用的名稱,但出於管理的目的,此名稱應該儘可能有較好的識別性。節點通過為其配置的ES叢集名稱確定其所要加入的叢集。

 分片(Shard)和副本(Replica)
   ES分片(shard)”機制可將一個索引內部的資料分佈地儲存於多個節點,它通過將一個索引切分為多個底層物理的Lucene索引完成索引資料的分割儲存功能,這每一個物理的Lucene索引稱為一個分片(shard)。每個分片其內部都是一個全功能且獨立的索引,因此可由叢集中的任何主機儲存。建立索引時,使用者可指定其分片的數量,預設數量為5個。 

   Shard有兩種型別:primaryreplica,即主shard及副本shardPrimary shard用於文件儲存,每個新的索引會自動建立5Primary shard,當然此數量可在索引建立之前通過配置自行定義,不過,一旦建立完成,其Primary shard的數量將不可更改。Replica shardPrimary Shard的副本,用於冗餘資料及提高搜尋效能。每個Primary shard預設配置了一個Replica shard,但也可以配置多個,且其數量可動態更改。ES會根據需要自動增加或減少這些Replica shard的數量。

   ES叢集可由多個節點組成,各Shard分散式地儲存於這些節點上。

ES可自動在節點間按需要移動shard,例如增加節點或節點故障時。簡而言之,分片實現了叢集的分散式儲存,而副本實現了其分散式處理及冗餘功能。

   如圖所示。

wKiom1ZMoAiRtgT_AACPe7v-Dhw038.jpg

   ElasticSearchRESTful API通過tcp協議的9200埠提供,可通過任何趁手的客戶端工具與此介面進行互動,這其中包括最為流行的curlcurlElasticSearch互動的通用請求格式如下面所示。

1 2 3 4 5 6 7 curl -X<VERB> '<PROTOCOL>://<HOST>/<PATH>?<QUERY_STRING>' -d '<BODY>' VERB:HTTP協議的請求方法,常用的有GET、POST、PUT、HEAD以及DELETE; PROTOCOL:協議型別,http或https; HOST:ES叢集中的任一主機的主機名; PORT:ES服務監聽的埠,預設為9200; QUERY_STRING:查詢引數,例如?pretty表示使用易讀的JSON格式輸出; BODY:JSON格式的請求主體;

   例如,檢視ElasticSearch工作正常與否的資訊。

1 ~]$ curl 'http://localhost:9200/?pretty'

   與ElasticSearch叢集互動時,其輸出資料均為JSON格式,多數情況下,此格式的易讀性較差。cat API會在互動時以類似於Linuxcat命令的格式對結果進行逐行輸出,因此有著較JSON好些的可讀性。呼叫cat API僅需要向“_cat”資源發起GET請求即可。具體使用方法請查閱官方文件。

   另外,ES叢集的CRUD操作也非常容易進行,朋友們參考官方文件即可。

五、ES中的資料查詢簡介

   需要注意的是,文件中每個域的值可能會儲存為特定型別,而非字串型別,因此,_all域的索引方式與特域的索引方式未必完全相同。

   文件中,域的資料儲存時支援“string”“numbers”“Booleans”“dates”幾種型別,不同型別的資料在索引時是略有區別的。在建立文件時,Elasticsearch會通過檢查域的值來動態為其建立mapping,可通過Mapping API來檢視typemapping,其訪問端點是_mapping

   下面,我們聊一個麻煩一點的問題,ES的精確值、full-text及倒排索引。

   精確值(Exact values)就是指資料未曾加工過的原始值,而Full-text則用於引用文字中的資料。在查詢中,精確值是很容易進行搜尋的,但full-text則需要判斷文件在多大程度上匹配查詢請求,換句話講,即需要評估文件與給定查詢的相關度(relevant)。因此,所謂的full-text查詢通常是指在給定的文字域內部搜尋指定的關鍵字,但搜尋操作該需要真正理解查詢者的目的。

  例如:
   (1) 搜尋“UK”應該返回包含“United Kingdom”的相關文件;
   (2) 搜尋“jump”應該返回包含“JUMP”“jumped”“jumps”“jumping”甚至是“leap”的文件;
   (3) 搜尋“johnny walker”應該匹配包含“Johnnie Walker”的文件;

   為了完成此類full-text域的搜尋,ES必須首先分析文字並將其構建成為倒排索引(inverted index),倒排索引由各文件中出現的單詞列表組成,列表中的各單詞不能重複且需要指向其所在的各文件。因此,為了建立倒排索引,需要先將各文件中域的值切分為獨立的單詞(也稱為termtoken),而後將之建立為一個無重複的有序單詞列表。這個過程稱之為分詞(tokenization)”

wKiom1ZMoMCRhc9pAAEht--Jm_A712.jpg

六、Queries and Filters
 
   儘管統一稱之為query DSL,事實上Elasticsearch中存在兩種DSL:查詢DSL(query DSL)和過濾DSL(filter DSL)。查詢子句和過濾子句的自然屬性非常相近,但在使用目的上略有區別。簡單來講,當執行full-text查詢或查詢結果依賴於相關度分值時應該使用查詢DSL,當執行精確值(extac-value)查詢或查詢結果僅有“yes”“no”兩種結果時應該使用過濾DSL

   Filter DSL計算及過濾速度較快,且適於快取,因此可有效提升後續查詢請求的執行速度。而query DSL不僅要查詢匹配的文件,還需要計算每個檔案的相關度分值,因此為更重量級的查詢,其查詢結果不會被快取。不過,得益於倒排索引,一個僅返回少量文件的簡單query或許比一個跨數百萬文件的filter執行起來並得顯得更慢。

Filter DSL中常見的有term Filterterms Filterrange Filterexists and missing Filtersbool Filter。而Query DSL中常見的有match_allmatch multi_matchbool Query。鑑於時間關係,這裡不再細述,朋友們可參考官方文件學習。

   Queries用於查詢上下文,而filters用於過濾上下文,不過,ElasticsearchAPI也支援此二者合併執行。組合查詢可用於合併查詢子句,組合過濾用於合併過濾子句,然而,Elasticsearch的使用習慣中,也常會把filter用於query上進行過濾。不過,很少有機會需要把query用於filter上的。

   好了,朋友們,今天的分享就先到這裡吧。感謝大家的時間。這些內容是我用來講課的講義精練出的內容,用於微信的方式分享可能顯得過於囉嗦,請大家將就著看啦。

from: http://mageedu.blog.51cto.com/4265610/1714522