天天看點

ElasticSearch入門 附.Net Core例子

Elasticsearch是基于Lucene的搜尋引擎。它提供了一個分布式,支援多租戶的全文搜尋引擎,它具有HTTP Web界面和無模式JSON文檔。 Elasticsearch是用Java開發的,根據Apache許可條款作為開源釋出。

----來自維基百科的解釋

我個人的了解是Elasticsearch(以下簡稱ES)是一個支援分布式的全文搜尋引擎,因為在海量資料搜尋時,普通關系型、非關系型資料庫因為IO讀取、處理器運算能力的限制,導緻查詢效率難以提升,但是ES是分布式的(能把處理壓力分攤給每個節點),而且它是給每個詞建立索引,是以查詢效率極高,堪稱即時搜尋。

而且ES能搭配Kibana,實作資料的可視化管理與資料分析。

ElasticSearch入門 附.Net Core例子

                                                                           Kibana儀表盤

前面所過ES是一個分布式搜尋引擎,其本質是一個分布式資料庫,可以多台計算機上的ES執行個體協同工作,這裡面的某一台計算機上的某個ES執行個體,就可以稱為一個Node(節點),所有的這些協同工作的執行個體,可以稱為一個Cluster(叢集)。

Elastic 會索引所有字段,經過處理後寫入一個反向索引(Inverted Index)。查找資料的時候,直接查找該索引。

是以,Elastic 資料管理的頂層機關就叫做 Index(索引)。它是單個資料庫的同義詞。每個 Index (即資料庫)的名字必須是小寫。

Index 裡面單條的記錄稱為 Document(文檔)。許多條 Document 構成了一個 Index。

Document 使用 JSON 格式表示,下面是一個例子。

同一個 Index 裡面的 Document,不要求有相同的結構(scheme),但是最好保持相同,這樣有利于提高搜尋效率。

Document 可以分組,比如<code>weather</code>這個 Index 裡面,可以按城市分組(北京和上海),也可以按氣候分組(晴天和雨天)。這種分組就叫做 Type,它是虛拟的邏輯分組,用來過濾 Document。

不同的 Type 應該有相似的結構(schema),舉例來說,<code>id</code>字段不能在這個組是字元串,在另一個組是數值。這是與關系型資料庫的表的一個差別。性質完全不同的資料(比如<code>products</code>和<code>logs</code>)應該存成兩個 Index,而不是一個 Index 裡面的兩個 Type(雖然可以做到)。

根據規劃,Elastic 6.x 版隻允許每個 Index 包含一個 Type,7.x 版将會徹底移除 Type。

----參考阮一峰 全文搜尋引擎 Elasticsearch 入門教程

Elasticsearch用于建構高可用和可擴充的系統。擴充的方式可以是購買更好的伺服器(縱向擴充)或者購買更多的伺服器(橫向擴充)。

Elasticsearch雖然能從更強大的硬體中獲得更好的性能,但是縱向擴充有它的局限性。真正的擴充應該是橫向的,它通過增加節點來均攤負載和增加可靠性。如果我們啟動一個單獨的節點,它還沒有資料和索引,這個叢集看起來就像下圖。

ElasticSearch入門 附.Net Core例子

叢集中一個節點會被選舉為主節點(master),它将臨時管理叢集級别的一些變更,例如建立或删除索引、增加或移除節點等。

主節點不參與文檔級别的變更或搜尋,這意味着在流量增長的時候,該主節點不會成為叢集的瓶頸。任何節點都可以成為主節點。我們例子中的叢集隻有一個節點,是以它會充當主節點的角色。

當索引建立完成的時候,主分片的數量就固定了,但是複制分片的數量可以随時調整。

讓我們在叢集中唯一一個空節點上建立一個叫做 blogs 的索引。預設情況下,一個索引被配置設定5個主分片,但是為了示範的目的,我們隻配置設定3個主分片和一個複制分片(每個主分片都有一個複制分片):

PUT /blogs

