Elasticsearch 不完全入门指北系列(二):概念介绍与 DSL

719 阅读7分钟

这是我参与更文挑战的第10天,活动详情查看:更文挑战

本篇会主要介绍一些关于 Elasticsearch 的基本概念以及 DSL 是什么。

1. 基本概念

1.1 近实时

Elasticsearch 是一个能提供近实时查询的搜索服务引擎,这意味着从索引文档到真正可搜索之间会有一个轻微的延迟(大概在一秒内)。后面的系列文章我们会谈到关于 ES 的数据搜索(或者叫读取)原理以及持久化原理,均与内存的刷新写入有关,这里我们只需要先知道大概会有一秒的延迟,并且在代理可以实现强制刷新就可以了。

1.2 分词与倒排索引

要解释倒排索引呢,就需要先了解一下分词。分词 顾名思义,作为一个动词,就是分解成词语,根据不同的规则,分词的结果也不尽相同。比如我们经常使用的中文分词插件 ik 分词:

ik_max_word: 会将文本做最细粒度的拆分,比如会将“中华人民共和国国歌”拆分为“中华人民共和国,中华人民,中华,华人,人民共和国,人民,人,民,共和国,共和,和,国国,国歌”,会穷尽各种可能的组合,适合 Term Query;

ik_smart: 会做最粗粒度的拆分,比如会将“中华人民共和国国歌”拆分为“中华人民共和国,国歌”,适合 Phrase 查询。

可见,根据查询的目标不同,我们也需要来调整不同的分词模式。分词大概就是这样。

倒排索引:比如我们要根据一些关键词来检索一些文章,首先我们会对所有的文章进行编码,也可以说是标记页码,倒排索引相当于创建了关键词(分词结果)目录,记录了哪个单词被哪些文章包含,如下:

关键词页码
运动1,2,3,5,7,8
活动3,4
生命1,2
chenqionghe8

当我们要搜索找到有“运动”的文章时,先去关键词目录找,找到在1,2,3,5,7,8这几页,然后直接把书翻到这些页就能获取到相应的内容了。如果我们要搜索“运动生命”,得先把这个分成“运动”和“生命”,再分别去目录找(因此怎么分词,也是搜索引擎中的一大艺术)。

倒排索引的原理其实就这么简单(其实没这么简单,可以先这么理解)。

1.3 文档(document)、索引(index)与类型(type)

文档(document) :Elasticsearch是面向文档(document oriented)的,这意味着它可以存储整个对象或文档(document)。然而它不仅仅是存储,还会索引(index)每个文档的内容使之可以被搜索。在Elasticsearch中,你可以对文档(而非成行成列的数据)进行索引、搜索、排序、过滤。 Elasticsearch 使用 Javascript 对象符号(JavaScript Object Notation),也就是JSON,作为文档序列化格式。通常,我们可以认为对象(object)和文档(document)是等价相通的。不过,他们还是有所差别: 对象(Object)是一个JSON结构体——类似于哈希、hashmap、字典或者关联数组;对象(Object)中还可能包含其他对象(Object)。 在Elasticsearch中,文档(document)这个术语有着特殊含义。它特指最顶层结构或者根对象(root object)序列化成的JSON数据(以唯一ID标识并存储于Elasticsearch中)。

索引:在 Elasticsearch 中存储数据的行为就叫做索引(indexing)。在 Elasticsearch 中,文档归属于一种类型 (type),而这些类型存在于索引(index)中,我们可以画一些简单的对比图来类比传统关系型数据库:

Relational DB -> Databases -> Tables -> Rows -> Columns
Elasticsearch -> Indices   -> Types  -> Documents -> Fields

Elasticsearch集群可以包含多个索引(indices)(数据库),每一个索引可以包含多个类型(types)(表),每一个类型包含多个文档(documents)(行),然后每个文档包含多个字段(Fields)(列)。

「索引」含义的区分

你可能已经注意到索引(index)这个词在Elasticsearch中有着不同的含义,所以有必要在此做一下区分:

  • 索引(名词) 如上文所述,一个索引(index)就像是传统关系数据库中的数据库,它是相关文档存储的地方,index的复数是indices 或indexes。
  • 索引(动词) 「索引一个文档」表示把一个文档存储到索引(名词)里,以便它可以被检索或者查询。这很像SQL中的INSERT关键字,差别是,如果文档已经存在,新的文档将覆盖旧的文档。
  • 倒排索引 传统数据库为特定列增加一个索引,例如B-Tree索引来加速检索。Elasticsearch和Lucene使用一种叫做倒排索引(inverted index)的数据结构来达到相同目的。

类型:6.0 之前的版本用来区分同一索引下的不同类型。在 6.0 的时候,已经默认只能支持一个索引一个 type 了,7.0 版本新增了一个参数 include_type_name ,即让所有的 API 是 type 相关的,这个参数在 7.0 默认是 true,不过在 8.0 的时候,会默认改成 false,也就是不包含 type 信息了,这个是 type 用于移除的一个开关。也就是说,对比图最后会更新成如下:

Relational DB -> Databases -> Tables -> Rows -> Columns
Elasticsearch ->  <无对应>  -> Indices  -> Documents -> Fields

1.4 节点和集群

节点(node)是一个运行着的 Elasticsearch 实例,你可以认为是单个服务器。集群(cluster)是一个或多个节点的集合,他们协同工作,共享数据并提供故障转移和扩展功能。实现整个 Elasticsearch 服务的高可用。

1.5 分片(shards)

理论上,索引可以存储尽可能多的数据,但是这种情况下性能往往不太乐观,或者常见的磁盘容量限制也不能允许。所以 Elasticsearch 提供了类似于 MongoDB 中的分片功能,该功能能将索引细分为多个分片。每个分片本身是一个功能完全和独立的“索引”,可以托管在集群中的任何节点上。

同样的,有分片技术来处理数据量增长快速的问题,就意味着需要复制技术来应对这种过程中(其实不只是该过程,任何情况下都应该有安全意识)数据安全的问题。Elasticsearch 允许您将索引分片的一个或多个副本转换为所谓的副本分片。复制技术为我们提供了数据的高可用性和搜索吞吐的扩展性。不过需要注意的是,副本分片从不分配在与从其复制的原始/主分片相同的节点上。

总而言之,每个索引可以拆分为多个分片。索引也可以复制为零(意味着没有副本)或更多次。一旦复制,每个索引将具有主分片(从索引复制的原始分片)和副本分片(主分片的副本)。开发者可以在创建索引时就为每个索引定义分片和副本的数量。创建索引后,可以随时动态更改副本数,但不能在此过程后随即更改分片数。

2. DSL 是什么?

领域特定语言(英语:domain-specific language、DSL)指的是专注于某个应用程序领域的计算机语言。又译作领域专用语言。而这里我们说到的便是关于 Elasticsearch 的专用语言。这些专用语言一般会用于直接访问 ES 而非通过比如 Java 客户端这种调用接口的方式来操作 ES 数据。DSL 并不是本系列的重点,这里我们就先不做更多描述和介绍了,大家可以参照 Quick Start 文档来做一些练习。

总结

本篇我们简单介绍了一些关于 Elasticsearch 的基本概念和 DSL 语言是什么。下一篇我们会开始搭建项目并逐渐介绍 Elasticsearch 的一些底层原理。

链接