Elasticsearch 是一个开源的、基于 Lucene 的分布式搜索和分析引擎,设计用于云计算环境中,能够实现实时的、可扩展的搜索、分析和探索全文和结构化数据。它具有高度的可扩展性,可以在短时间内搜索和分析大量数据。 Elasticsearch 不仅仅是一个全文搜索引擎,它还提供了分布式的多用户能力,实时的分析,以及对复杂搜索语句的处理能力,使其在众多场景下,如企业搜索,日志和事件数据分析等,都有广泛的应用。 本文将对 Elasticsearch 的基本概念进行介绍,包括索引、文档、字段、映射、节点、集群和分片等,帮助读者理解和使用 Elasticsearch。
2004 年,以色列人 Shay Banon 创造了一款名为 Compass 的搜索引擎,在考虑 Compass 的第三个版本时,他意识到有必要重写 Compass 的大部分内容,以"创建一个可扩展的搜索解决方案"。因此,他创建了"一个从头构建的分布式解决方案",并使用了一个公共接口,即 Http 上的 Json,它也适用于 Java 以外的编程语言。于是 Shay Banon 在 2010 年 2 月发布了 Elasticsearch 的第一个版本。
Elasticsearch 自从诞生以来,其应用越来越广泛,特别是大数据领域,功能也越来越强大,但是如何有效的监控管理 Elasticsearch 一直是公司所面对的难题,由于 Elasticsearch 集群的稳定性,决定了其业务发展的高度,对于一个应用来说其稳定是第一目标,所以完善的监控体系是必不可少的。
ElasticSearch 是一个分布式、高扩展、高实时的搜索与数据分析引擎,基于 Apache Lucene 实现。它提供了一个分布式的多用户的全文搜索引擎。它能很方便的使大量数据具有搜索、分析和探索的能力。充分利用 Elasticsearch 的水平伸缩性,能使数据在生产环境变得更有价值
Elasticsearch 提供了一个全文搜索的功能,但它不仅仅是一个搜索引擎。它还提供了分布式的实时文档存储,每个字段可以被索引与搜索。Elasticsearch 也能进行实时的数据分析,并能在近实时的情况下返回分析结果。
Elasticsearch 是用 Java 开发的,并作为 Apache 许可条款下的开源软件发布。它的 API 使用 JSON 作为数据交换的格式,支持各种语言的官方客户端,包括:Java、.NET(C#)、PHP、Python、Apache Groovy、Ruby 和许多其他语言。
ElasticSearch 主要特点包括:
Ps:Lucene 是 Elasticsearch 所基于的 Java 库,它引入了按段搜索的概念。
Elasticsearch 是与名为 Logstash 的数据收集和日志解析引擎以及名为 Kibana 的分析和可视化平台一起开发的。这三个产品被设计成一个集成解决方案,称为 “Elastic Stack”(以前称为"ELK stack")。
以上产品同属于一家全球性的公司——Elastic,其专注于提供开源搜索和数据分析技术,Elastic 的产品广泛应用于企业搜索、日志和事件数据分析、实时应用监控、大数据分析等领域。Elastic 的使命是使搜索变得简单,帮助人们从数据中发现和理解有价值的信息。
作为搜索引擎,ElasticSearch 绝对稳坐该领域的头把交椅,其内核基于 Lucene 构建,支持全文搜索是职责所在,提供了丰富友好的 API。
但是在现在项目中,Elasticsearch 用作传统意义上全文检索的比重越来越少,多数时候是用来做精确查询加速,查询条件很多,可以任意组合,查询速度很快,替代其它很多数据库复杂条件查询的场景需求。;甚至有的数据库产品直接使用 Elasticsearch 做二级索引,如 HBase、Redis 等。因此 Elasticsearch 由于自身的一些特性,更像一个多模数据库。
图示:Elasticsearch 于 2022 年 12 月是综合数据库排名热度已经到第 7 位!
Elasticsearch 与大名鼎鼎的 MongoDB 十分相似,Elasticsearch 使用 Json 格式来承载数据模型(MongoDB 使用 Bson,类似于 Json),已经成为事实上的文档型数据库,虽然底层存储不是 Json 格式。不过二者在产品定位上有差别:
值得注意的是 Elasticsearch 不是关系型数据库,内部数据更新采用乐观锁,无严格的 ACID 事务特性,任何企图将它用在关系型数据库场景的应用都会有很多问题!
Elasticsearch 虽然是基于 Lucene 构建,但应用领域确实非常宽泛:
在 Elasticsearch 中,索引(Index)是具有类似特性的文档集合。每个索引都有一个唯一的名称来标识,这个名称必须全部是小写。当我们对文档进行索引、搜索、更新和删除操作时,都会引用到这个索引名称。
例如,我们可以创建一个名为 “customer” 的索引来存储所有的客户数据,创建一个名为 “product” 的索引来存储所有的产品数据。当我们需要搜索某个客户的信息时,就可以对 “customer” 索引进行搜索;当我们需要更新某个产品的信息时,就可以对 “product” 索引进行更新。
这种方式使得我们可以在 Elasticsearch 中组织和管理大量的数据,同时也能保证高效的搜索和查询性能
在 Elasticsearch 早期版本中,类型(Type)是索引的逻辑分类,用于将具有共同字段的文档分组在一起。每个类型都有自己的映射(Mapping),定义了类型中文档的字段名和字段类型。
然而,需要注意的是,从 Elasticsearch 7.0 开始,类型的概念已经被逐渐废弃,一个索引下只能有一个类型,或者完全不使用类型。这是因为多类型存在一些问题,如字段名冲突、内存浪费等,所以 Elasticsearch 决定逐步移除多类型的支持。在新的版本中,我们通常直接在索引级别定义映射,不再使用类型。
在 Elasticsearch 中,映射(Mapping)是定义索引中字段名和字段类型的过程,可以看作是 Elasticsearch 中的"模式定义"。映射定义了字段的名称、字段的类型(如文本、整数、日期等)、以及可能的一些额外信息(如是否该字段可以被搜索、是否存储原始值等)
Ps:Elasticsearch 允许在文档中添加映射中未定义的字段。这是因为 Elasticsearch 默认开启了动态映射(Dynamic Mapping)功能。 当 Elasticsearch 遇到映射中未定义的字段时,它会根据字段的内容自动推断字段类型,并更新映射。例如,如果一个新字段的值是一个日期字符串,Elasticsearch 会自动将这个字段映射为日期类型。 但是,也可以关闭动态映射功能,或者设置为严格模式,这样在遇到未定义的字段时,Elasticsearch 会抛出异常,而不是自动更新映射。 需要注意的是,虽然 Elasticsearch 允许动态添加字段,但是频繁修改映射会影响性能,而且一旦字段被映射为某种类型,就不能再改变类型。因此,对于重要的字段,最好在创建索引时就定义好映射。
在 Elasticsearch 中,文档(Document)是可以被索引的基本信息单位。每个文档都由一系列字段组成,每个字段都有自己的数据类型和值。文档以 JSON 格式表示,这使得 Elasticsearch 能够处理复杂、层次化的数据结构。
在 Elasticsearch 中,文档(Document)具有以下特征:
name
)和它们的取值(如 John Doe
)。这意味着文档包含了所有描述数据的信息;这些特性使得 Elasticsearch 非常适合处理半结构化的数据,如 JSON,可以灵活地应对数据结构的变化。
在 Elasticsearch 中,字段(Field)是文档的一个属性或特性,每个字段都有一个字段名和字段值。字段的数据类型可以是简单的(如文本、数字、日期等),也可以是复杂的(如对象或者数组)。
例如,一个文档可能有一个名为 title
的字段用于存储标题,一个名为 date
的字段用于存储日期,等等。
字段的定义(包括字段名和字段类型)通常在映射(Mapping)中进行。
Ps:需要注意的是,虽然 Elasticsearch 允许动态添加字段(即在文档中添加映射中未定义的字段),但是一旦字段被映射为某种类型,就不能再改变类型。因此,对于重要的字段,最好在创建索引时就定义好映射。
在关系数据库中,我们可以将 Elasticsearch 的索引(Index)类比为表(Table),将映射(Mapping)类比为表结构定义(Schema),将文档(Document)类比为表的行数据(Row)。
这种类比可以帮助我们更好地理解 Elasticsearch 的数据模型,但需要注意的是,Elasticsearch 是一个分布式的全文搜索和分析引擎,它的设计和实现与关系数据库有很大的不同,所以这种类比并不完全准确。
Ps:在 Elasticsearch 早期版本中,类型(Type)可以被类比为关系数据库中的表(Table),所以索引(Index)可以被类比为关系数据库中的数据库(Database)。 然而,从 Elasticsearch 7.0 开始,类型的概念已经被逐渐废弃,一个索引下只能有一个类型,或者完全不使用类型。在这种情况下,索引(Index)更类似于关系数据库中的表(Table),映射(Mapping)类似于表结构定义,文档(Document)类似于表的行数据。
在 Elasticsearch 中,集群(Cluster)是由多个节点(Node)组成,节点共享相同的集群名称,可以协同工作以提供数据的索引和搜索功能。
Elasticsearch 集群具有以下特性:
这些特性使得 Elasticsearch 非常适合处理大量的数据,并且提供高可用性和可扩展性。
在 Elasticsearch 中,节点(Node)是集群中的一个单独的服务器,用于存储数据、参与集群的索引和搜索功能。
Elasticsearch 节点有以下特性:
这些特性使得 Elasticsearch 能够处理大量的数据,并且提供高可用性和可扩展性。
分片(Shard)是 Elasticsearch 中数据的最小单位,用于将索引数据分布在集群的多个节点上。
在 Elasticsearch 中,分片(Shard)有两种类型:主分片和副本分片:
当一个写操作发生时,首先在主分片上执行,然后将操作复制到所有的副本分片。当一个读操作发生时,Elasticsearch 会从主分片和所有可用的副本分片中选择一个来处理请求。
主分片和副本分片都可以分布在集群的任何节点上,Elasticsearch 会自动处理分片的分配和负载均衡。如果一个节点失败,Elasticsearch 会自动将该节点上的分片分配到其他节点上,以保证数据的可用性。
Ps:在 Elasticsearch 中,每个主分片都有其对应的副本分片,而不是主分片共用副本分片。 当一个索引的主分片数量设置为 2 时,Elasticsearch 会为该索引创建两个主分片,并将它们分配到不同的节点上。每个主分片都有一个对应的副本分片,副本分片会被分配到其他节点上。 这种设置可以提高数据的可用性和冗余度。当一个节点上的主分片不可用时,副本分片可以接管主分片的工作,保证数据的持久性和可用性。同时,副本分片也可以提供更好的读取性能,因为查询可以在主分片和副本分片之间并行执行。 总结来说,每个主分片都有其对应的副本分片,它们分布在不同的节点上,以提供高可用性和性能。
Ps:每个主分片都有其对应的副本分片,而不是主分片共用副本分片的原因主要有以下几点:
通过将每个主分片和其对应的副本分片分布在不同的节点上,Elasticsearch 可以提供高可用性、并行处理和负载均衡的优势,以保证数据的可用性和性能。