:::tips
持续更新中
:::
模块 | 序号 | 目录 | 链接 |
---|---|---|---|
前言介绍 | 1 | 前言 | |
2 | 介绍 | ||
基础知识 | 3 | 计算机网络 | |
4 | Linux操作系统 | ||
5 | Java基础 | ||
6 | 并发编程与并发安全 | ||
7 | JVM | ||
中间件 | 8 | Mysql | |
9 | Redis | ||
10 | Elasticsearch | ||
11 | RabbitMQ | ||
12 | RocketMQ | ||
框架 | 13 | 分布式系统与微服务 | |
14 | MyBatis | ||
15 | Dubbo | ||
16 | Spring | ||
17 | Spring MVC | ||
18 | Spring Boot | ||
19 | Spring Cloud | ||
20 | Spring Cloud Alibaba Nacos | ||
21 | Spring Cloud Alibaba Sentinel | ||
22 | Spring Cloud Alibaba Seata | ||
23 | Tomcat | ||
24 | Netty | ||
容器 | 25 | Docker | |
26 | Kubernetes | ||
架构设计 | 27 | 场景架构设计 | |
28 | 领域驱动设计 | ||
29 | 设计模式 | ||
数据结构与算法 | 30 | 数据结构与算法 | |
31 | LeetCode题解 |
Elasticsearch
基本概念
简要介绍下ES的基本概念
:::tips
Elasticsearch(通常简称为 ES)是一个开源的分布式搜索和分析引擎,基于 Apache Lucene 构建,广泛用于处理大规模数据的搜索和分析。以下是 Elasticsearch 的一些基本概念:
1. 核心功能
- 全文搜索:Elasticsearch 提供强大的全文搜索功能,支持复杂查询、评分和分析。
- 实时数据检索:Elasticsearch 能够在几乎实时的情况下存储和检索数据,适合实时数据分析和监控。
- 分布式架构:Elasticsearch 可以水平扩展,将数据分布到多个节点,保证高可用性和负载均衡。
2. 重要术语
- 节点(Node):Elasticsearch 集群中的单个实例,作为数据存储和查询的工作单位。每个节点都有一个唯一的标识符。
- 集群(Cluster):由多个节点组成,所有节点共同工作以处理数据和响应请求。通常由一个主节点(Master Node)负责协调集群操作。
- 索引(Index):逻辑上的数据集合,类似于数据库中的数据库表。每个索引使用特定的文档类型和配置进行存储。
- 文档(Document):存储在索引中的基本信息单位,类似于关系型数据库中的行。文档以 JSON 格式存储,包含字段和对应的值。
- 类型(Type)(注意:在新版 Elasticsearch 中已不推荐使用):定义文档的结构和字段。通过类型来区分索引中的不同文档。
- Shard(分片):每个索引可以被分割成多个分片,分片支持水平扩展,允许将数据分布到多个节点。主分片用于存储数据,副本分片提供冗余和故障恢复。
- 查询(Query):一种从索引中检索文档的方式,支持多种查询语言(如 DSL),可执行复杂的搜索和过滤操作。
3. 数据存储和映射
- 映射(Mapping):定义一个索引的结构,确定每个字段的数据类型(如字符串、数字、日期等)及其属性(如是否可索引、是否存储等)。
- 分析器(Analyzer):用于处理输入数据,以便为搜索和索引优化。分析器会分词、去除停用词和进行其他处理。
4. 应用场景
- 日志分析:常用于日志管理解决方案(如 ELK 栈:Elasticsearch, Logstash, Kibana)。
- 实时搜索引擎:适用于电子商务网站、内容管理系统等。
- 数据分析:可以通过聚合查询在海量数据中生成统计信息。
- 全文检索:为网站和应用程序提供高效的搜索体验。
5. 整合和扩展
Elasticsearch 可以与多种其他工具和框架整合,包括:
- Kibana:用于可视化 Elasticsearch 数据的前端工具。
- Logstash:数据处理管道,用于在多种数据源之间获取、处理和传输数据。
- Beats:轻量级的数据传输代理,用于将日志和其他数据发送到 Elasticsearch。
总结
Elasticsearch 是一个强大的搜索和分析引擎,广泛应用于数据存储、检索和分析。通过分布式架构、高效的查询功能和灵活的数据建模能力,Elasticsearch 适合各种复杂的搜索和数据分析任务。
:::
倒排索引
什么是倒排索引,并给出示例
:::tips
倒排索引是一种用于快速全文搜索的数据结构。其基本原理是:
- 正向索引:记录文档中每个词汇到其所在文档的映射。
- 倒排索引:记录每个词汇到包含该词汇的文档列表和位置的映射。
简单来说,倒排索引将关键词映射到其出现的文档上。这种方式能够快速查找到包含特定关键词的所有文档,从而提高搜索效率。倒排索引广泛应用于搜索引擎和文本检索系统中。
倒排索引是一种数据结构,用于快速检索包含特定词汇的文档。它将文档中的词汇与包含该词汇的文档ID关联起来。
示例:
假设我们有三个文档:
- 文档1: “猫 在 爬 树”
- 文档2: “狗 在 撒娇”
- 文档3: “猫 也 喜欢 喝 水”
正向索引可能看起来像这样:
倒排索引则是:
查询示例:
如果要找到包含“猫”的文档,只需查找倒排索引中“猫”的条目,得到文档ID [1, 3]。这样就能快速检索到所有包含该词的文档。
:::
Text和KeyWord
:::tips
在Elasticsearch中,text
和keyword
类型用于处理字符串数据,但它们的用途和特性有所不同:
text
类型
- 用途: 主要用于全文搜索的字段。
- 分析: 输入的文本会经过分析器(如分词、去除停用词等),将其拆分成多个词项。
- 支持: 可以执行模糊搜索、短语搜索、分词查询等。
- 示例: 用于文章内容、评论等需要进行全文检索的文本。
keyword
类型
- 用途: 主要用于精确匹配,不需要分词。
- 不分析: 原始字符串数据被索引,适合用作标识符、标签、分类等。
- 支持: 可用于聚合、排序、过滤,但不支持全文搜索。
- 示例: 用于ID、分类、状态标志等需要完全匹配的字段。
总结
**text**
: 用于全文检索,支持分词和模糊搜索。**keyword**
: 用于精确匹配,不支持分析,适合聚合和排序。
两个的区别主要分词的区别:
keyword 类型是不会分词的,直接根据字符串内容建立倒排索引,keyword类型的字段只能通过精确值搜索到;
Text 类型在存入 Elasticsearch 的时候,会先分词,然后根据分词后的内容建立倒排索引
:::
停顿词过滤
:::tips
停顿词过滤(Stop Word Filtering)是一种文本处理技术,用于移除在搜索或文本分析中没有实际意义的常见词汇。这些词汇通常是高频率出现但对理解句子内容贡献较小的词。
停顿词的例子
在英语中,常见的停顿词包括:
- “the”
- “is”
- “and”
- “in”
- “at”
在中文中,例如:
- “的”
- “了”
- “在”
- “是”
作用
- 减少索引大小:移除停顿词可以减少索引的体积,提高性能。
- 提高查询效率:搜索时忽略无意义的词汇,减少匹配非相关文档的可能性。
- 增强相关性:将重点放在具有实质性含义的词汇上,从而提升结果的相关性。
在Elasticsearch等搜索引擎中,通常内置了停顿词列表,并能够配置停顿词过滤器以满足不同的需求。
:::
Query和Filter
:::tips
query:查询操作不仅仅会进行查询,还会计算分值,用于确定相关度;
filter:查询操作仅判断是否满足查询条件,不会计算任何分值,也不会关心返回的排序问题,同时,filter 查询的结果可以被缓存,提高性能
总结
- 使用
query
时关注相关性和评分,使用filter
时关注结果的限制和效率。通常可以将两者结合使用,以实现更复杂的查询需求。
:::
深分页问题
详细说下ES深分页问题以及滚动搜索
:::tips
Elasticsearch的深分页问题主要与性能和资源消耗有关。以下是详细解释以及解决方案,包括滚动搜索的使用。
深分页问题
1. 问题描述
- 当使用
from
和size
进行分页时,尤其是from
参数值较大时(比如大于10000),Elasticsearch会逐页检索所有记录以计算相关性。 - 这种方法会严重影响性能,导致高内存消耗、查询速度降低以及显著的响应延迟。
2. 性能影响
- 内存消耗:Elasticsearch需要维护很多文档的状态,导致内存占用增加。
- 查询速度:深层分页需要遍历大量文档来找到所需的结果,影响查询速度。
- 负载增加:负载均衡器可能会受到影响,因为过多请求将消耗更多的CPU和内存。
滚动搜索
为了解决深分页问题,Elasticsearch引入了滚动搜索(Scroll API),适用于需要遍历大数据集的场景,尤其是在数据(如批处理)导入或需要同一查询多次遍历时。
1. 滚动搜索的特点
- 更高效的遍历:使用滚动搜索时,Elasticsearch创建一个游标,后续请求基于这个游标,不需要重复计算所有文档的相关性。
- 稳定的快照:滚动搜索在索引创建滚动时,不受数据变化影响,适合处理快照。
2. 使用滚动搜索的基本步骤
- 初始化滚动搜索请求:
- 获取滚动ID:响应中将包含一个
_scroll_id
,用于后续请求。 - 继续检索:
- 重复步骤:继续发送滚动请求,直到没有更多结果为止。
- 清理:完成后,可以用以下请求清理滚动会话:
适用场景
- 大数据导入:在将大量数据导入Elasticsearch时,滚动搜索可以确保所有数据都被处理。
- 批量处理:导出、处理或分析大量日志数据时,滚动搜索非常适合。
总结
- 深分页问题会影响Elasticsearch的性能,使用
from
和size
时,建议尽量避免大数量级的分页请求。 - 滚动搜索提供了一种高效的方式来遍历大量文档,适合处理大数据集并且有效降低系统负担。
为什么from越大越影响性能呢
在Elasticsearch中,使用from
进行深分页时,越大对性能的影响主要是由于以下几个原因:
1. 内存占用
- 文档状态维护:当执行分页查询时,Elasticsearch需要维护当前索引中的所有文档状态,包括它们的文档ID、相关性等信息。
from
越大,所需维护的状态越多,导致内存使用量显著增加。
2. 排序和相关性计算
- 获取所有文档:为了返回特定的页面,Elasticsearch首先计算满足查询条件的所有文档,并为它们打分(排序)。当
from
值较大时,搜索引擎需要查找并计算许多文档的相关性,然后从中排除大量文档以找到需要返回的页面。
3. I/O性能
- 本地文件访问:为满足
from
和size
的要求,Elasticsearch可能需要在物理磁盘上频繁读取数据,尤其是在深层分页时,这将导致更多的I/O操作,进一步影响查询响应时间。
4. 索引查询效率
- 逐层遍历:深分页实际上是一种逐层微博访问。即使返回的是第N页的结果,Elasticsearch仍然需要遍历前N-1页的结果,以确保正确性和相关性排序。这种遍历是一个线性过程,导致查询效率下降。
5. 吞吐量下降
- 负载增加:当系统需要处理大量的分页请求时,尤其是深层分页,可能会导致吞吐量下降,整个集群的查询效率因此受到影响。
总结
from
值越大,系统需要处理的文档数量和相关性计算显著增加,导致内存和I/O开销变大,从而影响整体性能。这就是为什么在设计分页查询时建议避免使用非常大的from
值,尤其是农场查询的场景。对于深分页,需要考虑使用滚动搜索或其他方案来改善性能。
介绍下scroll after与scroll的区别
Elasticsearch提供了两种主要的方式来处理大规模数据集的遍历:Scroll
和Search After
。这两者在使用场景和实现机制上有一些显著的区别。
1. Scroll
概述
- 针对大数据集:
Scroll
适用于需要遍历大量数据的场景,特别是当你需要处理或导出大量文档时。
特点
- 快照:
Scroll
在开始时创建一个固定的快照,以确保在滚动期间数据状态不变(即使有新的文档被索引或已删除)。 - 游标:每次滚动请求都会返回一个
_scroll_id
,用于获取下一批文档。你可以通过向/_search/scroll
请求这个_scroll_id
来获取结果。 - 高内存消耗:在处理大量文档时可能会消耗较多内存,因为它需要维护游标和文档状态。
示例
2. Search After
概述
- 适用于深分页:
Search After
用于实现深分页或实时数据获取,特别适合于对数据排序的情况下想要获取下一批结果,而不是遍历大量文档。
特点
- 无快照:
Search After
不创建快照,适合用来处理实时数据,能够反映出在请求之间的更新情况。 - 基于排序的游标:它使用上一批结果中的最后文档的排序值来找到下一批结果,而不是维护游标。你需要显式指定排序字段。
- 低内存开销:相比
Scroll
,Search After
在内存占用上较小,因为不需要维护整个请求的状态。
示例
总结
- Scroll:
- 适合大量数据的遍历,提供固定快照,节省文档在
scroll
期间的完整状态。 - 内存消耗高,因为维护游标。
- 适合大量数据的遍历,提供固定快照,节省文档在
- Search After:
- 适合深分页和需要处理实时更新数据的场景,不创建快照,记住排序值以获取下一批结果。
- 内存消耗相对较低,不维护状态,只依赖于排序结果的最后一项。
选择使用Scroll
还是Search After
主要取决于具体的用例、数据更新频率及所需性能。
:::
读写一致性保证
ES在高并发下如何保证读写一致的
:::tips
在Elasticsearch中,高并发环境下保证读写一致性是一个重要的问题。虽然Elasticsearch并不是一个传统的关系数据库,但它提供了一些机制来帮助达到一定程度的读写一致性。以下是一些主要方法:
1. 写一致性配置
- 刷新控制:
- Elasticsearch使用
refresh
机制来控制何时将写入的数据对搜索可见。默认情况下,每秒会刷新一次索引,但可以通过调整设置来手动控制。这对于高并发环境下的写操作非常重要。 - 在大量写入期间,可以暂时将
refresh_interval
设置为-1
,然后在写入完成后手动刷新。
- Elasticsearch使用
- 请求级别的写一致性:
- 在写入文档时,可以通过指定
refresh
参数来确保写操作的可见性。 - 例如,使用
POST /your_index/_doc/1?refresh=true
,使得写入立即对后续的读取可见。
- 在写入文档时,可以通过指定
2. 读一致性设置
- 版本控制:
- Elasticsearch提供了乐观锁机制,通过版本号来控制并发写入。每次更新时,可以指定版本号,只有在版本一致时才会进行更新。
- 强一致性查询:
- Elasticsearch保证的是最终一致性,因此在读取时可以通过设置
preference
参数来实现某种形式的一致性。例如,设置为_primary
或_primary_first
将确保从主分片读取数据。
- Elasticsearch保证的是最终一致性,因此在读取时可以通过设置
3. 集群状态管理
- 分片与副本:
- Elasticsearch采用分片和副本机制来提高可用性,确保读操作可以从任何副本中读取,从而提高并发处理能力。配置分片和副本数量时可以考虑负载均衡。
总结
虽然Elasticsearch主要是设计用作搜索引擎,并不提供传统意义上的强一致性,但通过合理的配置和优化,可以在高并发环境中实现一定程度的读写一致性。根据具体的业务需求和场景,选择合适的策略和配置来平衡性能与一致性是关键。
:::
写入流程
ES的写入流程
:::tips
Elasticsearch的写入流程是相对复杂的,涉及多个步骤,以确保数据的持久性和高效性。下面是Elasticsearch的写入流程的详细步骤:
1. 接收写入请求
- 请求解析:当Elasticsearch接收到索引或更新请求时,首先解析请求的内容,包括索引的名称、文档类型、文档ID以及文档的内容。
2. 路由计算
- 确定分片:根据索引的配置和文档的ID,Elasticsearch会计算出将该文档存储到哪个主分片。每个索引会根据哈希算法将文档ID映射到特定的分片。
3. 主分片写入
- 请求转发:写入请求会被发送到相应的主分片。
a. 数据处理
- 文档处理:在主分片中,系统会处理请求的文档,包括解析、验证等。
- 版本控制:Elasticsearch使用乐观锁定机制,通过版本号跟踪文档的变化,确保并发写操作的一致性。
4. 写入数据
- 倒排索引更新:在主分片中,文档被写入到内存中的数据结构(如倒排索引、文档表等)。这部分是Elasticsearch快速搜索的基础。
a. 内存缓冲
- 写入到内存:初始写入通常会在内存中进行,文档会被写入到称为“刷新缓冲区”的内存结构。这个缓冲区会定期刷新到磁盘。
5. 刷新到磁盘
- 刷新操作:当达到一定条件或者手动触发时,Elasticsearch会将内存中的改变刷新到持久层(如Lucene索引)。
- 创建段:在刷新过程中,Elasticsearch会生成一个新的段文件,将新的索引数据持久保存到磁盘。这一过程不会影响正在进行的写入操作。
6. 副本分片更新
- 转发到副本分片:在主分片完成写入后,Elasticsearch会将写入请求转发给相关的副本分片。
- 一致性:副本分片会执行相同的写入操作,以保持数据的冗余和一致性。
7. 完成响应
- 响应客户端:在主分片和副本分片完成写入操作后,Elasticsearch会返回响应给客户端,通常包括写入操作的结果(如文档ID、索引状态等)。
8. 清理过期数据
- 后台进程:经过一段时间后,Elasticsearch会执行后台任务,清理过期或被删除的文档,以释放资源和优化性能。
总结
Elasticsearch的写入流程确保了数据的快速索引和持久化。虽然写入过程涉及多个步骤,但通过内存缓冲、段创建和副本策略,Elasticsearch能够支持高并发的写入,同时保持数据的可靠性和一致性。这种架构特别适合现代应用中的高频率写操作和实时搜索场景。
:::
更新删除流程
ES的更新和删除流程
:::tips
Elasticsearch中的更新和删除流程相对复杂,但可以分为几个主要步骤。以下是对这两个操作的详细介绍:
更新流程
- 接收更新请求
- 当客户端发送更新请求时,Elasticsearch首先解析请求,包括目标索引、文档ID及更新内容。
- 路由计算
- Elasticsearch根据文档ID计算目标主分片,以确定将更新请求转发到哪个分片。
- 请求转发到主分片
- 将更新请求发送到相应的主分片。
- 读取现有文档
- 在进行更新时,Elasticsearch会先从主分片中读取目标文档的当前版本,以确保数据的正确性和一致性。
- 文档处理
- 根据请求中的内容,Elasticsearch会合并现有文档与更新内容(可以是添加、修改或删除字段)。
- 版本控制
- Elasticsearch使用乐观并发控制,检查文档的版本以防止丢失更新。如果文档被其他进程修改过,更新将会失败。
- 写入新文档
- 更新后的文档会被写入到内存中的数据结构(如倒排索引)。
- 刷新操作
- 在适当时机,内存中的改变会被刷新到磁盘,生成新的段文件。
- 副本分片更新
- 更新完成后,请求会被转发给相关的副本分片,以确保副本数据的一致性。
- 响应
- 完成所有更新操作后,Elasticsearch会将操作的结果返回给客户端。
更新请求示例
删除流程
- 接收删除请求
- 客户端发送删除请求,Elasticsearch解析请求,包括目标索引和文档ID。
- 路由计算
- 与更新操作相同,Elasticsearch根据文档ID计算目标主分片。
- 请求转发到主分片
- 将删除请求发送到相应的主分片。
- 删除操作
- 在主分片中,Elasticsearch会标记文档为“删除”。这实际上是将文档从索引中标记为存在,但不会立即删除物理存储的内容。
- 写入更新
- 删除标记会被写入到内存中,加入到当前的文档结构中(如倒排索引)。
- 刷新操作
- 删除标记会在适当时机被刷新到磁盘,这样后续查询时将不会返回被删除的文档。
- 副本分片更新
- 删除请求将会被转发给相应的副本分片,以确保副本中的数据同样被标记为删除。
- 响应
- 最后,Elasticsearch将删除操作的结果返回给客户端。
删除请求示例
总结
- 更新操作:
- 先读取文档,进行版本校验,合并内容后再写入新的文档。
- 使用乐观锁确保一致性,处理更复杂,因为需要先读取现有数据。
- 删除操作:
- 直接标记文档为删除,并且不会立即删除底层的存储。
- 完成后将请求转发给副本分片,确保一致性。
这两个操作都是在Elasticsearch中保持数据一致性的关键,采用了类似的逻辑,同时也考虑了性能和资源管理。
:::
搜索流程
按照query和fetch两阶段,介绍下es搜索流程
:::tips
Elasticsearch的搜索流程可以被分为两个主要阶段:Query阶段和Fetch阶段。下面详细介绍这两个阶段的工作原理。
1. Query 阶段
在Query阶段,Elasticsearch负责解析请求并进行初步的文档匹配。具体过程如下:
a. 请求解析
- 请求接收:Elasticsearch接收到搜索请求,解析请求内容,包括查询语法和参数。
- 路由选择:根据请求指定的索引,确定需要搜索的分片(包括主分片和副本)。
b. 查询执行
- 生成查询:请求中的查询条件被转换为内部Lucene查询格式。
- 搜索:针对每个相关分片执行查询。Elasticsearch会在每个分片上查找与查询条件相匹配的文档。
c. 计算相关性
- 倒排索引:使用倒排索引,使得在每个分片中快速定位到符合查询条件的文档。
- 相关性评分:为每个匹配的文档计算相关性得分(如TF-IDF或BM25算法),这将影响文档的显示顺序。
d. 向客户端发送中间结果
- 收集文档及得分:从每个分片收集匹配的文档ID和其相关性得分。
2. Fetch 阶段
在Fetch阶段,Elasticsearch负责进一步获取文档的详细信息并准备最终结果。具体过程如下:
a. 获取文档
- 从文档存储中获取:使用在Query阶段中收集到的文档ID,从Elasticsearch的存储中加载完整文档信息。
b. 应用排序和过滤
- 排序:根据相关性得分和请求中指定的排序字段,对文档进行排序。
- 过滤:应用任何过滤条件,确保只有符合请求要求的文档被返回。
c. 聚合计算
- 聚合处理:如果请求中包括聚合操作,Elasticsearch将在此阶段计算所需的聚合结果(如计数、平均值等)。
d. 返回结果
- 组装响应:将最终的文档列表和聚合结果整合成响应,并将其返回给客户端。返回的数据格式通常包括文档的source字段、ID、类型等信息。
总结
- Query 阶段:
- 负责请求解析、路由选择、查询执行和计算相关性得分。
- 初步匹配文档并生成文档ID列表。
- Fetch 阶段:
- 负责加载文档详细信息、应用排序和过滤、计算聚合以及准备最终响应。
这个两阶段流程为Elasticsearch高效的搜索能力提供了支撑,确保在大规模数据集上执行复杂查询时仍能保持良好的响应时间和资源管理。
:::
建立索引性能优化
建立索引阶段性能提升方法
:::tips
在建立Elasticsearch索引的阶段,可以采取以下措施来提升性能:
1. 批量索引处理
- 使用Bulk API: 将多个索引请求合并为一个批量操作,显著减少请求的开销。
2. 关闭自动刷新
- 调整刷新间隔: 在进行大量数据导入时,临时关闭或延长索引的刷新间隔,完成所有数据写入后再手动刷新。
3. 控制副本数
- 临时减少副本数: 在数据导入期间,将副本数设置为0,以提高写入速度
4. 优化Mapping
- 选择合适字段类型: 根据具体需求设置字段类型,尽量使用
keyword
而非text
,避免不必要的分析。 - 关闭不必要索引: 对于不需要在搜索中使用的字段,设置
index: false
。
5. 合理设置分片
- 分片数调整: 确保索引的分片数合理。分片过多会增加开销,而过少则会导致资源浪费。
6. 文档大小控制
- 控制文档大小: 保持单个文档的大小在100 KB到1 MB之间,以实现更好的性能。
7. 使用压缩
- 启用压缩设置: 可以在创建索引时启用
codec
以进行数据压缩,降低存储需求。
8. 调整硬件资源
- 使用SSD: 在SSD上存储索引,以提高I/O性能。
- 内存配置: 确保Elasticsearch节点具有足够的内存,以便更好地处理索引和缓存数据。
9. 合理使用索引模板
- 索引模板: 使用索引模板来自动设置映射和设置,确保所有新索引都使用相同的优化配置。
10. 监控和调优
- 使用监控工具: 监控索引建立的性能,并根据使用情况进行调整。可以利用Kibana等工具进行可视化监控。
通过这些策略,可以有效提升Elasticsearch在索引建立阶段的性能,缩短数据导入的时间,提高系统的响应速度。
:::
分布式原理
ES的分布式原理
:::tips
Elasticsearch是一个基于Lucene构建的分布式搜索引擎,具备高可用性、可扩展性和故障恢复的能力。下面是Elasticsearch的分布式原理的详细分解:
1. 集群架构
- 集群:一个Elasticsearch集群是由一个或多个节点组成的,可以在多个物理或虚拟机器上运行。集群通过网络连接在一起。
- 节点:每个节点是集群的一部分,存储数据并执行操作。节点的类型包括主节点、数据节点和协调节点等。
- 主节点:负责管理集群的元数据,包括索引、分片、复制等的信息。
- 数据节点:存储实际的数据和索引,并负责CRUD操作及搜索请求。
- 协调节点:接受用户请求并将其分发到相应的数据节点,最终收集和汇总其结果。
2. 索引与分片
- 索引:Elasticsearch中的基本数据结构,用于存储文档。每个索引都是一个逻辑集合,可以对应数据库中的表。
- 分片:为了实现水平扩展,Elasticsearch将每个索引分割为多个部分,称为分片。每个分片都是一个Lucene索引。
- 主分片:每个索引的分片可以设置为多个主分片,主分片包含实际数据。
- 副本分片:为了确保高可用性,Elasticsearch会为每个主分片创建一个或多个副本。副本用于故障恢复和负载均衡。
3. 数据分布
- 负载均衡:Elasticsearch采用哈希算法将文档分配到各个主分片。具体来说,文档ID会经过哈希运算将其映射到特定的分片,使数据在集群中均匀分布。
- 副本分配:Elasticsearch会在集群中均匀地分配副本分片,确保副本可用并减少单点故障的风险。
4. 高可用性与故障恢复
- 主节点选举:集群中的节点可以通过选举产生一个主节点,主节点负责处理集群状态的变化(如分片的添加和删除)。
- 故障检测:集群周期性检查节点的健康状况(通过心跳检测),当节点失效时,副本会被提升为主分片,确保数据正常。
- 数据恢复:当新节点加入或发生节点故障时,Elasticsearch会重新分配分片,确保数据在系统中的完整性。
5. 查询与索引机制
- 查询分发:当查询请求到达集群时,协调节点会将请求分发到相关的数据节点上并并行执行,然后收集和聚合结果后返回给客户端。
- 全文搜索:分布式搜索使用倒排索引,不同分片中的文档相互独立,但可以有共同的搜索请求。这种设计使得Elasticsearch能够高效地处理大量的数据和复杂的查询。
6. 可扩展性
- 动态伸缩:可以根据负载需求添加或移除节点,Elasticsearch会自动识别并重新分配分片,保持集群的平衡。
- 资源管理:可以通过配置不同节点的角色和功能,优化资源使用,确保系统高效。
总结
Elasticsearch的分布式原理使其能够处理大规模的数据集,提供高可用性和可扩展性。通过动态的分片和副本管理、请求分发和故障恢复机制,Elasticsearch能够保证数据的可靠性和系统的高性能。这使得它适合用于实时数据分析和大规模搜索的场景。
:::
Master选举
ES是如何选举Master的
:::tips
Elasticsearch使用一种称为“Zen Discovery”的机制来选举主节点(Master Node),确保在集群中有一个主节点负责管理集群状态(如索引、分片等)。以下是Elasticsearch主节点选举的详细过程:
1. 节点发现
- 集群形成:所有节点在启动时都会尝试加入一个集群。节点通过配置的集群名称进行识别。
- 集群状态信息:各节点定期发送心跳消息,以检测其他节点的状态。如果某个节点在设定时间内未响应,它会被视为失效。
2. 候选主节点选择
- 节点优先级:在整个集群中,每个节点都有一个资格权重,用于选择主节点。在选举过程中,所有在线的节点都会参与,并通过投票算法共同决定主节点。
- 选举规则:
- 首先,最初的主节点会被认为是候选节点。
- 如果没有主节点,会从参与者中随机选择一个节点作为候选者。
- 每个节点有一个内部计数器,记录它的检查点。节点会根据这一记录的值进行比较,从而决定哪个节点是更有资格的主节点。
3. 投票过程
- 内存状态传播:每个节点存储有集群的版本号。节点会向其他节点发送自身的状态信息,包括它的序号和集群状态的哈希值。
- 投票规则:当节点发现自己在集群中,或在集群中有一个新主节点失效时,它会为一位候选节点进行投票。投票是基于节点的状态和版本号的。
4. 主节点选举算法
- 领先者选举:所使用的算法为“领导者选举”算法(类似于Raft算法):
- 只有一个节点能够获得多数票,成为集群的主节点。
- 这些投票由节点收集,并进行相应的统计。如果某个节点获得超过一半的投票,便被选为新的主节点。
- 节点失效处理:如果当前主节点失效,则其他节点会立即开始新的主节点选举。
5. 集群状态更新
- 新主节点建立:一旦选出新主节点,集群会被更新为新的状态,其中包括所有的索引和分片信息。
- 版本提高:主节点的选举会引起集群状态的版本更新,所有节点在此后会按照新的版本号开始工作。
6. 恢复操作
- 主节点恢复:失效的节点恢复后,会再次加入集群,其状态将与集群的新主节点同步,确保数据一致性。
总结
- 选举机制:Elasticsearch使用基于投票的选举算法来确保集群中始终有一个有效的主节点。
- 容错性:在主节点失效时,系统能够迅速选举出新的主节点,保证系统的高可用性。
- 版本控制:选举过程中,节点的版本控制确保了集群状态的唯一性和一致性。
这种机制确保了集群的稳定性和可靠性,使Elasticsearch能够灵活、动态地管理其分布式结构。
:::
脑裂问题
ES是如何避免脑裂的
:::tips
在分布式系统中,“脑裂”(Split Brain)指的是网络故障或其他问题导致集群中多个主节点同时存在的状态,这会造成数据不一致和系统不稳定。Elasticsearch通过一系列机制来避免脑裂现象,确保集群在出现分区时仍然保持一致性。以下是Elasticsearch防止脑裂的主要机制:
1. Zen Discovery
Elasticsearch使用Zen Discovery作为集群的发现与管理机制,它包含了一系列防脑裂的机制:
- 主节点选举:Zen Discovery使用基于选票(Quorum)的选举机制,每次选举需要获得集群中半数以上节点的投票(Quorum)。这一点确保了只有在大多数节点存在并进行通信的情况下,新的主节点才能被选举出来。
2. 节点权重和资格
- 优先级和优先节点:每个节点可以配置其角色和优先级。能够当选主节点的资格由多个因素决定,包括节点的状态、健康状况等。只有在收到大多数节点的认可后,才会进行主节点选举。
3. 心跳机制
- 定期心跳:所有节点都会定期发送心跳消息以确认其实时状态。只有在节点无法在一定时间内确认连接,才被视为失效。这种机制使得集群能够及时发现故障节点,并进行适当的选举。
4. 失效检测
- 时间限制:在检测到某个主节点失效时,其他节点会启动新的选举过程,但只有当能够联系的节点数超过一半时,才允许选举新的主节点。这防止了少数节点中的主节点选举成功而导致的脑裂现象。
5. 集群状态
- 一致性更新:主节点负责维护集群状态,而这个状态是一个版本控制机制。只有主节点可以进行集群状态的更新,确保所有的更改都是原子的和一致的。副本节点会根据主节点的状态更新自己,以防止状态不一致。
6. 最大分片数规则
- 防止过多副本:在集群中,如果某些主分片和它们的副本都位于相同的故障区中,会引发脑裂问题。Elasticsearch通过配置,确保每个主分片和其副本分片不会被放置在同一个物理或逻辑节点上。
7. 节点重连策略
- 恢复机制:当网络问题修复、失效的节点恢复时,Elasticsearch会及时检测和采用恢复机制,确保集群状态能够根据主节点的最新状态进行更新,避免掉入脑裂状态。
总结
通过以上的机制,Elasticsearch能够有效地避免脑裂问题,确保在出现网络分隔或节点失效时集群内部状态的一致性和稳定性。这些机制确保了系统的高可用性,避免了数据不一致的问题,使得Elasticsearch能够在分布式环境中稳定运行。
:::