上一章节我们已经安装和启动了 Elasticsearch,本章节我本来就此开始讲解如何使用的。但后面转念一想,为了方便大家理解,我们拿 RDBMS (数据库) 常见的一些概念事先解释接下来会碰到的一些术语

Elasticsearch vs RDBMS

Elasticsearch 中,索引是一个集合,相当于数据库 ( RDBMS , 关系数据库管理系统 ) 中的数据库

集合中的每个映射,相当于 RDBMS 中的表

而索引中的每个 JSON 对象,又相当于 RDBMS 中的数据行

所以,Elasticsearch,集合是一些包含了 JSON 对象的映射的集合

详细的对比如下

Elasticsearch RDBMS
Index Database
Shard Shard
Mapping Table
Field Field
JSON Object Tuple

几个重要的概念

集群

集群中的一个节点就是一个 Elasticsearch 进程,多个节点组成一个集群

一般每个节点都运行在不同的操作系统上,配置好集群相关参数后 Elasticsearch 会自动组成集群 ( 节点发现方式也可以配置 )

集群内部通过 Elasticsearch 的选主算法选出主节点,而集群外部则是可以通过任何节点进行操作,无主从节点之分 ( 对外表现对等/去中心化,有利于客户端编程,例如故障重连 )

索引

「索引 」 有两个意思:

1、 作为动词,它指的是把一个文档「保存」到Elasticsearch中的过程,索引一个文档后,我们就可以使用Elasticsearch搜索到这个文档;
2、 作为名词,它是指保存文档的地方,相当于一个数据库概念中的「库」;

为了方便理解,我们可以将 Elasticsearch 中的一些概念对应到我们熟悉的关系型数据库上

Elasticsearch 索引 类型 文档
DB

分片

Elasticsearch 是一个分布式系统,我们一开始就应该以集群的方式来使用它。

Elasticsearch 在保存索引时会选择适合的 「 主分片 」 ( Primary Shard ),把索引保存到其中

我们可以把分片理解为一块物理存储区域

分片的分法是固定的,而且是安装时候就必须要决定好的 ( 默认是 5 ),后面就不能改变了

既然有主分片,那肯定是有 「 从 」 分片的,但 Elasticsearch 里称之为 「 副本分片 」 ( Replica Shard )

副本分片主要有两个作用:

1、 高可用

某分片节点挂了的话可走其他副本分片节点,节点恢复后上面的分片数据可通过其他节点恢复

2、 负载均衡

Elasticsearch 会自动根据负载情况控制搜索路由,副本分片可以将负载均摊

范例

我们举一个简单的例子来总结上面阐述的内容

 

该图是使用 Elasticsearch 的 RESTful 接口获取的,后面会介绍常用接口

上图中:

1、 3个Elasticsearch节点(es-58/59/60)组成一个集群;
2、 搭建集群时使用默认的主分片数5,shard0~shard4;
3、 该集群内有加入两个索引index1、index2;
4、 这两个索引中分别「索引」(保存)了两个文档;
5、 index1索引中这个文档被Elasticsearch自动保存到了分片2中,主分片在es-58节点,副本分片在es-59节点;
6、 index2索引中这个文档被Elasticsearch自动保存到了分片2中,主分片在es-59节点,副本分片在es-58节点;

多租户

Elasticsearch 中的多租户简单的说就是通过多索引机制同时提供给多种业务使用,每种业务使用一个索引 ( 关于多租户的详细定义与用途,可以参考这里 )

前面我们提到过可以把索引理解为关系型数据库里的库,那多索引可以理解为一个数据库系统建立多个库给不同的业务使用

实际使用时,我们可以通过每个租户一个索引的方式将他们的数据进行隔离,并且每个索引是可以单独配置参数的 ( 可对特定租户进行调优 )

这在典型的多租户场景下非常有用:例如我们的一个多租户应用需要提供搜索支持,这时可以通过 Elasticsearch 根据租户建立索引,这样每个租户就可以在自己的索引下搜索相关内容了

RESTful

因为RESTful,所以 Elasticsearch 接口非常清晰方便简单。

最关键的是 Elasticsearch 的 HTTP 接口不只是可以进行业务操作 ( 索引/搜索 ) ,还可以进行配置,甚至是关闭 Elasticsearch 集群

下面我们介绍几个很常用的接口

接口 说明
/_cat/nodes?v 查集群状态
/_cat/shards?v 查看分片状态
/ `$` 搜索

1、 v是verbose的意思,当使用这个参数,那么返回结果则更具可读性(有表头,有对齐);
2、 _cat是监测相关的APIs可以使用/_cat?help来获取所有接口;
3、 $ {index}和 $ {type}分别是具体的某一索引某一类型,是分层次的;

术语

接下里的教程为涉及到很多术语,这些术语可能比较难懂,不过没关系,你不懂也可以继续,当不懂某个术语的时候,回来这篇文章看看就知道了

analysis 分析

分析是将文本 ( text ) 转化为查询词 ( term ) 的过程

比如这三种短语:FOO BAR,Foo-Bar,foo,bar 都有可能被分解成查询词 foo 与 bar

