天天看點

《深入了解ElasticSearch》——1.2 ElasticSearch簡介

本節書摘來自華章計算機《深入了解elasticsearch》一書中的第1章,第1.2節,作者:[美] 拉斐爾·酷奇(rafa ku) 馬雷克·羅戈任斯基(marek rogoziński)更多章節内容可以通路雲栖社群“華章計算機”公衆号檢視。

雖然讀者可能已經對elasticsearch有所了解,至少已經了解了它的一些核心概念和基本用法。然而,為了全面了解該搜尋引擎是如何工作的,我們最好簡略地讨論一下它。

elasticsearch是一個可用于建構搜尋應用的成品軟體。它最早由shay banon建立并于2010年2月釋出。之後的幾年elasticsearch迅速流行開來,成為商業解決方案之外且開源的一個重要選擇,也是下載下傳量最多的開源軟體之一,每月下載下傳量超過20萬次。

1.2.1 elasticsearch的基本概念

現在,讓我們了解一下elasticsearch的基本概念及其特征。

索引

elasticsearch将它的資料存儲在一個或多個索引(index)中。用sql領域的術語來類比,索引就像資料庫,可以向索引寫入文檔或者從索引中讀取文檔,并通過在elasticsearch内部使用lucene将資料寫入索引或從索引中檢索資料。需要注意的是,elasticsearch中的索引可能由一個或多個lucene索引構成,具體細節由elasticsearch的索引分片(shard)、複制(replica)機制及其配置決定。

文檔

映射

正如你在1.1節所了解的那樣,所有文檔在寫入索引前都需要先進行分析。使用者可以設定一些參數,來決定如何将輸入文本分割為詞條,哪些詞條應該被過濾掉,或哪些附加處理是有必要被調用的(如移除html标簽)。此外,elasticsearch也提供了各種特性,如排序時所需的字段内容資訊。這就是映射(mapping)扮演的角色,存儲所有這種元資訊。雖然elasticsearch能根據字段值自動檢測字段的類型,但有時候(事實上,幾乎是所有時候)使用者還是想自行配置映射,以避免出現一些令人不愉快的意外。

類型

elasticsearch中每個文檔都有與之對應的類型(type)定義。這允許使用者在一個索引中存儲多種文檔類型,并為不同文檔類型提供不同的映射。

節點

單個的elasticsearch服務執行個體稱為節點(node)。很多時候部署一個elasticsearch節點就足以應付大多數簡單的應用,但是考慮到容錯性或在資料膨脹到單機無法應付這些狀況時,你也許會更傾向于使用多節點的elasticsearch叢集。

叢集

當資料量或查詢壓力超過單機負載時,需要多個節點來協同處理,所有這些節點組成的系統稱為叢集(cluster)。叢集同時也是無間斷提供服務的一種解決方案,即便在某些節點因為當機或執行管理任務(如更新)不可用時。elasticsearch幾乎無縫內建了叢集功能。在我們看來,這是它勝過競争對手的最主要的優點之一。而且,在elasticsearch中配置一個叢集是再容易不過的事了。

分片

正如我們之前提到的那樣,叢集允許系統存儲的資料總量超過單機容量。為了滿足這個需求,elasticsearch将資料散布到多個實體lucene索引上。這些lucene索引稱為分片(shard),而散布這些分片的過程叫作分片處理(sharding)。elasticsearch會自動完成分片處理,并且讓這些分片呈現出一個大索引的樣子。請記住,除了elasticsearch本身自動進行分片處理外,使用者為具體的應用進行參數調優也是至關重要的,因為分片的數量在索引建立時就已經配置好,而且之後無法改變,至少對目前的版本是這樣的。

副本

分片處理允許使用者向elasticsearch叢集推送超過單機容量的資料。副本(replica)則解決了通路壓力過大時單機無法處理所有請求的問題。思路很簡單,即為每個分片建立備援的副本,處理查詢時可以把這些副本用作最初的主分片(primary shard)。請記住,我們并未付出額外的代價。即使某個分片所在的節點當機,elasticsearch也可以使用其副本,進而不會造成資料丢失,而且支援在任意時間點添加或移除副本,是以一旦有需要可随時調整副本的數量。

網關

在elasticsearch的工作過程中,關于叢集狀态,索引設定的各種資訊都會被收集起來,并在網關(gateway)中被持久化。

