Elasticsearch - 核心原理、特点、以及架构详解
作者:hangge | 2025-04-30 09:56
1,什么是 Elasticsearch?
(1)Elasticsearch 是一个分布式的全文检素引擎。它对 Lucene 的功能做了封装,具有实时搜索、稳定、可靠、快速等特点。
(2)Elasticsearch 主要包含以下特性:
- 支持分布式建立素引和搜索索引。
- 索引支持分片,以及自动负载均衡。
- 支持 REST API。
- 集群配置简单。
- 支持第三方插件(通过插件实现 Web 界面管理集群)。
2,Elasticsearch 的核心原理
(1)Elasticsearch 最重要的一个特点是天生支持分布式。可以这样说,Elasticsearch 就是为分布式而生的。
(2)为了便于理解 Elasticsearch,这里对 MySQL 和 Elasticsearch 做一个对比分析:
- MySQL 中有 Database(数据库)的概念。对应地,在 Elasticsearch 中有 Index(索引库)的概念。
- MySQL 中有 Table(表)的概念。对应地,在 Elasticsearch 中有 Type(类型)的概念。
- MySQL 中有 Row(行)的概念,表示一条数据。对应地,在 Elasticsearch 中有 Document(文档)的概念。
- MySQL 中有 Column(列)的概念,表示一条数据中的某个列。对应地,在 Elasticsearch 中有 Field(字段)的概念。
| MySQL | Elasticsearch |
| Database(数据库) | Index(索引库) |
| Table(表) | Type(类型),Elasticsearch 从 7x 版本开始取消了 Type |
| Row(行) | Document(文档) |
| Column(列) | Field(字段) |
(3)关于 Elasticsearch 中的 Type:
- Elasticsearch 在 1.x ~ 5.x 版本中是正常支持 Type 的,每一个 Index 下面可以有多个 Type。
- 在 6.0 版本中,每一个 Index 中只支持 1 个 Type,属于过渡阶段。
- 从 7.0 版本开始,取消了 Type。这也就意味着,每一个 Index 中存储的数据类型可以认为都是同一种,不再区分类型了。
Elasticsearch 取消 Type 主要还是基于性能方面的考虑。因为在 Elasticsearch 设计初期,设计者参考了关系型数据库的设计模型,存在 Type 的概念。但是,Elasticsearch 的搜索引擎是基于 Lucene 的,这种“基因”决定了 Type 是多余的。
- 在关系型数据库中,Table 是独立的。但是在 Elasticsearch 中,同一个 Index 中不同 Type 的数据,在底层是存储在同一个 Lucene 的索引文件中的。
- 如果同一个 Index 中的不同 Type 中都有一个 id 字段,则 Elasticsearch 会认为这两个 id 字段是同一个字段。那么,用户必须在不同的 Type 中给这个 id 字段定义相同的字段类型,否则,不同 Type 中的相同字段名称会在处理时出现冲突,会导致 Lucene 处理效率下降。
- 除此之外,在同一个 Index 的不同 Type 下存储“字段个数不一样的数据”会导致存储中出现稀疏数据,影响 Lucene 压缩文档的能力,最终导致 Elasticsearch 查询效率降低。
3,Elasticsearch 集群(Cluster)
(1)Elasticsearch 集群中有多个节点,其中一个为主节点,主节点是通过选举产生的。
(2)主从节点是对于集群内部来说的。Elasticsearch 的一个核心特性就是去中心化,从字面上来理解就是“无中心节点”(这是对于集群外部来说的)。因为,从外部来看,Elasticsearch 集群在逻辑上是一个整体,我们与任何一个节点的通信和与整个 Elasticsearch 集群的通信是等价的。
(3)主节点的职责是负责管理集群状态,包括:管理分片的状态、副本的状态,以及从节点的发现和删除。
4,Elasticsearch 索引库分片(Shard)
(1)Elasticsearch 集群可以把一个索引库分成多个分片。这样的好处是:可以把一个大的素引库水平拆分成多个分片,分布到不同的节点上,构成分布式搜索,进而提高性能和吞吐量。
注意:分片的数量只能在创建索引库时指定,在索引库创建后不能更改。
注意:在 Elasticsearch 7.0 版本之前,每一个索引库默认有 5 个分片。
(3)因为每一个 Elasticsearch 的分片底层对应的都是 Lucene 索引文件,单个 Lucene 索引文件最多存储“Integer.MAX_VALUE-128”个文档(数据)。
5,Elasticsearch 分片的副本(Replica)
(1)Elasticsearch 集群可以给分片设置副本,副本具有如下两个作用:
- 副本的第 1 个作用是提高系统的容错性:当某个分片损坏或丢失时,可以从副本中恢复。
- 副本的第 2 个作用是提高 Elasticsearch 的查询效率:Elasticsearch 会自动对搜索请求进行负载均衡。
提示:分片的副本数量可以随时修改。
(2)在默认情况下,每一个索引库只有 1 个主分片和 1 个副本分片(前提是 Elasticsearch 集群有 2 个及以上个数的节点。如果 Elasticsearch 集群只有 1 个节点,则素引库就只有 1 个主分片,不会产生副本分片,因为主分片和副本分片在 1 个节点中是没有意义的)。
提示:为了保证数据安全,以及提高查询效率,建议将分片副本数量设置为 2 或者 3。
6,Elasticsearch 数据恢复机制(Recovery)
(1)Elasticsearch 集群在有节点加入或退出时,会根据机器的负载对分片进行重新分配,“挂掉”的节点在重新启动时也会进行数据恢复。
(2)Cluster、Shard、Replica 这 3 者的关系如下图所示:

