Elasticsearch 是一个开源的、基于 Lucene 的分布式搜索和分析引擎,设计用于云计算环境中,能够实现实时的、可扩展的搜索、分析和探索全文和结构化数据。它具有高度的可扩展性,可以在短时间内搜索和分析大量数据。 Elasticsearch 不仅仅是一个全文搜索引擎,它还提供了分布式的多用户能力,实时的分析,以及对复杂搜索语句的处理能力,使其在众多场景下,如企业搜索,日志和事件数据分析等,都有广泛的应用。 本文将对 Elasticsearch 的基本概念进行介绍,包括索引、文档、字段、映射、节点、集群和分片等,帮助读者理解和使用 Elasticsearch。
1、Elasticsearch简介
1.1、ElasticSearch的诞生
2004 年,以色列人 Shay Banon 创造了一款名为 Compass 的搜索引擎,在考虑 Compass 的第三个版本时,他意识到有必要重写 Compass 的大部分内容,以"创建一个可扩展的搜索解决方案"。因此,他创建了"一个从头构建的分布式解决方案",并使用了一个公共接口,即 Http 上的 Json,它也适用于 Java 以外的编程语言。于是 Shay Banon 在 2010 年 2 月发布了 Elasticsearch 的第一个版本。
Elasticsearch 自从诞生以来,其应用越来越广泛,特别是大数据领域,功能也越来越强大,但是如何有效的监控管理 Elasticsearch 一直是公司所面对的难题,由于 Elasticsearch 集群的稳定性,决定了其业务发展的高度,对于一个应用来说其稳定是第一目标,所以完善的监控体系是必不可少的。
1.2、ElasticSearch概述
ElasticSearch 是一个分布式、高扩展、高实时的搜索与数据分析引擎,基于 Apache Lucene 实现。它提供了一个分布式的多用户的全文搜索引擎。它能很方便的使大量数据具有搜索、分析和探索的能力。充分利用 Elasticsearch 的水平伸缩性,能使数据在生产环境变得更有价值
Elasticsearch 提供了一个全文搜索的功能,但它不仅仅是一个搜索引擎。它还提供了分布式的实时文档存储,每个字段可以被索引与搜索。Elasticsearch 也能进行实时的数据分析,并能在近实时的情况下返回分析结果。
Elasticsearch 是用 Java 开发的,并作为 Apache 许可条款下的开源软件发布。它的 API 使用 JSON 作为数据交换的格式,支持各种语言的官方客户端,包括:Java、.NET(C#)、PHP、Python、Apache Groovy、Ruby 和许多其他语言。
ElasticSearch 主要特点包括:
- 分布式实时文件存储:每个字段都被索引并可被搜索;
- 分布式实时分析:搜索、稳定、可靠;
- 可扩展性:可以扩展到上百台服务器,处理 PB 级结构化或非结构化数据;
- 多租户:具有多种粒度的索引能力,例如可以对用户数据进行单独索引,也可以将所有用户的数据存储在一个索引中,并使用用户 ID 进行过滤或者聚合;
- 全文搜索:内置对全文搜索的支持,内部使用 Lucene 进行全文搜索;
- 安全:内置用户认证、权限控制、SSL/TLS 加密等安全特性;
- JSON/HTTP:使用 JSON 进行数据交互,提供了 RESTful API;
- 兼容性:支持多种语言客户端,如 Java、Python、PHP、JavaScript 等;
- 生态系统:Elasticsearch 是 Elastic Stack(也被称为 ELK Stack)的一部分,该栈还包括 Logstash(日志收集、处理和转发工具)、Kibana(数据可视化工具)和 Beats(轻量级数据采集器)
Ps:Lucene 是 Elasticsearch 所基于的 Java 库,它引入了按段搜索的概念。
1.3、ElasticStack概述
Elasticsearch 是与名为 Logstash 的数据收集和日志解析引擎以及名为 Kibana 的分析和可视化平台一起开发的。这三个产品被设计成一个集成解决方案,称为 “Elastic Stack”(以前称为"ELK stack")。
- Elasticsearch:是一个分布式、RESTful 搜索和分析引擎,能够解决不断增长的各种类型的数据的搜索问题;
- Logstash:是服务器端数据处理管道,能够同时从多个来源采集数据,转换数据,然后将数据发送到你选择的"存储库";
- Kibana:让用户可以在 Elasticsearch 中可视化和管理数据。它是 Elasticsearch 的窗口,任何希望从 Elasticsearch 索引中提取数据并将其可视化的人都会使用 Kibana;
- Beats:是一款轻量级的数据采集器,用于采集各种类型的数据并发送到 Logstash 或 Elasticsearch
以上产品同属于一家全球性的公司——Elastic,其专注于提供开源搜索和数据分析技术,Elastic 的产品广泛应用于企业搜索、日志和事件数据分析、实时应用监控、大数据分析等领域。Elastic 的使命是使搜索变得简单,帮助人们从数据中发现和理解有价值的信息。
2、ElasticSearch 是搜索引擎?还是数据库?
2.1、作为搜索引擎
作为搜索引擎,ElasticSearch 绝对稳坐该领域的头把交椅,其内核基于 Lucene 构建,支持全文搜索是职责所在,提供了丰富友好的 API。
但是在现在项目中,Elasticsearch 用作传统意义上全文检索的比重越来越少,多数时候是用来做精确查询加速,查询条件很多,可以任意组合,查询速度很快,替代其它很多数据库复杂条件查询的场景需求。;甚至有的数据库产品直接使用 Elasticsearch 做二级索引,如 HBase、Redis 等。因此 Elasticsearch 由于自身的一些特性,更像一个多模数据库。
图示:Elasticsearch 于 2022 年 12 月是综合数据库排名热度已经到第 7 位!
2.2、作为数据库
Elasticsearch 与大名鼎鼎的 MongoDB 十分相似,Elasticsearch 使用 Json 格式来承载数据模型(MongoDB 使用 Bson,类似于 Json),已经成为事实上的文档型数据库,虽然底层存储不是 Json 格式。不过二者在产品定位上有差别:
- Elasticsearch 更加擅长的基于查询搜索的分析型数据库,倾向 OLAP;
- MongoDB 定位于事务型应用层面 OLTP,虽然也支持数据分析,但是效果谁用谁知道~
值得注意的是 Elasticsearch 不是关系型数据库,内部数据更新采用乐观锁,无严格的 ACID 事务特性,任何企图将它用在关系型数据库场景的应用都会有很多问题!
2.3、ElasticSearch 的应用场景
Elasticsearch 虽然是基于 Lucene 构建,但应用领域确实非常宽泛:
- 全文检索:Elasticsearch 最初是作为一个全文搜索引擎而设计的,它将 Lucene 的复杂设置进行了封装,为开发人员提供了友好的接口,可以提供快速、实时的全文搜索服务,非常适合用于网站搜索、文档搜索等场景。
- 应用查询:Elasticsearch 最擅长的就是查询,基于倒排索引核心算法,查询性能强于 B-Tree 类型所有数据产品,尤其是关系型数据库方面。当数据量超过千万或者上亿时,数据检索的效率非常明显。
- 大数据:Elasticsearch 已经成为大数据平台对外提供查询的重要组成部分之一。大数据平台将原始数据经过迭代计算,之后结果输出到 Elasticsearch 提供查询,特别是大批量的明细数据。
- 日志检索:Elasticsearch 结合 Logstash 和 Kibana,形成了著名的 ELK 三件套,专门针对日志采集、存储、查询设计的产品组合。
- 监控领域:Elasticsearch 进入此领域比较晚,但由于其倒排索引核心算法,也是支持时序数据场景的,性能也是相当不错的,在功能性上完全压住时序数据库。
- 机器学习:Elasticsearch 本身是数据平台,集成了部分机器学习算法,同时又集成了 Kibana 可视化操作,使得从数据采集、到模型训练、到模型预测应用都可以一键式完成。
- 作为 NoSQL 数据库:Elasticsearch 支持分布式的 CRUD 操作,可以作为一个分布式的 NoSQL 数据库使用。
- 地理空间数据分析和搜索:Elasticsearch 支持地理空间数据的索引和搜索,可以用于地理位置搜索、地理空间数据分析等场景。
3、ElasticSearch逻辑结构
3.1、逻辑结构设计:索引
在 Elasticsearch 中,索引(Index)是具有类似特性的文档集合。每个索引都有一个唯一的名称来标识,这个名称必须全部是小写。当我们对文档进行索引、搜索、更新和删除操作时,都会引用到这个索引名称。
例如,我们可以创建一个名为 “customer” 的索引来存储所有的客户数据,创建一个名为 “product” 的索引来存储所有的产品数据。当我们需要搜索某个客户的信息时,就可以对 “customer” 索引进行搜索;当我们需要更新某个产品的信息时,就可以对 “product” 索引进行更新。
这种方式使得我们可以在 Elasticsearch 中组织和管理大量的数据,同时也能保证高效的搜索和查询性能
3.2、逻辑结构设计:类型
在 Elasticsearch 早期版本中,类型(Type)是索引的逻辑分类,用于将具有共同字段的文档分组在一起。每个类型都有自己的映射(Mapping),定义了类型中文档的字段名和字段类型。
然而,需要注意的是,从 Elasticsearch 7.0 开始,类型的概念已经被逐渐废弃,一个索引下只能有一个类型,或者完全不使用类型。这是因为多类型存在一些问题,如字段名冲突、内存浪费等,所以 Elasticsearch 决定逐步移除多类型的支持。在新的版本中,我们通常直接在索引级别定义映射,不再使用类型。
3.3、逻辑结构设计:映射
在 Elasticsearch 中,映射(Mapping)是定义索引中字段名和字段类型的过程,可以看作是 Elasticsearch 中的"模式定义"。映射定义了字段的名称、字段的类型(如文本、整数、日期等)、以及可能的一些额外信息(如是否该字段可以被搜索、是否存储原始值等)
Ps:Elasticsearch 允许在文档中添加映射中未定义的字段。这是因为 Elasticsearch 默认开启了动态映射(Dynamic Mapping)功能。 当 Elasticsearch 遇到映射中未定义的字段时,它会根据字段的内容自动推断字段类型,并更新映射。例如,如果一个新字段的值是一个日期字符串,Elasticsearch 会自动将这个字段映射为日期类型。 但是,也可以关闭动态映射功能,或者设置为严格模式,这样在遇到未定义的字段时,Elasticsearch 会抛出异常,而不是自动更新映射。 需要注意的是,虽然 Elasticsearch 允许动态添加字段,但是频繁修改映射会影响性能,而且一旦字段被映射为某种类型,就不能再改变类型。因此,对于重要的字段,最好在创建索引时就定义好映射。
3.4、逻辑结构设计:文档
在 Elasticsearch 中,文档(Document)是可以被索引的基本信息单位。每个文档都由一系列字段组成,每个字段都有自己的数据类型和值。文档以 JSON 格式表示,这使得 Elasticsearch 能够处理复杂、层次化的数据结构。
在 Elasticsearch 中,文档(Document)具有以下特征:
- 自我包含:一篇文档同时包含字段(如
name
)和它们的取值(如John Doe
)。这意味着文档包含了所有描述数据的信息; - 层次型结构:文档中的字段可以是简单的值,也可以是复杂的值,包含其他字段和取值。例如,“location” 字段可以是一个包含 “city” 和 “country” 字段的对象;
- 灵活的结构:文档不依赖于预先定义的模式。这意味着你可以为每个文档定义不同的字段。例如,并非所有的文档都需要 “description” 这个字段,所以可以彻底忽略该字段。同时,如果需要,可以为文档添加新的字段,如 “location” 的 “latitude” 和 “longitud”;
- JSON 格式:文档以 JSON 格式表示,这使得 Elasticsearch 能够处理复杂、层次化的数据结构,并且与许多现代编程语言的数据处理方式兼容;
- 可索引和可搜索:文档被存储在索引中,你可以对文档进行索引、搜索、更新和删除操作。每个文档都有一个唯一的 ID,你可以通过这个 ID 来引用文档。
这些特性使得 Elasticsearch 非常适合处理半结构化的数据,如 JSON,可以灵活地应对数据结构的变化。
3.5、逻辑结构设计:字段
在 Elasticsearch 中,字段(Field)是文档的一个属性或特性,每个字段都有一个字段名和字段值。字段的数据类型可以是简单的(如文本、数字、日期等),也可以是复杂的(如对象或者数组)。
例如,一个文档可能有一个名为 title
的字段用于存储标题,一个名为 date
的字段用于存储日期,等等。
字段的定义(包括字段名和字段类型)通常在映射(Mapping)中进行。
Ps:需要注意的是,虽然 Elasticsearch 允许动态添加字段(即在文档中添加映射中未定义的字段),但是一旦字段被映射为某种类型,就不能再改变类型。因此,对于重要的字段,最好在创建索引时就定义好映射。
3.6、逻辑结构类比
在关系数据库中,我们可以将 Elasticsearch 的索引(Index)类比为表(Table),将映射(Mapping)类比为表结构定义(Schema),将文档(Document)类比为表的行数据(Row)。
- 索引(Index):在 Elasticsearch 中,索引是文档的集合。这与关系数据库中的表(Table)类似,表也是行数据的集合;
- 映射(Mapping):映射定义了索引中文档的字段名和字段类型,类似于关系数据库中的表结构定义(Schema),定义了表中列的名称和数据类型。
- 文档(Document):文档是 Elasticsearch 中可以被索引的基本数据单位,包含了多个字段和字段的值。这与关系数据库中的行数据(Row)类似,行数据也包含了多个列和列的值。
这种类比可以帮助我们更好地理解 Elasticsearch 的数据模型,但需要注意的是,Elasticsearch 是一个分布式的全文搜索和分析引擎,它的设计和实现与关系数据库有很大的不同,所以这种类比并不完全准确。
Ps:在 Elasticsearch 早期版本中,类型(Type)可以被类比为关系数据库中的表(Table),所以索引(Index)可以被类比为关系数据库中的数据库(Database)。 然而,从 Elasticsearch 7.0 开始,类型的概念已经被逐渐废弃,一个索引下只能有一个类型,或者完全不使用类型。在这种情况下,索引(Index)更类似于关系数据库中的表(Table),映射(Mapping)类似于表结构定义,文档(Document)类似于表的行数据。
4、ElasticSearch物理结构
4.1、物理结构设计:集群
在 Elasticsearch 中,集群(Cluster)是由多个节点(Node)组成,节点共享相同的集群名称,可以协同工作以提供数据的索引和搜索功能。
Elasticsearch 集群具有以下特性:
- 数据分布:集群中的数据被分为多个分片(Shard),每个分片可以存储在集群中的任何节点上;
- 高可用性:如果集群中的某个节点失败,其他节点可以接管失败节点的工作,保证数据的可用性;
- 负载均衡:集群可以自动分配和平衡数据和查询负载,以优化性能;
- 可扩展性:可以通过添加更多的节点到集群来扩展集群的容量和性能;
- 实时性:集群可以在接收到新的数据后立即进行索引和搜索,提供近实时的搜索功能
这些特性使得 Elasticsearch 非常适合处理大量的数据,并且提供高可用性和可扩展性。
4.2、物理结构设计:节点
在 Elasticsearch 中,节点(Node)是集群中的一个单独的服务器,用于存储数据、参与集群的索引和搜索功能。
Elasticsearch 节点有以下特性:
- 数据存储:每个节点都可以存储数据,数据被分为多个分片,每个分片可以存储在不同的节点上;
- 分片分配:Elasticsearch 会自动处理分片的分配和负载均衡,当添加或移除节点时,Elasticsearch 会自动重新分配分片。
- 故障恢复:如果一个节点失败,Elasticsearch 会自动将该节点上的分片分配到其他节点上,以保证数据的可用性。
- 多种角色:节点可以有多种角色,如数据节点用于存储数据和执行数据相关的操作,主节点用于管理集群的元数据,协调节点用于路由请求和聚合结果,等等。
- 可扩展:可以通过添加节点来扩展 Elasticsearch 集群的容量和性能。
这些特性使得 Elasticsearch 能够处理大量的数据,并且提供高可用性和可扩展性。
4.3、物理结构设计:分片
分片(Shard)是 Elasticsearch 中数据的最小单位,用于将索引数据分布在集群的多个节点上。
在 Elasticsearch 中,分片(Shard)有两种类型:主分片和副本分片:
- 主分片(Primary Shard):每个索引都有一个或多个主分片。主分片的数量在创建索引时设置,之后不能更改。主分片负责索引的所有写操作(如添加、更新和删除文档),并参与读操作(如搜索和聚合);
- 副本分片(Replica Shard):副本分片是主分片的复制品。副本分片的数量可以在创建索引后随时更改。副本分片不能接收写操作,但可以参与读操作,从而提高查询性能和数据可用性。
当一个写操作发生时,首先在主分片上执行,然后将操作复制到所有的副本分片。当一个读操作发生时,Elasticsearch 会从主分片和所有可用的副本分片中选择一个来处理请求。
主分片和副本分片都可以分布在集群的任何节点上,Elasticsearch 会自动处理分片的分配和负载均衡。如果一个节点失败,Elasticsearch 会自动将该节点上的分片分配到其他节点上,以保证数据的可用性。
Ps:在 Elasticsearch 中,每个主分片都有其对应的副本分片,而不是主分片共用副本分片。 当一个索引的主分片数量设置为 2 时,Elasticsearch 会为该索引创建两个主分片,并将它们分配到不同的节点上。每个主分片都有一个对应的副本分片,副本分片会被分配到其他节点上。 这种设置可以提高数据的可用性和冗余度。当一个节点上的主分片不可用时,副本分片可以接管主分片的工作,保证数据的持久性和可用性。同时,副本分片也可以提供更好的读取性能,因为查询可以在主分片和副本分片之间并行执行。 总结来说,每个主分片都有其对应的副本分片,它们分布在不同的节点上,以提供高可用性和性能。
Ps:每个主分片都有其对应的副本分片,而不是主分片共用副本分片的原因主要有以下几点:
- 高可用性:每个主分片和其对应的副本分片分布在不同的节点上,当一个节点或主分片不可用时,副本分片可以接管主分片的工作,保证数据的可用性和持久性。如果主分片共用副本分片,当一个节点或主分片不可用时,所有的分片都会受到影响,导致数据的不可用性。
- 并行处理:每个主分片和其对应的副本分片可以并行处理读取请求,提高查询性能。如果主分片共用副本分片,所有的读取请求都会集中在同一个分片上,可能导致性能瓶颈。
- 负载均衡:每个主分片和其对应的副本分片可以分布在不同的节点上,实现数据的负载均衡。如果主分片共用副本分片,所有的数据都会集中在同一个节点上,可能导致节点的负载过重。
通过将每个主分片和其对应的副本分片分布在不同的节点上,Elasticsearch 可以提供高可用性、并行处理和负载均衡的优势,以保证数据的可用性和性能。