1.2.2 elasticsearch架構背後的關鍵概念

elasticsearch架構遵循了一些設計理念。通常開發團隊希望這個搜尋引擎産品易于使用和擴充,并能在elasticsearch的各個地方展現出來。從架構的角度出發,elasticsearch具有下面這些主要特征:

合理的預設配置,使得使用者在簡單安裝以後能直接使用elasticsearch而不需要任何額外的調試,這包括内置的發現(如字段類型檢測)和自動配置功能。

預設的分布式工作模式。每個節點總是假定自己是某個叢集的一部分或将是某個叢集的一部分,一旦工作啟動節點便會加入某個叢集。

對等架構(p2p)可以避免單點故障(spof)。節點會自動連接配接到叢集中的其他節點,進行互相的資料交換和監控操作。這其中就包括索引分片的自動複制。

易于向叢集擴充新節點,不論是從資料容量的角度還是數量角度。

elasticsearch沒有對索引中的資料結構強加任何限制,進而允許使用者調整現有的資料模型。正如之前描述的那樣,elasticsearch支援在一個索引中存在多種資料類型,并允許使用者調整業務模型,包括處理文檔之間的關聯(盡管這種功能非常有限)。

準實時(near real time,nrt)搜尋和版本同步(versioning)。考慮到elasticsearch的分布式特性,查詢延遲和節點之間臨時的資料不同步是難以避免的。elasticsearch嘗試消除這些問題并且提供額外的機制用于版本同步。

1.2.3 elasticsearch的工作流程

現在,讓我們簡單地讨論一下elasticsearch是如何工作的。

啟動過程

當elasticsearch節點啟動時,它使用廣播技術(也可配置為單點傳播)來發現同一個叢集中的其他節點(這裡的關鍵是配置檔案中的叢集名稱)并與它們連接配接。讀者可以通過下圖的描述來了解相關的處理過程:

《深入了解ElasticSearch》——1.2 ElasticSearch簡介

https://yqfile.alicdn.com/5a80f59364030303ffbc7681cf9dc3523f1984b6.png" >

叢集中會有一個節點被選為管理節點(master node)。該節點負責叢集的狀态管理以及在叢集拓撲變化時做出反應,分發索引分片至叢集的相應節點上。

請記住,從使用者的角度來看,elasticsearch中的管理節點并不比其他節點重要,這與其他某些分布式系統不同(如資料庫)。實際上,你不需要知道哪個節點是管理節點,所有操作可以發送至任意節點,elasticsearch内部會自行處理這些不可思議的事情。如果有需要,任意節點可以并行發送子查詢給其他節點,并合并搜尋結果,然後傳回給使用者。所有這些操作并不需要經過管理節點處理(請記住,elasticsearch是基于對等架構的)。

管理節點讀取叢集的狀态資訊,并在必要時進行恢複處理。在該階段,管理節點會檢查所有索引分片并決定哪些分片将用于主分片。然後,整個叢集進入黃色狀态。

這意味着叢集可以執行查詢,但是系統的吞吐量以及各種可能的狀況是未知的(這種狀況可以簡單了解為所有的主分片已經配置設定出去了,而副本沒有),因而接下來就是要尋找到備援的分片并用作副本。如果某個主分片的副本數過少,管理節點将決定基于某個主分片建立分片和副本。如果一切順利,叢集将進入綠色狀态(這意味着所有主分片和副本均已配置設定好)。

故障檢測

叢集正常工作時,管理節點會監控所有可用節點,檢查它們是否正在工作。如果任何節點在預定義的逾時時間内沒有響應,則認為該節點已經斷開,然後開始啟動錯誤處理過程。這意味着要在叢集-分片之間重新做平衡,因為之前已斷開節點上的那些分片不可用了,剩下的節點要肩負起相應的責任。換句話說,對每個丢失的主分片,一個新的主分片将會從原來的主分片的副本中脫穎而出。新分片和副本的放置政策是可配置的,使用者可以根據具體需求進行配置。更多資訊請參見第4章(索引分布架構)的内容。

為了描述故障檢測(failure detection)是如何工作的,我們用一個隻有三個節點的叢集為例,即包含一個管理節點,兩個資料節點。管理節點會發送ping請求至其他節點,然後等待響應。如果沒有響應,則該節點會從叢集中移除。如下圖所示:

