Elasticsearch 介绍
ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。
从上图可以看出ES要掌握的几个要点:
- Index 类似于关系数据库里的数据库
- Type 类似于关系数据库里的表,但是ES6.0以后每个Index只允许有一个type,这是因为同一个Index里面的不同的type在字段名称相同的时候会受到影响。
- Node代表一台机器上的一个节点,当然一台机器上可以有多个节点,不过一般一个节点最合适,整个ES集群里不同节点之间相互交互,一个节点里可以有多个Index
- 一个节点里有多个Index,在物理存储方面,整个节点的数据被存储到分片中,默认情况下一个Index有5个主分片(可以根据需要自己设置主分片数量),其中每一个分片有一个复制分片,复制分片和主分片一般分布到不同的节点上,一方面可以应对容错,同时可以轮询应对高并发查询。
如图中所示,所有p开头代表主节点,r开头代表复制节点,对于某一索引,有3个主分片,每个主分片有p0有三个复制分片r0,那么当P0和3个r0分别部署到不同的节点上时候,我们每一个机器都有了所有的数据,那么对于一个查询请求,任意一台机器就可以应对。 - 默认一个Node有5个主分片,每个主分片有一个副本分片
针对不同的索引可以自己设置
PUT /blogs
{
“settings” : {
“number_of_shards” : 3,
“number_of_replicas” : 1
}
}
主分片数目一旦确定便不能更改
复制分片数目可以动态调整
PUT /blogs/_settings
{
“number_of_replicas” : 2
}
确定分片位置
shard = hash(routing) % number_of_primary_shards
这里的routing默认是_id,我们可以在插入数据的时候动态指定,加入routing字段值,这样能够保证按照业务逻辑来分离数据,不如根据中学生、高中生、小学生来根据routing来存储到制定的分片上,那么对于某些只查询不同阶段学生数据的查询只用查一个分片就行,不用查询所有的分片,然后把各个分片查询到的数据,排序展示。
ES如何索引数据?
新建、索引和删除单个文档
- 1.客户端向 Node 1 发送新建、索引或者删除请求。
- 2.节点使用文档的 _id 确定文档属于分片 0 。请求会被转发到 Node 3
因为分片 0 的主分片目前被分配在
Node 3 上。 3.Node 3 在主分片上面执行请求。如果成功了,它将请求并行转发到 Node 1 和 Node 2 的副本分片上。一旦所有的副本分片都报告成功, Node 3 将向协调节点报告成功,协调节点向客户端报告成功。
我们可以发送请求到集群中的任一节点。 每个节点都有能力处理任意请求。 每个节点都知道集群中任一文档位置,所以可以直接将请求转发到需要的节点上。 在下面的例子中,将所有的请求发送到 Node 1 ,我们将其称为 协调节点(coordinating node) 。(当发送请求的时候, 为了扩展负载,更好的做法是轮询集群中所有的节点。)
新建、删除时候直接操作主分片,然后复制主分片上的数据到复制负片上。这就是上面例子中为何会把请求转发到node3上的原因
取回单个文档
1、客户端向 Node 1 发送获取请求。
2、节点使用文档的 _id 来确定文档属于分片 0 。分片 0 的副本分片存在于所有的三个节点上。 在这种情况下,它将请求转发到 Node 2 。(也可以转发到NODE3或者直接从NODE1返回文档)
3、Node 2 将文档返回给 Node 1 ,然后将文档返回给客户端。
在处理读取请求时,协调结点在每次请求的时候都会通过轮询所有的副本分片来达到负载均衡。
分布式搜索
- 1.客户端发送一个 search 请求到 Node 3 , Node 3 会创建一个大小为 from + size 的空优先队列。
- 2.Node 3 将查询请求转发到索引的每个主分片或副本分片中。每个分片在本地执行查询并添加结果到大小为 from + size 的本地有序优先队列中。
- 3.每个分片返回各自优先队列中所有文档的 ID 和排序值给协调节点,也就是 Node 3 ,它合并这些值到自己的优先队列中来产生一个全局排序后的结果列表。
- 当一个搜索请求被发送到某个节点时,这个节点就变成了协调节点。 这个节点的任务是广播查询请求到所有相关分片并将它们的响应整合成全局排序后的结果集合,这个结果集合会返回给客户端。
- 一个索引可以由一个或几个主分片组成, 所以一个针对单个索引的搜索请求需要能够把来自多个分片的结果组合起来。 针对 multiple 或者 all 索引的搜索工作方式也是完全一致的–仅仅是包含了更多的分片而已。