ElasticSearch—10大核心概念

前言

在学习一门技术时,我们首先想到的资料肯定是官方文档,这是最权威的第一手资料。然而,有些官方文档中出现的概念,如果没有一定知识储备,看起来会显得晦涩难懂。就比如在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
hello1
world1

倒排索引底层原理决定了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的核心概念!
ElasticSearch—10大核心概念