文章目录
一、ElasticSearch是什么
Elasticsearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。
二、ElasticSearch可以用来做什么
- 搜索
- 分析
三、ES核心概念
1. 面向文档的ES
2.物理设计
ES在后台把每个索引划分成多个分片,每片分片可以在集群的不同服务器间迁移
3.逻辑设计
一个索引类型中,包含多个文档,比如文档1、文档2。当我们索引一篇文档时,可以通过 索引>类型>文档ID,索引到某个具体的文档。注意:ID不一定是数字
- 文档
相当于 Mysql中的一条条数据 - 类型
相当于Mysql中字段的类型[Varchar/Int],类型中对于字段的定义称为映射 - 索引
相当于数据库 - 节点和分片
- 倒排索引
所以倒排索引是什么?
根据标签找到对应的ID的方式,从ID找标签转为标签找ID的反向索引
- 倒排索引
四、分片和副本
1.分片
当有大量的文档时,由于内存的限制、磁盘处理能力不足、无法足够快的响应客户端的请求等,一个节点可能不够。这种情况下,数据可以分为较小的分片。每个分片放到不同的服务器上。
2.副本
分片的备胎。
启动 2 个 ES 节点,配置分片个数为 3,副本个数为 1(每个分片有一个副本)。如下图,蓝色的代表主分片,绿色的是副本,仔细一点不难发现,分片与其副本不在同一个节点内。这是非常合理的,因为副本本来就是主分片的备胎,当主分片节点挂了,另外一个节点的副本将会充当主分片,如果它们在同一个节点内,副本将发挥不到作用。
3.脑裂问题
- discovery.zen.minimum_master_nodes:这个参数的作用,就是告诉es直到有足够的master候选节点时,才可以选举出一个master,否则就不要选举出一个master。这个参数必须被设置为集群中master候选节点的quorum数量,也就是大多数。至于quorum的算法,就是:master候选节点数量 / 2 + 1。
eg:
3个节点,discovery.zen.minimum_master_nodes设置为2,是如何避免脑裂?
比如我们有3个节点,quorum是2.现在网络故障,1个节点在一个网络区域,另外2个节点在另外一个网络区域,不同的网络区域内无法通信。这个时候有两种情况
-
如果master是单独的那个节点,另外2个节点是master候选节点,那么此时那个单独的master节点因为没有指定数量的候选master node在自己当前所在的集群内,因此就会取消当前master的角色,尝试重新选举,但是无法选举成功。然后另外一个网络区域内的node因为无法连接到master,就会发起重新选举,因为有两个master候选节点,满足了quorum,因此可以成功选举出一个master。此时集群中就会还是只有一个master。
-
如果master和另外一个node在一个网络区域内,然后一个node单独在一个网络区域内。那么此时那个单独的node因为连接不上master,会尝试发起选举,但是因为master候选节点数量不到quorum,因此无法选举出master。而另外一个网络区域内,原先的那个master还会继续工作。这也可以保证集群内只有一个master节点。
五、分布式文档
1.路由
2.文档的写操作
新建、索引和删除请求都是写(write)操作,它们必须在主分片上成功完成才能复制到相关的复制分片上
上图过程:
- 客户端给Node 1发送新建、索引或删除请求。
- 节点使用文档的_id确定文档属于分片0。它转发请求到Node 3,分片0位于这个节点上。
- Node 3 在主分片上执行请求,如果成功,它转发请求到相应的位于 Node 1 和 Node 2 的复制节点上。当所有的复制节点报告成功,Node 3报告成功到请求的节点,请求的节点再报告给客户端。
- 客户端接收到成功响应的时候,文档的修改已经被应用于主分片和所有的复制分片。你的修改生效了。
3.搜索文档(单个文档)的过程
文档能够从主分片或任意一个复制分片被检索。
- 客户端给Node 1发送get请求。
- 节点使用文档的 _id 确定文档属于分片 0 。分片 0 对应的复制分片在三个节点上都有。此时,它转发请求到Node 2。
- Node 2 返回文档(document)给 Node 1 然后返回给客户端。
4.全文搜索
对于全文搜索而言,文档可能分散在各个节点上,那么在分布式的情况下,如何搜索文档呢?
搜索,分为2个阶段,搜索(query)+取回(fetch)。
- 搜索
- 客户端发送一个search(搜索)请求给 Node 3创建了一个长度为from+size的空优先级队
- Node 3 转发这个搜索请求到索引中每个分片的原本或副本。每个分片在本地执行这个查询并且结果将结果放到一个大小为 from+size 的有序本地优先队列里去。
- 每个分片返回document的ID和它优先队列里的所有document的排序值给协调节点Node 3。Node 3把这些值合并到自己的优先队列里产生全局排序结果。
- 取回
- 协调节点辨别出哪个document需要取回,并且向相关分片发出 GET 请求。
- 每个分片加载document并且根据需要 enrich 它们,然后再将document返回协调节点。
- 一旦所有的document都被取回,协调节点会将结果返回给客户端。