{

"settings" : {

"number_of_shards" : 3,

"number_of_replicas" : 1

}

ElasticSearch入門 附.Net Core例子

我們的叢集現在看起來就像上圖,三個主分片都被配置設定到 Node 1 。

在單一節點上運作意味着有單點故障的風險:沒有資料備份。幸運的是,要防止單點故障,我們唯一需要做的就是啟動另一個節點。

如果我們啟動了第二個節點,這個叢集看起來就像下圖

ElasticSearch入門 附.Net Core例子

第二個節點已經加入叢集,三個複制分片(replica shards)也已經被配置設定了,分别對應三個主分片,這意味着在丢失任意一個節點的情況下依舊可以保證資料的完整性。

文檔的索引将首先被存儲在主分片中,然後并發複制到對應的複制節點上。這可以確定我們的資料在主節點和複制節點上都可以被檢索。

随着應用需求的增長,我們該如何擴充?如果我們啟動第三個節點,我們的叢集會自我感覺,這時便成為了三節點叢集。

分片已經被重新配置設定以平衡負載:

ElasticSearch入門 附.Net Core例子

從 Node 1 和 Node 2 來的分片已經被移動到新的 Node 3 上,這樣每個節點就有兩個分片,以代替之前的三個。這意味着每個節點的硬體資源(CPU、RAM、I/O)被較少的分片共享,這樣每個分片就會有更好的表現。

分片本身就是一個完整成熟的搜尋引擎,它可以使用單一節點的所有資源。使用這6個分片(3個主分片和三個複制分片)我們可以擴充最多到6個節點,每個節點上有一個分片,這樣就可以100%使用這個節點的資源了。

----參考文獻Elasticsearch: 權威指南

因為每個平台上ES安裝方法有所差別,而且網絡上有較為詳細的安裝教程,本文在此不再贅述。原本是想着在我的兩台騰訊雲Centos伺服器上,搭建一個ES叢集的,但是因為雲伺服器記憶體1G,運作ES時總是報錯,大體意思是記憶體不足,是以我就在自己的PC上,隻搭建了一個ES節點,還不算ES叢集,不過不影響功能的測試。

Windows環境下ES 6.4 MSI下載下傳位址:https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-6.4.0.msi

一路預設下一步,安裝完成後,在浏覽器位址輸入http://localhost:9200/,如果您能看到下列結果,說明安裝完成。

"You Know, for Search"

ES有一套Restful 風格的API系統,通過該API我們與ES進行互動。

利用PostMan向ES POST一條資料如下。

ElasticSearch入門 附.Net Core例子

http://localhost:9200/index/test1/1 中Index是該資料的Index(上文有介紹Index),test1是該資料的Type,1是該條資料的Id,該ID在通過ID擷取資料時需要用到。

在知道資料的Index,Type和ID的情況下,可以通過和上文Post資料的Url一樣的格式擷取資料,不同之處時,此時的HTTP方法時Get,如下:

ElasticSearch入門 附.Net Core例子

ES的資料查詢文法較為豐富,此處以一個最簡單的查詢為例,Http方法為POST,請求的Url中同樣指定了Index和Type

   "query" : { "match" : { "tagline" : "for" }}

指的時查詢tagline中包含的for的資料,

ElasticSearch入門 附.Net Core例子

其他更詳細的查詢文法,建議大家檢視Elasticsearch: 權威指南,此處主要抛磚引玉。

在上文中,我們了解到,可以通過restful api與ES進行互動,那麼,如果需要在我們的程式中使用ES,是不是要建立一個這樣的Helper方法,通過HTTP調用RESTFul API與ES進行互動呢?

不是不可以,但是Elastic為大部分語言都建立了"Clients”,其實就是把上文提及的那些方法進行了一個封裝,是我們在代碼中,能夠友善地調用ES。

以.Net Core為例,該”Clients”開源在Github:

https://github.com/elastic/elasticsearch-net

在該倉庫中,其實有<code>Elasticsearch.Net</code> 和 <code>NEST</code>兩個.Net官方SDK,兩個各有特色。

<code>Elasticsearch.Net</code> 是一個非常low leave而且靈活的SDK,它不在意你如何的建構自己的請求和響應。它非常抽象,是以所有的Elasticsearch RESTFul API被表示為方法,而且不會影響你建構json / request / response對象的方式。 它還内置可配置/可覆寫的群集故障轉移重試機制。

<code>NEST</code> 是一個 high level SDK, 有非常大的彈性,如果你想更好的提升你的搜尋服務,你完全可以使用它來做為你的用戶端。可以映射所有請求和響應對象,擁有一個強類型DSL(領域特定語言),并且可以使用.net的特性,如協變、Auto Mapping Of POCOs,NEST内部使用的依然是Elasticsearch.Net用戶端。

本Demo我使用的NEST,是以第一步是建立一個Asp.Net Core Api應用程式并引入NEST的Nuget包。

然後我建立一個EsClientProvider,代碼如下:

IEsClientProvider代碼如下:

然後再Startup的ConfigureServices進行服務的注冊

最後,修改ValueContoller,代碼如下:

其中Index方法能進行資料的送出,Search是通過Post實體的type來進行資料查詢。

代碼不複雜,我就不詳細介紹了,在PostMan中進行Search方法的測試,效果如下:

ElasticSearch入門 附.Net Core例子

查詢要求是type是567,響應的實體中,type确實為567,Success!

項目完整代碼:https://github.com/liuzhenyulive/Elasticsearch.Net-Demo

 另外推薦一個不錯的ElasticSearch學習資料: ElasticSearch教程

不定期分享.Net實用幹貨,歡迎關注

ElasticSearch入門 附.Net Core例子