> For the complete documentation index, see [llms.txt](https://lewiszlw.gitbook.io/notebooks/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://lewiszlw.gitbook.io/notebooks/storage/elasticsearch.md).

# Elasticsearch

## Elasticsearch节点类型

**1.主节点master**

* 创建或删除索引
* 跟踪哪些节点是集群的一部分
* 决定哪些分片分配给相关的节点

稳定的主节点对集群的健康是非常重要的，默认情况下任何一个集群中的节点都有可能被选为主节点，索引数据和搜索查询等操作会占用大量的cpu，内存，io资源，为了确保一个集群的稳定，分离主节点和数据节点是一个比较好的选择。

**2.数据节点data**

* 存储索引数据
* 对文档进行增删改查，聚合操作

数据节点对cpu，内存，io要求较高， 在优化的时候需要监控数据节点的状态，当资源不够的时候，需要在集群中添加新的节点。

**3.客户端节点**

* 处理路由请求
* 处理搜索
* 分发索引

当主节点和数据节点配置都设置为false的时候，该节点只能处理路由请求，处理搜索，分发索引操作等，从本质上来说该客户节点表现为智能负载平衡器。独立的客户端节点在一个比较大的集群中是非常有用的，他协调主节点和数据节点，客户端节点加入集群可以得到集群的状态，根据集群的状态可以直接路由请求。

## Elasticsearch副本和分片

**系统可用性**

* 服务可用性：在2个/多个节点的情况下，允许1个/一部分节点停止服务，整个集群依然可以对外提供服务；
* 数据可用性：引入副本(replication)解决1个/一部分节点停止，节点上数据也同时丢失的情况。此时每个节点都有完备数据。

**分片** 分片是ES能支持PB级别数据的基石。 a、分片存储部分数据，可以分布于任意节点； b、分片数在索引创建时指定，且后续不能更改，默认为5个； c、有主分片和副本分片之分，以实现数据的高可用； d、副本分片由主分片同步数据，可以有多个，从而提高数据吞吐量。

## Elasticsearch文档创建和读取

**文档创建的流程**

1. Client向node3发送创建文档请求；
2. node3通过routing计算该文档存储在shard1上，查询cluster state后，确认主shard1在node2上，然后转发请求到node2；
3. node2上的主shard1接收并执行创建文档的请求后，将同样的请求转发到副shard1，查询cluster state后，确认副shard1在node1，向node1发送请求；
4. node1上的副shard1接收并执行创建文档的请求后， 通知主shard1结果；
5. node2上的主shard1接收到副shard1创建文档成功的结果，通知node3创建成功；
6. node3返回结果给Client。

**文档读取的流程**

1. Client向node3发送读取文档doc1的请求；
2. node3通过routing计算该doc1在shard1上，查询cluster state后，确认主shard1和副shard1的位置，然后以**轮询**的机制获取一个shard(比如这次是主shard1，下次就是副shard1)；
3. 本次是在node2上的主shard1接收到读取文档的请求，执行并返回结果给node3；
4. node3返回结果给Client。

**文档批量创建的流程**

1. Client向node3发送批量创建文档请求(bulk)；
2. node3通过routing计算文档对应的所有shard，然后按主shard分配对应执行的操作，同时发送请求到其他的主shard；
3. 每个主shard接收并执行请求后，发送同样的请求到副shard；
4. 每个副shard接收并执行请求后，返回结果到主shard，再由主shard返回给 node3；
5. node3整合所有结果，并返回给Client。

**文档批量读取的流程**

1. Client向node3发送批量读取文档请求(bulk)；
2. node3通过routing计算文档对应的所有shard，再以轮询的机制，按shard构建mget请求，通过发送给设计的shard；
3. 由shard返回文档结果；
4. node3整合后返回结果到Client

## 倒排索引

在搜索引擎中，每个文档都有一个对应的文档 ID，文档内容被表示为一系列关键词的集合。例如，文档 1 经过分词，提取了 20 个关键词，每个关键词都会记录它在文档中出现的次数和出现位置。

倒排索引就是关键词到文档 ID 的映射，每个关键词都对应着一系列的文件，这些文件中都出现了关键词。

举例

| DocId | Doc                      |
| ----- | ------------------------ |
| 1     | 谷歌地图之父跳槽 Facebook        |
| 2     | 谷歌地图创始人拉斯离开谷歌加盟 Facebook |

对文档进行分词之后，得到以下倒排索引

| WordId | Workd    | DocIds |
| ------ | -------- | ------ |
| 1      | 谷歌       | 1, 2   |
| 2      | 地图       | 1, 2   |
| 3      | 之父       | 1      |
| 4      | 跳槽       | 1      |
| 5      | Facebook | 1, 2   |
| 6      | 创始人      | 2      |
| 7      | 拉斯       | 2      |
| 8      | 离开       | 2      |
| ..     | ..       | ..     |

另外，实用的倒排索引还可以记录更多的信息，比如文档频率信息，表示在文档集合中有多少个文档包含某个单词。