《深入了解ElasticSearch》——1.2 ElasticSearch簡介

https://yqfile.alicdn.com/cbc2ad5fc3e3346e872a97bc05f3f65cef3c4c4d.png" >

與elasticsearch通信

前面已經讨論過elasticsearch是如何建構的了,然而,對普通使用者來說,最重要的還是如何向elasticsearch推送資料并建構查詢。為了提供這些功能,elasticsearch對外公開了一個設計精巧的api。

elasticsearch假設資料由url攜帶或者以json(文檔的形式由http消息體攜帶。使用java或基于jvm語言的使用者,應該了解一下java api,它除了rest api提供的所有功能以外還有内置的叢集發現功能。

值得一提的是,elasticsearch在内部也使用java api進行節點間通信。讀者可以在第8章中了解更多java api的細節,而這裡隻是簡略地了解java api提供了哪些功能。本書假設讀者已經使用過這些功能了,隻是在此做一點小小的提示。如果使用者還沒有使用過,強烈建議閱讀相關材料,其中《elasticsearch server》一書覆寫了所有這些内容。

索引資料

《深入了解ElasticSearch》——1.2 ElasticSearch簡介

https://yqfile.alicdn.com/935e5719fafc94526bbe7bbb52cc03c0c18bd13b.png" >

第二種或第三種方式允許使用者通過bulk api或udp bulk api來一次性發送多個文檔至叢集。兩者的差別在于網絡連接配接方式,前者使用http協定,後者使用udp協定,且後者速度快,但是不可靠。第四種方式使用插件發送資料,稱為河流(river),河流運作在elasticsearch節點上,能夠從外部系統擷取資料。

有一件事情需要記住,建索引操作隻會發生在主分片上,而不是副本上。當把一個索引請求發送至某節點時,如果該節點沒有對應的主分片或者隻有副本,那麼這個請求會被轉發到擁有正确的主分片的節點(如下圖所示)。

《深入了解ElasticSearch》——1.2 ElasticSearch簡介

https://yqfile.alicdn.com/b9ee65b3c521f247253963fece01688144b2c97d.png" >

查詢資料

查詢api占據了elasticsearch api的大部分内容。使用查詢dsl(基于json的可用于建構複雜查詢的語言),我們可以做下面這些事情:

使用各種查詢類型,包括:簡單的詞項查詢、短語查詢、範圍查詢、布爾查詢、模糊查詢、區間查詢、通配符查詢、空間查詢等。

組合簡單查詢建構複雜查詢。

文檔過濾,在不影響評分的前提下抛棄那些不滿足特定查詢條件的文檔。

查找與特定文檔相似的文檔。

查找特定短語的查詢建議和拼寫檢查。

使用切面建構動态導航和計算各種統計量。

使用預搜尋(prospective search)并查找與指定文檔比對的query集合。

對于查詢操作,讀者應該要重點了解:查詢并不是一個簡單的、單步驟的操作。一般來說,查詢分為兩個階段:分散階段(scatter phase)和合并階段(gather phase)。分散階段将query分發到包含相關文檔的多個分片中去執行查詢,合并階段則從衆多分片中收集傳回結果,然後對它們進行合并、排序、後續處理,然後傳回給用戶端。該機制可以由下圖描述。

《深入了解ElasticSearch》——1.2 ElasticSearch簡介

https://yqfile.alicdn.com/deead989113f2e7f791834f3f3cd24d8f11a5f02.png" >

elasticsearch對外提供了6個系統參數,任何一個都可以用來定制分散/合并機制。關于這個問題可參閱本書的上一版《elasticsearch server》(packt出版社)。

索引配置

前面已經讨論過elasticsearch的自動索引配置以及發現識别文檔字段類型和結構的功能。當然,elasticsearch也提供了一些功能使得使用者能手動配置,例如使用者想通過映射來配置自定義的文檔結構,或者想設定索引的分片和副本數,抑或定制文本分析過程,種種這些需求都可以通過手動配置解決。

系統管理和監控

elasticsearch中系統管理和監控相關的api允許使用者改變叢集的設定,如調節叢集發現機制和索引放置政策等。此外,你還可得到關于叢集狀态資訊或每個節點、每個索引的統計資訊。叢集監控api非常全面,我們将在第5章學習相關api的使用範例。