Elasticsearch是基于Lucene的搜索引擎。它提供了一个分布式,支持多租户的全文搜索引擎,它具备HTTP Web界面和无模式JSON文档。 Elasticsearch是用Java开发的,根据Apache许可条款做为开源发布。html
----来自维基百科的解释node
我我的的理解是Elasticsearch(如下简称ES)是一个支持分布式的全文搜索引擎,由于在海量数据搜索时,普通关系型、非关系型数据库由于IO读取、处理器运算能力的限制,致使查询效率难以提高,可是ES是分布式的(能把处理压力分摊给每一个节点),并且它是给每一个词建立索引,因此查询效率极高,堪称即时搜索。git
并且ES能搭配Kibana,实现数据的可视化管理与数据分析。github
Kibana仪表盘数据库
前面所过ES是一个分布式搜索引擎,其本质是一个分布式数据库,能够多台计算机上的ES实例协同工做,这里面的某一台计算机上的某个ES实例,就能够称为一个Node(节点),全部的这些协同工做的实例,能够称为一个Cluster(集群)。json
Elastic 会索引全部字段,通过处理后写入一个反向索引(Inverted Index)。查找数据的时候,直接查找该索引。api
因此,Elastic 数据管理的顶层单位就叫作 Index(索引)。它是单个数据库的同义词。每一个 Index (即数据库)的名字必须是小写。浏览器
Index 里面单条的记录称为 Document(文档)。许多条 Document 构成了一个 Index。服务器
Document 使用 JSON 格式表示,下面是一个例子。restful
{ "user": "张三", "title": "工程师", "desc": "数据库管理" }
同一个 Index 里面的 Document,不要求有相同的结构(scheme),可是最好保持相同,这样有利于提升搜索效率。
Document 能够分组,好比weather
这个 Index 里面,能够按城市分组(北京和上海),也能够按气候分组(晴天和雨天)。这种分组就叫作 Type,它是虚拟的逻辑分组,用来过滤 Document。
不一样的 Type 应该有类似的结构(schema),举例来讲,id
字段不能在这个组是字符串,在另外一个组是数值。这是与关系型数据库的表的一个区别。性质彻底不一样的数据(好比products
和logs
)应该存成两个 Index,而不是一个 Index 里面的两个 Type(虽然能够作到)。
根据规划,Elastic 6.x 版只容许每一个 Index 包含一个 Type,7.x 版将会完全移除 Type。
----参考阮一峰 全文搜索引擎 Elasticsearch 入门教程
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: 权威指南
由于每一个平台上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进行交互。
利用PostMan向ES POST一条数据以下。
http://localhost:9200/index/test1/1 中Index是该数据的Index(上文有介绍Index),test1是该数据的Type,1是该条数据的Id,该ID在经过ID获取数据时须要用到。
在知道数据的Index,Type和ID的状况下,能够经过和上文Post数据的Url同样的格式获取数据,不一样之处时,此时的HTTP方法时Get,以下:
ES的数据查询语法较为丰富,此处以一个最简单的查询为例,Http方法为POST,请求的Url中一样指定了Index和Type
{
"query" : { "match" : { "tagline" : "for" }}
}
指的时查询tagline中包含的for的数据,
其余更详细的查询语法,建议你们查看Elasticsearch: 权威指南,此处主要抛砖引玉。
在上文中,咱们了解到,能够经过restful api与ES进行交互,那么,若是须要在咱们的程序中使用ES,是否是要建立一个这样的Helper方法,经过HTTP调用RESTFul API与ES进行交互呢?
不是不能够,可是Elastic为大部分语言都建立了"Clients”,其实就是把上文说起的那些方法进行了一个封装,是咱们在代码中,可以方便地调用ES。
以.Net Core为例,该”Clients”开源在Github:
https://github.com/elastic/elasticsearch-net
在该仓库中,其实有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客户端。
本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方法的测试,效果以下:
查询要求是type是567,响应的实体中,type确实为567,Success!
项目完整代码:https://github.com/liuzhenyulive/Elasticsearch.Net-Demo
不按期分享.Net实用干货,欢迎关注!