可以使用不同的分析器,这些查询词实际上将被存储在索引中

一次对FoO:bAR 的全文查询 ( 不是查询词查询 ) 可能会被分析为为查询词 foo,bar,可以匹配上保存在索引中的查询词

这就是分析处理过程(包含了索引与搜索),它使得 es 可以进行全文查询

cluster ( 集群 )

一个或多个拥有同一个集群名称的节点组成了一个集群

每个集群都会自动选出一个主节点,如果该主节点故障,则集群会自动选出新的主节点来替换故障节点

document ( 文档 )

一个文档就是一个保存在 Elasticsearch 中的 JSON 文本,可以把它理解为关系型数据库表中的一行

每个文档都是保存在索引中的,拥有一种类型和 id

一个文档是一个 JSON 对象 ( 一些语言中的 hash / hashmap / associative array ) 包含了 0 或多个字段 ( 键值对 )

原始的JSON 文本在索引后将被保存在 _source 字段里,搜索完成后返回值中默认是包含该字段的

id

Id是用于标识文档的,一个文档的索引/类型/id 必须是唯一的

文档id 是自动生成的,如果显式不指定

field ( 字段 )

一个文档包含了若干字段,或称之为键值对

字段的值可以是简单标量值,例如字符串、整型、日期,也可以是嵌套结构,例如数组或对象

一个字段类似于关系型数据库表中的一列

每个字段的映射都有一个字段类型 ( 不要和文档类型搞混了 ),它描述了这个字段可以保存的值类型,例如整型、字符串、对象

映射还可以让我们定义一个字段的值如何进行分析

index ( 索引 )

一个索引类似关系型数据库中的一个数据库,它可以映射为多种类型

一个索引就是逻辑上的一个命名空间,对应到 1 或多个主分片上,可以拥有 0 个或多个副本分片

mapping ( 映射 )

一个映射类似于关系型数据库中的表

每个索引都存在一个映射,它定义了该索引中的每一种类型,以及索引相关的配置

映射可以显示定义,或者在文档被索引时自动创建

node ( 节点 )

一个节点是集群中的一个 Elasticsearch 运行实例

测试环境,多个节点可以同时启在同一个服务器上,生产环境一般是一个服务器上一个节点

节点启动时将使用单播或者是组播来发现和自己配置的集群名称相同的集群,并尝试加入到该集群中

shard ( 分片 )

一个分片就是一个 Lucene 实例,它是 Elasticsearch 管理的底层 「 工作单元 」

一个索引是逻辑上的一个命名空间,指向主分片和副本分片

索引的主分片和副本分片数量必须明确指定好,在应用代码使用时只需要处理和索引的交互,不会涉及到和分片的交互

Elasticsearch 会在集群中的所有节点上设置好分片,但节点失效或加入新节点时会自动将移动节点分片

primary shard ( 主分片 )

每个文档都会被保存在一个主分片上

当我们索引一个文档时,它将在一个主分片上进行索引,然后才放到该主分片的各副本分片上

默认情况下,一个索引有 5 个主分片

我们可以指定更少或更多的主分片来伸缩索引可处理的文档数

需要注意的是,一旦索引创建,就不能修改主分片个数

replica shard ( 副本分片 )

每个主分片可以拥有 0 个或多个副本分片,一个副本分片是主分片的一份拷贝

这样做有两个主要原因:

1、 故障转移

当主分片失效时,一个副本分片会被提升为主分片

2、 提高性能

获取与搜索请求可以被主分片或副本分片处理

默认情况下,每个主分片都有一个副本分片,副本分片的数量可以动态调整

在同一个节点上,副本分片和其主分片不会同时运行

routing ( 路由 )

当我们索引一个文档时,它将被保存在一个主分片上,分片的选择是通过路由值哈希得到的

默认情况下,路由值使用文档的 id,如果该文档指定来了父文档,则路由值使用父文档 id

这是为了确保子文档和父文档被保存在相同的分片上

该值可以在索引时指定,也可以通过映射路由字段来指定

source field ( 源字段 )

默认情况下,在获取和搜索请求返回值中的 _source 字段保存了源 JSON 文本

这使得我们可以直接在返回结果中访问源数据,而不需要根据 id 再发一次检索请求

索引的 JSON 字符串将完整返回,无论是否是一个合法的 JSON

该字段的内容也不会描述数据如何被索引

term ( 查询词 )

一个查询词是一个被 Elasticsearch 索引的确切值

查询词foo,Foo,FOO 是不同的

查询词可以使用查询词查询接口进行获取

text ( 文本 )

文本( 或称之为全文 ) 是普通的、非结构化的文本,例如一句话。

默认情况下,文本将被分解为查询词,查询词将被保存在索引中

为能够进行全文搜索,文本字段在索引时将被分解为查询词,查询关键字在搜索时也将被分解为查询词,通过对比查询词是否相同而完成全文搜索

type ( 类型 )

一种类似于关系型数据库中的一张表的类型

每种类型都有若干字段,用于指定给该类型文档

映射定义了该文档中的每个字段如何进行分析