本章节主要是对 Elasticsearch 的入门讲解篇,包括 Elasticsearch 是做什么的,有什么特点,优秀使用案例,还有和 Mysql 等关系型数据库的对比等进行了一定的讲解。

本文以 Elasticsearch 6.4.0 的角度来讲解其基本概念。

一、简介

Lucene:简单来说,就是一个 jar 包,里面包含了封装好的各种建立倒排索引,以及进行搜索的代码,包含各种算法,我们用java开发的时候,引入 lucene.jar 就可以进行开发了。

ElasticSearch 是一个基于 Lucene 的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于 RESTful web 接口。ElasticSearch 是用 Java 开发的,并作为 Apache 许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到近实时搜索,稳定,可靠,快速,安装使用方便。

Elasticsearch 有如下几个特点:

  • 分布式存储,每个字段都被索引并可被搜索
  • 分布式的近实时分析搜索引擎
  • 可以扩展到上百台服务器,处理 PB 级结构化或非结构化数据

二、ES国内外使用优秀案例

1) 2013 年初,GitHub 抛弃了 Solr,采取 ElasticSearch 来做 PB 级的搜索。 “GitHub 使用 ElasticSearch 搜索 20TB 的数据,包括 13 亿文件和 1300 亿行代码”。

2)维基百科:启动以 Elasticsearch 为基础的核心搜索架构。

3)SoundCloud:“SoundCloud 使用 ElasticSearch 为 1.8 亿用户提供即时而精准的音乐搜索服务”。

4)百度:百度目前广泛使用 ElasticSearch 作为文本数据分析,采集百度所有服务器上的各类指标数据及用户自定义数据,通过对各种数据进行多维分析展示,辅助定位分析实例异常或业务层面异常。目前覆盖百度内部 20 多个业务线(包括 casio 、云分析、网盟、预测、文库、直达号、钱包、风控等),单集群最大 100 台机器,200 个 Elasticsearch 节点,每天导入 30 TB+数据。

5) 淘宝等电商网站,新闻网站,OA 办公系统等。

三、基本概念

参考官方文档:https://www.elastic.co/guide/en/elasticsearch/reference/6.4/getting-started-concepts.html

1. 节点(Node) 和 集群(Cluster)

集群是一个或多个 Elasticsearch 节点(服务器)的集合, 这些节点共同保存整个数据,并在所有节点上提供联合索引和搜索功能。一个集群由一个唯一集群 ID 确定,并指定一个集群名(默认为 “elasticsearch” )。该集群名非常重要,因为节点可以通过这个集群名加入集群,一个节点是集群的一部分。

2. Index(索引)

索引是具有相似特征的文档的集合。例如,您可以为客户数据创建索引,为产品目录创建另一个索引,为订单数据创建另一个索引。索引由名称标识(必须全为小写,不能以下划线开头,不能包含逗号)。

在一个 Elasticsearch 集群中,您可以定义任意数量的索引。

3. Type(类型)

在 Elasticsearch 6.0.0 或更高版本中创建的索引只能包含一个映射类型。类型将在 Elasticsearch 7.0.0 中的 API 中弃用,并在 8.0.0 中完全删除。

详情可参考:https://www.elastic.co/guide/en/elasticsearch/reference/6.4/removal-of-types.html#_why_are_mapping_types_being_removed

4. Document(文档)

文件是可以建立索引的基本信息单位,以 json 表示。你可以用其来定义单个产品信息或是员工信息。我们可以把文档理解为 Mysql 表中的行级数据。在 Index(索引) 中,您可以存储大量文档。文档中有几个公共不可或缺的属性,分别为 _index、_type、_id、_source。

  • _index:表示所在的 index 名。
  • _type:在 6.x 版本只能指定一个类型,在 6.4.0 版本中默认为 “doc”。
  • _id:文档的唯一标识,类似于 Mysql 数据库的主键 id 。
  • _source:文档数据以 json 的形式保存在该字段内。

针对特定一个或一类文档进行操作时,必须指定这些属性。

5. Mapping(映射)

模式映射(schema mapping,或简称为映射)用于定义 Index(索引) 的元数据,指定要索引并存储文档的字段类型。Elasticsearch 在 Mapping 中存储有关字段的信息。Mapping 在文件中以 json 表示。

6. Field(字段)

Elasticsearch 里最小单元,相当于 Mysql 表的某个字段,类似于 json 里一个键。

7、Shards(分片)

索引可能会存储大量数据,这些数据可能超过单个节点的硬件限制。例如,十亿个文档的单个索引占用了 1 TB的磁盘空间,可能不适合单个节点的磁盘,或者可能太慢而无法单独满足来自单个节点的搜索请求。

为了解决此问题,Elasticsearch 提供了 Shards(分片) 的概念。每个 Shards(分片) 本身就是一个功能齐全且独立的 Lucene “索引”,可以存储在 Elasticsearch 集群中的任何节点上,这就是分布式存储。

分片的好处?

  • 当你查询的索引分布在多个分片上时,Elasticsearch 会把查询发送给每个相关的分片,并将结果合并在一起。所以,多个分片可以加快查询,提高吞吐量。
  • 通过将分片放在不同节点,可以存储超过单节点容量的数据。
8、Replica(副本)

当集群某节点宕机了,为了防只数据丢失,Elasticsearch 还提供了 Replica(副本) 概念。副本分片(Replica Shards)是一个分片的精确复制,每个分片可以有零个或多个副本。换句话说,Elasticsearch 可以有许多相同的分片,其中之一被自动选择去更改索引操作,这种特殊的分片称为主分片(primary shards),其余称为副本分片(replica shards)。在主分片丢失时,例如该分片数据所在服务器不可用,集群则将副本分片提升为新的主分片。

Replica(副本)的好处:

  • 提供高可用性。当主分片节点故障时,可升级一个副本分片为新的主分片来应对节点故障。需要特别说明的是:副本分片(Replica Shards) 永远不会与 主分片(primary Shards) 分配在同一节点上。
  • 由于每个 Shards(分片) 本身就是一个功能齐全且独立的 Lucene “索引”,所以也可以在所有的副本分片(Replica Shards)上并行执行搜索,从而加快 Elasticsearch 查询,提高吞吐量。
  • 增加副本分片,可以将数据存储到更多节点上,更好地处理并发请求。

可以在创建 索引(Index) 时定义 主分片(Primary Shards)副本分片(Replica Shards) 的数量。创建索引后,您还可以动态更改副本数,但要更改分片数就不那么轻松了。因此,预先规划正确的分片数量是最佳方法。

默认情况下,Elasticsearch 中的每个索引分配有 5 个主分片和 1 个副本分片,这意味着如果集群中至少有两个节点,则索引将具有 5 个主分片和另外 5 个副本分片(1个完整副本),总计每个索引 10 个分片。

四、关系型数据库和ElasticSearch中的对应关系

在 6.4.x 的官方文档中表示,“ 索引 ”类似于SQL数据库中的“ 数据库 ”,而“ 类型 ”等同于 “ 表 ”,这是一个不好的类比。但为了方便理解,其它概念还是有一些对应关系的。如下表所示:

关系型数据库 Elasticsearch
数据行 Row 文档 Document,但不需要固定结构,不同文档可以具有不同字段集合
模式 Schema 映射 Mapping
数据列 Column 字段 Field