乐趣区

ElasticSearch10大核心概念

前言

在学习一门技术时,我们首先想到的资料肯定是官方文档,这是最权威的第一手资料。然而,有些官方文档中出现的概念,如果没有一定知识储备,看起来会显得晦涩难懂。就比如在 ES 中,有几个核心概念我们必须要理解,这些在官方文档中往往作为术语来使用,只有理解了这些概念才能更深入的学习 ES。下面是我在学习 ES 过程中,对 ES 核心概念的总结,结合了官方文档和自己的理解,如果发现描述有错误,请大家在评论区留言,多多交流!

字段 Field

字段在 ES 中可以理解为 JSON 数据的键,下面的 JSON 数据中,name 就是一个字段。

{"name":"jack"}

文档 Document

文档 在 ES 中相当于传统数据库中的的概念,ES 中的数据都以 JSON 的形式来表示,在 MySQL 中插入一行数据和 ES 中插入一个 JSON 文档是一个意思。下面的 JSON 数据表示,一个包含 3 个字段的 文档

{
    "name":"jack",
    "age":18,
    "gender":1
}

映射 Mapping

映射 是对 文档 中每个 字段 的类型进行定义,每一种数据类型都有对应的使用场景。例如:string的数据会被作为全文本来处理,这种数据类型适合需要搜索的场景。有些数据类型,你不需要对它进行搜索,相反需要对它做聚合运算,那么 keywordinteger 数据类型就更合适。
正如上面说的,每个 文档 都有映射,但是在大多数使用场景中,我们并不需要显示的创建映射,因为 ES 中实现了动态映射。我们在索引中写入一个下面的 JSON 文档,在动态映射的作用下,name会映射成 text 类型,age会映射成 long 类型。

{
    "name":"jack",
    "age":18,
}

既然有动态映射,我们当然也可以自定义映射,在深度使用中,我们需要对数据类型进行精确的控制,以达到我们实际场景的要求,ES 可能不知道我们需要数据类型,这种情况下我们可以使用自定义映射。通过映射 API,我们可以方便的 创建 修改 查看 删除 映射。

索引 Index

索引 是 ES 中最大的数据单元,相当于关系型数据库中 的概念。前面我们说一个 文档 相当于 MySQL 中一行数据,如果按照关系型数据库中的对应关系,还应该有的概念。ES 中没有 的概念,这是 ES 和数据库的一个区别,在我们建立 索引 之后,可以直接往 索引 中写入 文档 。在 6.0 版本之前,ES 中有Type 的概念,可以理解成关系型数据库中的 ,但是官方说这是一个设计上的失误,所以在 6.0 版本之后 Type 就被废弃了。

分片 Shards

上面我们说 索引 是 ES 中最大的数据存储单元,我们可以往 索引 中不断写入 文档 ,到了一定数量级,索引文件就会占满整个服务器的磁盘,磁盘容量只是其中一个问题,索引文件变的大,会严重降低搜索的效率。怎么解决这个问题呢?分片就是用来解决这些问题的,简单来讲,分片就是把单索引文件分成多份存储,且这些索引的分片可以分部在不同的机器上。假设单台机器磁盘容量 1TB,现在需要存放 5TB 的索引数据,那就可以把 5TB 索引分成 10 份,分别存放到 10 台机器上每份 500G,这就是所谓的 分片

副本 Replicas

我们已经知道,一个索引可以分成多个分片,分部在不同的机器上。那假设上面所说的 10 台机器中有一台发生故障了,在这台机器上的分片也就没了,就会导致索引损坏。为了解决索引高可用的问题,ES 引入了 副本 机制,这里的副本指的就是分片的副本,分片的原始数据称为 主分片,主分片和副本会放在不同的机器上,这样假设有一个分配丢失了,另外的分片可以作为后备。如果主分片的机器挂掉了,其中一个副本分片就会升级成主分片。同时,因为副本分片的工作和主分片是一样的,所以增加副本的数量可以提升查询性能。

词项 term

在传统关系型数据库中,假如想要存储一篇几千字的文本,可以通过 text 直接存进去,和存储其它类型的数据没什么不同。存储虽然很方便,但是要对文本中的关键词进行搜索,查询速度非常慢,尤其是在大数据量的时候。还是上面的场景,在 ES 中存储这篇文章,它不会直接存进去,而是先把大文本切割成很多个小的词,这些词就是我们所说的 词项 ,它是 ES 搜索的最小单位,每个查询都是按 词项 搜索的。ES 使用了 倒排索引 来存储数据,什么是倒排索引?在关系型数据中,最好的方式是用主键 id 来查询,可以快速定位到文章内容,而 倒排索引 则相反,它建立的是 词项 和文章 id 的对应关系,索引它更适合文本搜索,下面是一个倒排索引,hello 和 world 这两个词都命中了 id= 1 的文章。

词项 term 文章 id
hello 1
world 1

倒排索引底层原理决定了 ES 天生适合做全文本搜索。

分析器 Analyzers

前面说过,ES 中不会把一篇文章直接存入磁盘,在存储时它会先对文本进行分析,分析器的就是用来分析这些文本,中间包括过滤、分词等过程,经过分析处理后再存储到磁盘。分析器由 3 部分组成,分别是 字符过滤器 分词器 词项处理器 。字符过滤器把原始文本作为字符流来处理,它可以过滤一些特殊字符、html 标签等; 分词器 是分析器的核心部分,它负责把大文本分割成多个 词项 ,比如文本 "Quick brown fox!",可以被分割成 3 个词项,[Quick, brown, fox!] 词项处理器 接受词项流,它可以移除一些不需要的词。ES 提供了多种分析器,默认使用标准的分析器,能满足大部分的需求,实在不行也可以使用自定义的 分析器,除了分析器以外,分词器、字符过滤器等在 ES 中也提供了多种选择。

节点 Node & 集群 Cluster

简单来讲,节点 就是一个 ElasticSearch 进程,当我们启动一个 ElasticSearch 程序,就启动了一个 节点 ,很多个 节点 集合在一起就成了 集群 ,即使只有单个节点,也可以把它看成只有单个节点的 集群 。节点也分多种类型,主要分为 主节点 数据节点 协调节点 Ingest 节点,每个节点都有各自的职责,如果集群中只有单个节点,那这个节点会扮演多个节点的角色,它需要独自完成整个搜索和索引的过程。集群对外提供服务时,相当于一个整体,集群中的每个节点都可以处理 Http 请求,每个请求经过一系列内部转发,处理完成后返回数据给外部客户端。集群内部每个节点之间通信使用 Java API,它的底层是基于 TCP 的自定义协议,而对于外部客户端,ES 使用的是 Restful 风格的 Http 协议。

总结

说了这么多核心概念,可能一下子不好理解,下图是我画的 ElasticSearch 的整体架构图。集群中有 4 个节点,其中 2 个为数据节点,专门用来存放数据和建立索引,索引 P 由 2 个分片组成,分片 P1 和 P2 的主分片分别存放在 数据节点 -2 数据节点 -1中,P1 和 P2 各有 1 个副本分片,存放在另一台数据节点中,这样可以保证的即使 数据节点 -1挂掉了,数据节点 -2仍然有完整的数据,P2 的副本分片将升级为主分片;主节点负责一些轻量级的操作,用于分片分配等;协调节点只能用于请求的路由,相当于负载均衡器。每个节点之间通过点对点的方式进行 TCP 通信,请求不需要经过主节点。
最后,希望本篇文章能帮助你理解 ES 的核心概念!

退出移动版