來源:碼農阿宇
連結:http://www.cnblogs.com/CoderAyu/p/9601991.html
1、什麼是ElasticSearch?
Elasticsearch是基於Lucene的搜尋引擎。它提供了一個分散式,支援多租戶的全文搜尋引擎,它具有HTTP Web介面和無樣式JSON檔案。
Elasticsearch是用Java開發的,根據Apache許可條款作為開源釋出。
我個人的理解是Elasticsearch(以下簡稱ES)是一個支援分散式的全文搜尋引擎,因為在海量資料搜尋時,普通關係型、非關係型資料庫因為IO讀取、處理器運算能力的限制,導致查詢效率難以提升,但是ES是分散式的(能把處理壓力分攤給每個節點),而且它是給每個詞建立索引,所以查詢效率極高,堪稱即時搜尋。
而且ES能搭配Kibana,實現資料的視覺化管理與資料分析。
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 入門教程(http://www.ruanyifeng.com/blog/2017/08/elasticsearch.html)
3、ES工作原理
Elasticsearch用於構建高可用和可擴充套件的系統。擴充套件的方式可以是購買更好的伺服器(縱向擴充套件)或者購買更多的伺服器(橫向擴充套件)。
Elasticsearch雖然能從更強大的硬體中獲得更好的效能,但是縱向擴充套件有它的侷限性。真正的擴充套件應該是橫向的,它透過增加節點來均攤負載和增加可靠性。如果我們啟動一個單獨的節點,它還沒有資料和索引,這個叢集看起來就像下圖。
叢集中一個節點會被選舉為主節點(master),它將臨時管理叢集級別的一些變更,例如新建或刪除索引、增加或移除節點等。
主節點不參與檔案級別的變更或搜尋,這意味著在流量增長的時候,該主節點不會成為叢集的瓶頸。任何節點都可以成為主節點。我們例子中的叢集只有一個節點,所以它會充當主節點的角色。
當索引建立完成的時候,主分片的數量就固定了,但是複製分片的數量可以隨時調整。
讓我們在叢集中唯一一個空節點上建立一個叫做 blogs 的索引。預設情況下,一個索引被分配5個主分片,但是為了演示的目的,我們只分配3個主分片和一個複製分片(每個主分片都有一個複製分片):
PUT /blogs
{
“settings” : {
“number_of_shards” : 3,
“number_of_replicas” : 1
}
}
我們的叢集現在看起來就像上圖,三個主分片都被分配到 Node 1 。
在單一節點上執行意味著有單點故障的風險:沒有資料備份。幸運的是,要防止單點故障,我們唯一需要做的就是啟動另一個節點。
如果我們啟動了第二個節點,這個叢集看起來就像下圖
第二個節點已經加入叢集,三個複製分片(replica shards)也已經被分配了,分別對應三個主分片,這意味著在丟失任意一個節點的情況下依舊可以保證資料的完整性。
檔案的索引將首先被儲存在主分片中,然後併發複製到對應的複製節點上。這可以確保我們的資料在主節點和複製節點上都可以被檢索。
隨著應用需求的增長,我們該如何擴充套件?如果我們啟動第三個節點,我們的叢集會自我感知,這時便成為了三節點叢集。
分片已經被重新分配以平衡負載:
從 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一條資料如下。
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,如下:
4.4 、資料的查詢
ES的資料查詢語法較為豐富,此處以一個最簡單的查詢為例,Http方法為POST,請求的Url中同樣指定了Index和Type
{
“query” : { “match” : { “tagline” : “for” }}
}
指的時查詢tagline中包含的for的資料,
其他更詳細的查詢語法,建議大家檢視Elasticsearch: 權威指南,此處主要拋磚引玉。
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
(); 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
Search(string type) {
return _client.Search
(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方法的測試,效果如下:
查詢要求是type是567,響應的物體中,type確實為567,Success!
專案完整程式碼:https://github.com/liuzhenyulive/Elasticsearch.Net-Demo
●編號148,輸入編號直達本文
●輸入m獲取文章目錄
Web開發
更多推薦《18個技術類公眾微信》
涵蓋:程式人生、演演算法與資料結構、駭客技術與網路安全、大資料技術、前端開發、Java、Python、Web開發、安卓開發、iOS開發、C/C++、.NET、Linux、資料庫、運維等。