摘要: 歡迎來到Elasticsearch的世界並閱讀本書第2版。經過閱讀本書,咱們將帶領你接觸與Elasticsearch緊密相關的各類話題。請注意,本書不是爲初學者寫的。筆者將本書做爲《Elasticsearch Server, Second Edition》的續做和姊妹篇。html
前 言
歡迎來到Elasticsearch的世界並閱讀本書第2版。經過閱讀本書,咱們將帶領你接觸與Elasticsearch緊密相關的各類話題。請注意,本書不是爲初學者寫的。筆者將本書做爲《Elasticsearch Server, Second Edition》的續做和姊妹篇。相對於《Elasticsearch Server》,本書涵蓋了不少新知識,不過你偶爾也能夠在本書中發現一些引自《Elasticsearch Server》的內容。
本書將探討與Elasticsearch和Lucene相關的多個不一樣主題。首先,咱們以介紹Lucene和Elasticsearch的基本概念做爲開始,帶領讀者認識Elasticsearch提供的衆多查詢方式。在這裏,將涉及和查詢相關的不一樣主題,好比結果過濾以及如何爲特定場景選擇合適的查詢方式。顯然,Elasticsearch不只僅只有查詢功能。所以,本書還將介紹Elasticsearch新加入的彙集功能,以及衆多可以賦予被索引數據意義的特性,並設法提供更佳的用戶查詢體驗。
對大多數用戶來講,查詢和數據分析是Elasticsearch最吸引人的部分,不過這些還不是咱們想要探索的所有內容。所以,本書在涉及索引架構時還會試圖跟讀者探討一些額外話題,好比如何選擇合適的分片數和副本數,如何調整分片分配行爲等。當談論Elasticsearch和Lucene之間的關係時,咱們還將介紹不一樣的打分算法、算法之間的差別、如何選擇合適的存儲機制,以及爲何須要作此選擇。
最後,咱們還將觸及Elasticsearch的管理功能,將探討發現和恢復模塊,以及對人類友好的Cat API。Cat API能夠幫助咱們快速獲取相關的運維信息,它的返回數據組織成一種大多數人都易於閱讀的格式,無需進行JSON解析。咱們還將認識和使用部落節點,它可以爲咱們提供在多個節點間聯合查詢的能力。
由於本書的書名,咱們沒法忽略與性能相關的話題,因此咱們決定用整整一章來探討性能。咱們談論了文檔取值及其相關改進,還介紹了垃圾回收器的工做方式,以及在垃圾回收器未能如咱們指望般工做時能夠作些什麼。最後,探討了如何擴展Elasticsearch以應對高索引量和查詢量的場景。
和本書第1版同樣,咱們決定以開發Elasticsearch插件的話題做爲本書結尾。咱們將展現如何構建Apache Maven項目,並開發兩個不一樣類型的插件—自定義REST操做插件和自定義分析插件。
假如你在讀完某些主題後對其產生濃厚的興趣,那麼這本書就是適合你的。但願你在讀完後可以喜歡這本書。
本書主要內容
第1章先介紹Apache Lucene的工做方式,再介紹Elasticsearch的基本概念,並演示Elasticsearch內部是如何工做的。
第2章描述Lucene評分過程,爲何要進行查詢改寫,什麼是查詢模板以及如何使用查詢模板。除此以外,還介紹了過濾器的使用,以及如何爲特定場景選擇合適的查詢方式。
第3章描述了查詢二次評分、多匹配控制,並介紹了用於作查詢分析的各類聚合類型。關鍵詞項聚合和最優詞項聚合能夠根據所含內容片斷對文檔進行歸類。除此以外,還介紹了Elasticsearch的parent-child文檔關係處理,並提供了在Elasticsearch中使用腳本的相關知識。
第4章覆蓋了有關用戶體驗提高的相關話題。本章介紹了查詢建議(suggester),它能幫助修正查詢中的拼寫錯誤並構建高效的自動完成(autocomplete)機制。除此以外,經過實際的案例展現如何經過使用不一樣查詢類型和Elasticsearch的其餘功能來提升查詢相關性。
第5章介紹瞭如下技術:如何選擇合適的分片及副本數,路由是如何工做的,索引分片機制是如何工做的以及如何影響分片行爲。同時介紹了什麼是查詢執行偏好,以及它是如何影響查詢執行的。
第6章描述如何修改Lucene評分以及如何選擇備用的評分算法。本章也介紹了Elasticsearch的準實時搜索和索引,事務日誌的使用,理解索引的段合併,以及如何調整段合併來適應應用場景。在本章最後,還將介紹Elasticsearch的緩存機制和請求打斷器,以免出現內存用盡的故障。
第7章介紹了什麼是發現、網關、恢復模塊,如何配置這些模塊,以及有哪些使人心煩的疑難點。還介紹了什麼是Cat API,如何把數據備份到各類雲服務上(好比亞馬遜的AWS和微軟的Azure),以及如何從雲服務上恢復數據。最後還介紹瞭如何使用部落節點進行聯盟搜索。
第8章覆蓋了與Elasticsearch性能相關的各類主題,從使用文檔取值來優化字段數據緩存的內存使用,到JVM垃圾回收器的工做原理,再到查詢基準測試,最後到如何擴展Elasticsearch以適應更高的索引量和查詢量場景。
第9章經過演示如何開發你本身的REST操做插件和查詢語言分析插件來介紹Elasticsearch的插件開發。
閱讀本書的必備資源
本書寫做時採用了Elasticsearch的1.4.x版本,全部的範例代碼應該能在該版本下正常運行。除此以外,讀者須要一個能發送HTTP請求的命令行工具,例如curl,該工具在絕大多數操做系統上是可用的。請記住,本書的全部範例都使用了curl。若是讀者想使用其餘工具,請注意檢查請求的格式,以保證你所選擇的工具能正確解析它。
除此以外,爲了運行第9章的範例,須要讀者的機器上已安裝了JDK,而且須要一個編輯器來開發相關代碼(或者相似Eclipse的Java IDE)。另外,還要求使用Apache Maven進行代碼的管理與構建。
本書的目標讀者
本書的目標讀者是那些對Elasticsearch基本概念已經很熟悉可是又想深刻了解其自己,同時也對Apache Lucene、JVM垃圾收集感興趣的Elasticsearch用戶和發燒友。除此以外,想了解如何改進查詢相關性、如何使用Elasticsearch Java API、如何編寫自定義插件的讀者,也會發現本書的趣味性和實用性。
若是你是Elasticsearch的初學者,連查詢和索引這些基本概念都不熟悉,那麼你會發現本書的絕大多數章節難以理解,由於這些內容假定讀者已經有相關背景知識。若是是這種狀況,建議參考Packt出版社出版的另外一本關於Elasticsearch的圖書—《Elasticsearch Server, Second Edition》。node
爲了全面理解Elasticsearch的工做原理,尤爲是索引和查詢處理環節,對Apache Lucene的理解顯得相當重要。揭開Elasticsearch神祕的面紗,你會發現它在內部使用Apache Lucene建立索引,同時也使用Apache Lucene進行搜索。在接下來的幾頁裏,將向讀者展現Apache Lucene的基本概念,特別是那些歷來沒有使用過Lucene的讀者們。算法
讀者也許會好奇,爲何Elasticsearch的創始人決定使用Apache Lucene而不是開發一個本身的全文檢索庫。對於這個問題,筆者並非很肯定,畢竟咱們不是這個項目的創始人,咱們猜測是由於Lucene的如下特色而獲得了創始人的青睞:成熟,高性能,可擴展,輕量級以及強大的功能。Lucene內核能夠建立爲單個Java庫文件,而且不依賴第三方代碼,用戶可使用它提供的各類所見即所得的全文檢索功能進行索引和搜索操做。固然,Lucene還有不少擴展,它們提供了各類各樣的功能,例如多語言處理、拼寫檢查、高亮顯示等。若是不須要這些額外的特性,能夠下載單個的Lucene core庫文件,直接在應用程序中使用它。數據庫
儘管咱們能夠直接探討Apache Lucene架構的細節,可是有些概念仍是須要提早了解的,以便於更好地理解Lucene的架構,它們包括:apache
Apache Lucene將寫入索引的全部信息組織爲倒排索引(inverted index)的結構形式。倒排索引是一種將詞項映射到文檔的數據結構,它與傳統的關係數據庫的工做方式不一樣。你能夠認爲倒排索引是面向詞項的而不是面向文檔的。咱們來看看簡單的倒排索引是什麼樣的。例如,假設咱們有一些只包含title字段的文檔,以下所示:json
這些文檔索引好之後,可簡略地顯示以下圖:
數組
正如你所見,每一個詞項指向該詞項所出現過的文檔數。這種索引組織方式容許快速有效的搜索操做,例如基於詞項的查詢。除了詞項自己之外,每一個詞項有一個與之關聯的計數(即文檔頻率),該計數能夠告訴Lucene這個詞項在多少個文檔中出現過。
每一個索引由多個段(segment)組成,每一個段寫入一次可是查詢屢次。索引期間,一個段建立之後再也不修改。例如,文檔被刪除之後,刪除信息單獨保存在一個文件中,而段自己並無被修改。
多個段將會在段合併(segments merge)階段被合併在一塊兒。或者強制執行段合併,或者由Lucene的內在機制決定在某個時刻執行段合併,合併後段的數量更少,可是更大。段合併不是常耗費I/O,合併期間有些再也不使用的信息將被清理掉,例如,被刪除的文檔。對於容納相同數據的索引,段的數量更少的時候搜索速度更快。儘管如此,仍是須要強調一下:由於段合併不是常耗費I/O,請不要強制進行段合併,你只須要仔細配置段合併策略,剩餘的事情Lucene會自行完成。
若是你想知道段由哪些文件組成以及每一個文件都存儲了什麼信息,請參考Apache Lucene的官方文檔:http://lucene.apache.org/core/4_10_3/core/org/apache/lucene/codecs/lucene410/pa-ckage-summary.html。
更深刻地瞭解Lucene索引
固然,實際的Lucene索引比前面提到的更復雜、更高深,除了詞項的文檔頻率和出現該詞項的文檔列表外,還包含其餘附加信息。在這裏咱們會介紹一些索引中的附加信息。瞭解這些信息對咱們頗有幫助,儘管它們只在Lucene內部使用。
(1)norm
norm是一種與每一個被索引文檔相關的因子,它存儲文檔的歸一化結果,被用於計算查詢的相關得分。norm基於索引時的文檔加權值(boost)計算得出,與文檔一塊兒被索引存儲。使用norm可讓Lucene在創建索引時考慮不一樣文檔的權重,不過須要一些額外的磁盤空間和內存來索引和存儲norm信息。
(2)詞項向量
詞項向量(term vector)是一種針對每一個文檔的微型倒排索引。詞項向量的每一個維由詞項和出現頻率結對組成,還能夠包括詞項的位置信息。Lucene和Elasticsearch默認都禁用詞項向量索引,不過要實現某些功能,如關鍵詞高亮等須要啓用這個選項。
(3)倒排項格式
隨着Lucene 4.0的發佈,Lucene引入瞭解碼器架構,容許開發者控制索引文件寫入磁盤的格式,倒排項就是索引中可定製的部分之一。倒排項中能夠存儲字段、詞項、文檔、詞項位置和偏移以及載荷(payload,一個在Lucene索引中隨意存放的字節數組,能夠包含任何咱們須要的信息)。針對不一樣的使用目的,Lucene提供了不一樣的倒排項格式。好比,有一種優化後的格式是專門爲高散列範圍字段如惟一標識提供的。
(4)doc values
咱們前面提到過,Lucene索引是一種倒排索引。不過,針對某些功能,如切面(faceting)或聚合(aggregation),這種倒排索引架構就不是最佳選擇。這類功能一般須要操做文檔而不是詞項,Lucene須要把索引翻轉過來構成正排索引才能完成這些功能所須要的計算。基於這些考慮,Lucene引入了doc values和額外的數據結構來進行分組、排序和聚合。doc values存儲字段的正排索引。Lucene和Elasticsearch都容許咱們經過配置來指定doc values的存儲實現方式。可選的存儲實現包括基於內存的、基於硬盤的,以及兩者的混合。緩存
讀者也許會好奇,文檔中的數據是如何轉化爲倒排索引的?查詢串又是怎麼轉換爲能夠用於搜索的詞項的?這個轉換過程被稱爲分析(analysis)。
文本分析由分析器來執行,它創建在分詞器(tokenizer)、過濾器(filter)及字符映射器(character mapper)之上。
Lucene的分詞器用來將文本切割成詞條,詞條是攜帶各類額外信息的詞項,這些信息包括:詞項在原始文本中的位置,詞項的長度。分詞器工做的結果被稱爲詞條流,由於這些詞條被一個接一個地推送給過濾器處理。
除了分詞器,過濾器也是Lucene分析器的組成部分。過濾器數額可選,能夠爲零個、一個或多個,用於處理詞條流中的詞條。例如,它能夠移除、修改詞條流中的詞條,甚至能夠創造新的詞條。Lucene中有不少現成的過濾器,你也能夠根據須要實現新的過濾器。如下是一些過濾器的例子。
小寫過濾器:將全部詞條轉化爲小寫。
ASCII過濾器:移除詞條中全部非ASCII字符。
同義詞過濾器:根據同義詞規則,將一個詞條轉化爲另外一個詞條。
多語言詞幹還原過濾器:將詞條的文本部分歸約到它們的詞根形式,即詞幹還原。當分析器中有多個過濾器時,會逐個處理,理論上能夠有無限多個過濾器。
過濾器能夠一個接一個地被調用,所以咱們能夠經過逐個添加多個過濾器的方式來得到近乎無限的分析能力。
最後咱們介紹字符映射器,它用於調用分詞器以前的文本預處理操做。字符映射器的一個例子就是HTML文本的去標籤處理。
索引與查詢
也許讀者會好奇,Lucene以及全部基於Lucene的軟件是如何控制索引及查詢操做的?在索引期,Lucene會使用你選擇的分析器來處理文檔中的內容,能夠對不一樣的字段使用不一樣的分析器,例如,文檔的title字段與description字段就可使用不一樣的分析器。
在檢索時,若是你使用了某個查詢分析器(query parser),那麼你的查詢串將會被分析。固然,你也能夠選擇不分析數據。有一點須要牢記,Elasticsearch中有些查詢會被分析,而有些則不會被分析。例如,前綴查詢(prefix query)不會被分析,而匹配查詢(match query)會被分析。
你還應該記住,索引期與檢索期的文本分析要採用一樣的分析器,只有查詢(query)分詞出來的詞項與索引中詞項能匹配上,纔會返回預期的文檔集。例如,若是在索引期使用了詞幹還原與小寫轉換,那麼在查詢期,也應該對查詢串作相同的處理,不然,查詢可能不會返回任何結果。安全
Elasticsearch提供的一些查詢類型(query type)支持Apache Lucene的查詢解析語法,所以,咱們應該深刻了解Lucene的查詢語言。
1. 理解基本概念
在Lucene中,一個查詢(query)一般被分割爲詞項與操做符。Lucene中的詞項能夠是單個的詞,也能夠是一個短語(用雙引號括起來的一組詞)。若是查詢被設置爲要被分析,那麼預先選定的分析器將會對查詢中的全部詞項進行處理。
一個查詢也能夠包含布爾操做符。布爾操做符鏈接多個詞項,使之構成從句(clause)。有如下這些布爾操做符。
AND:它的含義是,文檔匹配當前從句當且僅當AND操做符左右兩邊的詞項都在文檔中出現。例如,咱們想執行「apache AND lucene」這樣的查詢,只有同時包含「apache」和「lucene」這兩個詞項的文檔纔會被返回給用戶。
OR:它的含義是,包含當前從句中任意詞項的文檔都被視爲與該從句匹配。例如,咱們執行「apache OR lucene」這樣的查詢,任意包含詞項「apache」或詞項「lucene」的文檔都會返回給用戶。
NOT:它的含義是,與當前從句匹配的文檔必須不包含NOT操做符後面的詞項。例如,咱們執行「lucene NOT elasticsearch」這樣的查詢,只有包含詞項「lucene」且不包含詞項「elasticsearch」的文檔纔會被返回給用戶。
除了前面介紹的那些操做符之外,咱們還可使用如下這些操做符。
+:它的含義是,只有包含了「+」操做符後面詞項的文檔纔會被認爲與從句匹配。例如,咱們想查找那些必須包含「lucene」可是「apache」可出現可不出現的文檔,可執行以下查詢:「+lucene apache」。
–:它的含義是,與從句匹配的文檔,不能出現「-」操做符後的詞項。例如,咱們想查找那些包含了「lucene」可是不包含「Elasticsearch」的文檔,能夠執行以下查詢:「+lucene -elasticsearch」。
若是查詢中沒有出現前面提到過的任意操做符,那麼默認使用OR操做符。
除了前面介紹的內容以外,有一件事情值得一提:可使用圓括號對從句進行分組,以構造更復雜的從句,例如:
網絡
2. 在字段中查詢
就像Elasticsearch的處理方式那樣,Lucene中全部數據都存儲在字段(field)中,而字段又是文檔的組成單位。爲了實現針對某個字段的查詢,用戶須要提供字段名稱,再加上冒號以及將要在該字段中執行查詢的從句。若是你想查詢全部在「title」字段中包含詞項「Elasticsearch」的文檔,可執行如下查詢:
也能夠在一個字段中同時使用多個從句,例如,若是你想查找全部在「title」字段中同時包含詞項「Elasticsearch」和短語「mastering book」的文檔,可執行以下查詢:
固然,上面的查詢也能夠寫成下面這種形式:
3. 詞項修飾符
除了使用簡單詞項和從句的常規字段查詢之外,Lucene容許用戶使用修飾符(modifier)修改傳入查詢對象的詞項。毫無疑問,最多見的修飾符就是通配符(wildcard)。Lucene支持兩種通配符:?和*。前者匹配任意一個字符,然後者匹配多個字符。
請記住,出於對性能的考慮,通配符不能做爲詞項的第一個字符出現。
除通配符以外,Lucene還支持模糊(fuzzy and proximity)查詢,辦法是使用「~」字符以及一個緊隨其後的整數值。當使用該修飾符修飾一個詞項時,意味着咱們想搜索那些包含該詞項近似詞項的文檔(因此這種查詢稱爲模糊查詢)。~字符後的整數值肯定了近似詞項與原始詞項的最大編輯距離。例如,當咱們執行查詢writer~2,意味着包含詞項writer和writers的文檔均可以被視爲與查詢匹配。
當修飾符~用於短語時,其後的整數值用於告訴Lucene詞項之間多大距離是能夠接受的。例如,咱們執行以下查詢:
在title字段中包含mastering Elasticsearch的文檔被視爲與查詢匹配,而包含mastering book Elasticsearch的文檔則被認爲不匹配。而若是咱們執行下面這個查詢:
title:"mastering Elasticsearch"~2,
則這兩個文檔都被認爲與查詢匹配。
此外,還可使用^字符並賦以一個浮點數對詞項加權(boosting),從而提升該詞項的重要程度。若是都被加權,則權重值較大的詞項更重要。默認狀況下詞項權重爲1。能夠參考2.1節進一步瞭解什麼是權重值(boost value),以及其在文檔評分中的做用。
咱們也可使用方括號和花括號來構建範圍查詢。例如,咱們想在一個數值類型的字段上執行一個範圍查詢,執行以下查詢便可:
上面查詢的返回文檔的price字段的值大於等於10.00並小於等於15.00。
固然,咱們也能夠在字符串類型的字段上執行範圍查詢(range query),例如:name:[Adam TO Adria]
上面查詢的返回文檔的name字段中,包含了按字典順序介於Adam 和Adria之間(包括Adam和Adria)的詞項。
若是想執行範圍查詢同時又想排除邊界值,則可以使用花括號做爲修飾符。例如,咱們想查找price字段值大於等於10.00但小於15.00的文檔,可以使用以下查詢:
若是想執行一邊受限而另外一邊不作限制的範圍查詢,例如,查找price字段值大於等於10.00的文檔,可以使用以下查詢:
4. 特殊字符處理
不少應用場景中,也許你想搜索某個特殊字符(這些特殊字符包括+、–、&&、||、!、(,)、{}、[]、^、"、~、*、?、:、\、/),須要先使用反斜槓對這些特殊字符進行轉義。例如,你可能想搜索abc"efg這個詞項,須要按以下方式處理:abc\"efg
當讀者手持本書閱讀時,可能已經對Elasticsearch有所瞭解了,至少已經瞭解了它的一些核心概念和基本用法。不過,爲了全面理解該搜索引擎是如何工做的,咱們最好簡略地討論一下它。
也許你已經瞭解到,Elasticsearch是一個可用於構建搜索應用的成品軟件(譯者注:區別於Lucene這種中間件)。它最先由Shay Banon建立,並於2010年2月發佈。以後的幾年,Elasticsearch迅速流行開來,成爲其餘開源和商業解決方案以外的一個重要選擇。它是下載量最多的開源項目之一。
如今,讓咱們瀏覽一下Elasticsearch的基本概念以及它們的特徵。
1. 索引
Elasticsearch將它的數據存儲在一個或者多個索引(index)中。用SQL領域的術語來類比,索引就像數據庫,能夠向索引寫入文檔或者從索引中讀取文檔。就像以前說過的那樣,Elasticsearch在內部使用Lucene將數據寫入索引或從索引中檢索數據。讀者須要注意的是,Elasticsearch中的索引可能由一個或多個Lucene索引構成,細節由Elasticsearch的索引分片(shard)、複製(replica)機制及其配置決定。
2. 文檔
文檔(document)是Elasticsearch世界中的主要實體(對Lucene來講也是如此)。對於全部使用Elasticsearch的案例來講,它們最終都會被歸結到對文檔的搜索之上。文檔由字段構成,每一個字段包含字段名以及一個或多個字段值(在這種狀況下,該字段被稱爲是多值的,即文檔中有多個同名字段)。文檔之間可能有各自不一樣的字段集合,文檔並無固定的模式或強制的結構。這種現象看起來很眼熟(這些規則也適用於Lucene文檔)。事實上,Elasticsearch的文檔最後都被存儲爲Lucene文檔了。從客戶端的角度來看,文檔是一個JSON對象(想了解更多關於JSON格式的細節,請參考http://en.wikipedia.org/wiki/JSON)。
3. 類型
**Elasticsearch中每一個文檔都有與之對應的類型(type)定義。這容許用戶在一個索引中存儲多種文檔類型,併爲不一樣文檔類型提供不一樣的映射。若是同SQL領域類比,Elasticsearch的類型就像一個數據庫表。
**4. 映射
正如你在1.1節所瞭解到的那樣,全部文檔在寫入索引前都將被分析。用戶能夠設置一些參數,決定如何將輸入文本分割爲詞條,哪些詞條應該被過濾掉,或哪些附加處理有必要被調用(例如移除HTML標籤)。這就是映射(mapping)扮演的角色:存儲分析鏈所需的全部信息。雖然Elasticsearch能根據字段值自動檢測字段的類型,有時候(事實上幾乎是全部時候)用戶仍是想本身來配置映射,以免出現一些使人不愉快的意外。
5. 節點
單個的Elasticsearch的服務實例被稱爲節點(node)。不少時候部署一個Elasticsearch節點就足以應付大多數簡單的應用,可是考慮到容錯性或者數據膨脹到單機沒法應付這些情況,也許你會更傾向於使用多節點的Elasticsearch集羣。
Elasticsearch節點能夠按用途分爲3類。衆所周知,Elasticsearch是用來索引和查詢數據的,所以第1類節點就是數據(data)節點,用來持有數據,提供對這些數據的搜索功能。第2類節點指主(master)節點,做爲監督者負責控制其餘節點的工做。一個集羣中只有一個主節點。第3類節點是部落(tribe)節點。部落節點是Elasticsearch 1.0版新引入的節點類型,它能夠像橋樑同樣鏈接起多個集羣,並容許咱們在多個集羣上執行幾乎全部能夠在單集羣Elasticsearch上執行的功能。
6. 集羣
多個協同工做的Elasticsearch節點的集合被稱爲集羣(cluster)。Elasticsearch的分佈式屬性使咱們能夠輕鬆處理超過單機負載能力的數據量。同時,集羣也是無間斷提供服務的一種解決方案,即使當某些節點由於宕機或者執行管理任務(例如升級)不可用時,Elasticsearch幾乎是無縫集成了集羣功能。在咱們看來,這是它賽過競爭對手的最主要優勢之一。在Elasticsearch中配置一個集羣是再容易不過的事了。
7. 分片
正如咱們以前提到的那樣,集羣容許系統存儲的數據總量超過單機容量。爲了知足這個需求,Elasticsearch將數據散佈到多個物理的Lucene索引上去。這些Lucene索引被稱爲分片(shard),而散佈這些分片的過程叫作分片處理(sharding)。Elasticsearch會自動完成分片處理,而且讓用戶看來這些分片更像是一個大索引。請記住,除了Elasticsearch自己自動進行分片處理外,用戶爲具體的應用進行參數調優也是相當重要的,由於分片的數量在索引建立時就被配置好了,以後沒法改變,除非建立一個新索引並從新索引所有數據。
8. 副本
分片處理容許用戶推送超過單機容量的數據至Elasticsearch集羣。副本(replica)則解決了訪問壓力過大時單機沒法處理全部請求的問題。思路是很簡單的,爲每一個分片建立冗餘的副本,處理查詢時能夠把這些副本看成最初的主分片(primary shard)使用。值得注意的是,副本給Elasticsearch帶來了更多的安全性。若是主分片所在的節點宕機了,Elasticsearch會自動從該分片的副本中選出一個做爲新的主分片,所以不會對索引和搜索服務產生干擾。能夠在任意時間點添加或移除副本,因此一旦你有須要,可隨時調整副本的數量。
Elasticsearch的架構遵循了一些設計理念。開發團隊但願這個搜索引擎產品易於使用和擴展,這些特徵在Elasticsearch的每一個角落裏均可以被看到。從架構的視角來看,有下面這些主要特徵:
本節咱們將探索一些關鍵的Elasticsearch特性,如啓動、故障檢測、數據索引和查詢等。
1. 啓動過程
當Elasticsearch節點啓動時,它使用發現(discovery)模塊來發現同一個集羣中的其餘節點(這裏的關鍵是配置文件中的集羣名稱)並與它們鏈接。默認狀況下,Elasticsearch節點會向網絡中發送廣播請求,以找到擁有相同集羣名稱的其餘節點。讀者能夠經過下圖的描述來了解相關的處理。
集羣中有一個節點被選爲主(master)節點。該節點負責集羣的狀態管理以及在集羣拓撲變化時作出反應,分發索引分片至集羣的相應節點上去。
請記住,從用戶的角度來看,Elasticsearch中的管理節點並不比其餘節點重要,這與其餘的某些分佈式系統不一樣(例如數據庫)。在實踐中,你不須要知道哪一個節點是管理節點,全部操做能夠發送至任意節點,Elasticsearch內部會自行處理這些難以想象的事情。若是有須要,任意節點能夠並行發送子查詢給其餘節點,併合並搜索結果,而後返回給用戶。全部這些操做並不須要通過管理節點處理(請記住,Elasticsearch是基於對等架構的)。
管理節點讀取集羣的狀態信息,若是有必要,它會進行恢復(recovery)處理。在該階段,管理節點會檢查有哪些索引分片,並決定哪些分片將用做主分片。此後,整個集羣進入黃色狀態。
這意味着集羣能夠執行查詢,可是系統的吞吐量以及各類可能的情況是未知的(這種情況能夠簡單理解爲全部的主分片已經被分配了,可是副本沒有被分配)。下面的事情就是尋找到冗餘的分片用做副本。若是某個主分片的副本數過少,管理節點將決定基於某個主分片建立分片和副本。若是一切順利,集羣將進入綠色狀態(這意味着全部主分片以及副本均已分配好)。
2. 故障檢測
集羣正常工做時,管理節點會監控全部可用節點,檢查它們是否正在工做。若是任何節點在預約義的超時時間內不響應,則認爲該節點已經斷開,而後錯誤處理過程開始啓動。這意味着可能要在集羣–分片之間從新作平衡,選擇新的主節點等。對每一個丟失的主分片,一個新的主分片將會從原來的主分片的副本中選出來。新分片和副本的放置策略是可配置的,用戶能夠根據具體需求進行配置。更多的信息能夠在第7章瞭解到。
爲了描述故障檢測(failure detection)是如何工做的,咱們用一個只有3個節點的集羣做爲例子,將會有一個管理節點,兩個數據節點。管理節點會發送ping請求至其餘節點,而後等待響應。若是沒有響應(實際上多少次ping請求無響應能夠確認節點失敗取決於配置),則該節點會被從集羣中移除出去。相反地,全部節點也會向主節點發送ping請求來檢查主節點是否在正常工做。節點之間的相互探測以下圖所示。
3. 與Elasticsearch通訊
前面已經討論過Elasticsearch是如何構建的了,然而,對普通用戶來講,最重要的部分是如何向Elasticsearch推送數據以及構建查詢。爲了提供這些功能,Elasticsearch對外公開了一個設計精巧的API。若是咱們說,基本上每一個Elasticsearch功能模塊都有一個API,這將是使人鼓舞的。這個主API是基於REST的(REST細節請參考http://en.wikipedia.org/wiki/Representational_state_transfer),而且在實踐中能輕鬆整合到任意支持HTTP協議的系統中去。
Elasticsearch假設數據由URL攜帶或者以JSON(JSON細節請參考(http://en.wikipedia.org/wiki/JSON)文檔的形式由HTTP消息體攜帶。使用Java或者基於JVM語言的用戶,應該瞭解一下Java API,它除了REST API提供的全部功能之外還有內置的集羣發現功能。
值得一提的是,Elasticsearch在內部也使用Java API進行節點間通訊。所以,Java API提供了全部可被REST API調用的功能。
(1)索引數據
Elasticsearch提供了多種索引數據的方式。最簡單的方式是使用索引API,它容許用戶發送一個文檔至特定的索引。例如,使用curl工具(curl細節請參考http://curl.haxx.se/),可使用以下命令建立一個文檔:
第2種方式容許用戶經過bulk API或UDP bulk API一次發送多個文檔至集羣。二者的區別在於網絡鏈接方式,前者使用HTTP協議,後者使用UDP協議。後者速度快,可是不可靠。還有一種方式使用被叫做河流(river)的插件來發送數據。不過在這裏咱們不須要了解這種河流插件,由於它們將在Elasticsearch將來版本中被移除。
有一件事情須要記住,建索引操做只會發生在主分片上,而不是副本上。當一個索引請求被髮送至一個節點上時,若是該節點沒有對應的主分片或者只有副本,那麼這個請求會被轉發到擁有正確的主分片的節點。而後,該節點將會把索引請求羣發給全部副本,等待它們的響應(這一點能夠由用戶控制),最後,當特定條件具有時(好比說達到規定數目的副本都完成了更新時)結束索引過程。
下圖展現了咱們剛剛探討的索引處理過程。
(2)查詢數據
查詢API佔據了Elasticsearch API的大部分。使用查詢DSL(基於JSON的可用於構建複雜查詢的語言),咱們能夠作下面這些事情:
使用預搜索(prospective search)和查找與指定文檔匹配的query集合。
談到查詢操做,讀者應該瞭解一個很重要的事實:查詢並非一個簡單的、單步驟的操做。通常來講,查詢分爲兩個階段:分散階段(scatter phase)和合並階段(gather phase)。在分散階段將查詢分發到包含相關文檔的多個分片中去執行查詢,而在合併階段則從衆多分片中收集返回結果,而後對它們進行合併、排序,進行後續處理,而後返回給客戶端。該機制能夠由下圖描述。
Elasticsearch對外提供了6個系統參數,經過使用其中之一來定製分散/合併機制。在本書的姐妹版《Elasticsearch Server, Second Edition》(Packt出版社)中已經討論過這個問題了。
本書可做爲《Elasticsearch server, Second Edition》一書的延續。所以,咱們在這裏也沿用在那本書中的案例。總的來講,假設本身正在實現和運做一個在線書店。
首先須要一個library索引,它的映射定義以下:
這段映射代碼位於隨書提供的library.json文件。
咱們將要使用的數據也能夠在隨書提供的books.json文件中找到。這個文件中的文檔示例以下:
讀者能夠從本身在http://www.packtpub.com 的我的帳戶中下載全部已購Packt書籍的示例代碼文件。若是您從其餘地方購買本書,能夠訪問http://www.packtpub.com/support 進行登記,隨後Packt出版社會把文件經過e-mail發送給您。
咱們須要執行以下命令來建立帶以上映射的索引,並索引數據:
在本章中,咱們瞭解了Apache Lucene的通常架構,例如它的工做原理,文本分析過程是如何完成的,如何使用Apache Lucene查詢語言。此外,咱們還討論了Elasticsearch的一些基本概念,例如它的基本架構和內部通訊機制。 下一章將學習Apache Lucene的默認評分公式,什麼是查詢重寫過程(query rewrite process)以及它是如何工做的。除此以外,還將討論Elasticsearch的一些功能,例如查詢模板、過濾器,以及它們影響查詢性能的機制。咱們將學習如何使用過濾器,並選擇合適的查詢方式來完成查詢工做。