7,Elasticsearch 的分词原理
(1)Elasticsearch 在添加数据(即创建索引)时,会先对数据进行分词。在查询索引数据时,也会先根据查询的关键字进行分词。所以在 Elasticsearch 中,分词这个过程是非常重要的,涉及查询的效率和准确度。
(2)假设有一条数据,数据中有一个字段 titile,字段的值为 LexCorp BFG-9000。我们想在 Elasticsearch 中对这条数据创建索引,方便后期检索。创建素引和查询索引的大致流程如下图所示。

(3)图中左侧是创建索引的过程:
- 首先对数据利用空白字符进行切分,将 LexCorp BFG-9000 切分为 LexCorp 和 BFG-9000。
- 接着对词语进行切分,将 LexCorp 分为 Lex 和 Corp,将 BFG-9000 切分为 BFG 和 9000。
- 最后执行小写转换操作,将英文词语全部转换为小写。
(4)图中右侧是查询索引的过程。例如用户想查询 LexCorp BFG-9000 这条数据,但是具体的内容记不清了,大致想起来了一些关键词 Lex corp bfg9000。接下来就根据这些关键词进行查询。
- 首先对数据利用空白字符进行切分,将 Lex corp bfg9000 分为 Lex、corp 和 bfg9000。
- 接着对词语进行切分,Lex 和 corp 不变,将 bfg9000 分为 bfg 和 9000。
- 最后执行小写转换操作,将英文词语全部转换为小写。这样在检索时就可以忽略英文大小写了,因为前面在创建素引时也会将英文转换为小写。
- 到这里可以发现,通过 Lex corp bfg9000 是可以查询到 LexCorp BFG-9000 这条数据的。因为,在经过空白字符切分、词语切分、小写转换之后,这两条数据是一样的。在底层只要有一个词语是匹配的,就可以把这条数据查找出来。
8,Elasticsearch 的架构分析
(1)Elasticsearch 是在 Lucene 的架构之上做了进一步封装,所以 Elasticsearch 的架构比 Lucene 的架构复杂,如下图所示:


(2)各层级模块说明如下:
- Gateway:Elasticsearch 用来存储索引的文件系统,支持多种类型,最常见的是 LocalFileSysterm(本地文件系统)。
- Distributed Lucene Directory:分布式的 Lucene 文件系统。
- Index Module:Elasticsearch 的索引模块。
- Search Module:Elasticsearch 的搜素模块。
- Mapping:Elasticsearch 的元数据类型解析模块。
- Discovery:Elasticsearch 的节点发现模块。不同机器上的 Elasticsearch 节点要组成集群并进行消息通信,集群内部需要选举 Master 节点,这些工作都由 Discovery 模块完成。支持多种发现机制,例如 Zen、EC2、Azure、GCE 等。
- Scripting:用来支持在查询语句中插入 Javascript、Python 等脚本语言。Scripting 模块负责解析这些脚本。如果使用脚本语句则性能较低。
- Third Plugins:支持多种第三方插件。
- Transport:通信和数据传输模块。支持多种传输协议,例如 Thrift、Memecached、HTTP 等。
- JMX:Java 的管理框架。用来监控 Elasticsearch 应用。
- REST API:Elasticsearch 提供的上层抽象 API。可以通过 REST API 和集群进行交互。
- SQL:Elasticsearch 从 6.x 版本开始官方提供了 SQL 插件,可以通过 SQL 查询 Elasticsearch 中的索引数据。Java(Netty):Elasticsearch 使用的网络编程框架。
全部评论(0)