天天看點

ElasticSearch入門 附.Net Core例子1.什麼是ElasticSearch?2.ES中名詞概念3.ES工作原理4.ES的安裝與使用5.Net Core中使用ES

1.什麼是ElasticSearch?

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

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

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

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

ElasticSearch入門 附.Net Core例子1.什麼是ElasticSearch?2.ES中名詞概念3.ES工作原理4.ES的安裝與使用5.Net Core中使用ES

                                                                           Kibana儀表盤

2.ES中名詞概念

2.1 Node和Cluster

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

2.2 Index

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

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

2.3 Document

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

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

{
  "user": "張三",
  "title": "工程師",
  "desc": "資料庫管理"
}
           

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

2.4 Type

Document 可以分組,比如

weather

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

不同的 Type 應該有相似的結構(schema),舉例來說,

id

字段不能在這個組是字元串,在另一個組是數值。這是與關系型資料庫的表的

一個差別

。性質完全不同的資料(比如

products

logs

)應該存成兩個 Index,而不是一個 Index 裡面的兩個 Type(雖然可以做到)。

根據

規劃

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

----參考

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

3.ES工作原理

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

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

ElasticSearch入門 附.Net Core例子1.什麼是ElasticSearch?2.ES中名詞概念3.ES工作原理4.ES的安裝與使用5.Net Core中使用ES

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

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

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

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

PUT /blogs

{

"settings" : {

"number_of_shards" : 3,

"number_of_replicas" : 1

}

ElasticSearch入門 附.Net Core例子1.什麼是ElasticSearch?2.ES中名詞概念3.ES工作原理4.ES的安裝與使用5.Net Core中使用ES

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

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

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

ElasticSearch入門 附.Net Core例子1.什麼是ElasticSearch?2.ES中名詞概念3.ES工作原理4.ES的安裝與使用5.Net Core中使用ES

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

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

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

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

ElasticSearch入門 附.Net Core例子1.什麼是ElasticSearch?2.ES中名詞概念3.ES工作原理4.ES的安裝與使用5.Net Core中使用ES

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

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

----參考文獻

Elasticsearch: 權威指南

4.ES的安裝與使用

4.1安裝

因為每個平台上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/

,如果您能看到下列結果,說明安裝完成。

{
    "name": "DESKTOP-1FC1B1D",
    "cluster_name": "elasticsearch",
    "cluster_uuid": "lZx4n2xzToeaj9k3HEHAqw",
    "version": {
        "number": "6.4.0",
        "build_flavor": "unknown",
        "build_type": "unknown",
        "build_hash": "595516e",
        "build_date": "2018-08-17T23:18:47.308994Z",
        "build_snapshot": false,
        "lucene_version": "7.4.0",
        "minimum_wire_compatibility_version": "5.6.0",
        "minimum_index_compatibility_version": "5.0.0"
    },
    "tagline": "You Know, for Search"
}      

"You Know, for Search"

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

4.2資料的送出

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

ElasticSearch入門 附.Net Core例子1.什麼是ElasticSearch?2.ES中名詞概念3.ES工作原理4.ES的安裝與使用5.Net Core中使用ES
http://localhost:9200/index/test1/1

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

4.3資料通過ID擷取

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

ElasticSearch入門 附.Net Core例子1.什麼是ElasticSearch?2.ES中名詞概念3.ES工作原理4.ES的安裝與使用5.Net Core中使用ES

4.4資料的查詢

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

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

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

ElasticSearch入門 附.Net Core例子1.什麼是ElasticSearch?2.ES中名詞概念3.ES工作原理4.ES的安裝與使用5.Net Core中使用ES

其他更詳細的查詢文法,建議大家檢視

,此處主要抛磚引玉。

5.Net Core中使用ES

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

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

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

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

5.1 SDK(用戶端,Clients)

在該倉庫中,其實有

Elasticsearch.Net

NEST

兩個.Net官方SDK,兩個各有特色。

Elasticsearch.Net

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

NEST

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

5.2建立一個Demo

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

PM> Install-Package NEST      

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

public class EsClientProvider : IEsClientProvider
    {
        private readonly IConfiguration _configuration;
        private ElasticClient _client;
        public EsClientProvider(IConfiguration configuration)
        {
            _configuration = configuration;
        }

        public ElasticClient GetClient()
        {
            if (_client != null)
                return _client;

            InitClient();
            return _client;
        }

        private void InitClient()
        {
            var node = new Uri(_configuration["EsUrl"]);
            _client = new ElasticClient(new ConnectionSettings(node).DefaultIndex("demo"));
        }
    }      

IEsClientProvider代碼如下:

public interface IEsClientProvider
    {
        ElasticClient GetClient();
    }      

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

public void ConfigureServices(IServiceCollection services)
        {

            services.AddSingleton<IEsClientProvider, EsClientProvider>();

            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
        }      

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

public class ValueController : ControllerBase
    {
        private readonly ElasticClient _client;

        public ValueController(IEsClientProvider clientProvider)
        {
            _client = clientProvider.GetClient();
        }

        [HttpPost]
        [Route("value/index")]
        public IIndexResponse Index(Post post)
        {
            return _client.IndexDocument(post);
        }

        [HttpPost]
        [Route("value/search")]
        public IReadOnlyCollection<Post> Search(string type)
        {
            return _client.Search<Post>(s => s
                .From(0)
                .Size(10)
                .Query(q => q.Match(m => m.Field(f => f.Type).Query(type)))).Documents;
        }
    }      

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

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

ElasticSearch入門 附.Net Core例子1.什麼是ElasticSearch?2.ES中名詞概念3.ES工作原理4.ES的安裝與使用5.Net Core中使用ES

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

項目完整代碼:

https://github.com/liuzhenyulive/Elasticsearch.Net-Demo

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

ElasticSearch入門 附.Net Core例子1.什麼是ElasticSearch?2.ES中名詞概念3.ES工作原理4.ES的安裝與使用5.Net Core中使用ES