ES

初识ElastricSearch

2021-03-20  本文已影响0人  阿Q说代码

不知道大家在项目中是否使用过ElastricSearch?大家对它的了解又有多少呢?官网的定义:Elasticsearch是一个分布式、可扩展、近实时的搜索与数据分析引擎。今天我们就来揭开一下它的神秘面纱(以下简称ES)。

ES 是使用 Java 编写的一种开源搜索引擎,它在内部使用 Lucene 做索引与搜索,通过对 Lucene 的封装,隐藏了 Lucene 的复杂性,取而代之的提供一套简单一致的 RESTful API。然而,ES不仅仅是 Lucene,并且也不仅仅只是一个全文搜索引擎,它还有如下特点:

一、结构化数据、非结构化数据

首先我们将数据大体分为两类,一类是结构化数据:也称作行数据,指具有固定格式或有限长度的数据,是由二维表结构来逻辑表达和实现的数据,严格地遵循数据格式与长度规范,主要通过关系型数据库进行存储和管理,如数据库、元数据等;一类是非结构化数据:又可称为全文数据,不定长或无固定格式,不适于由数据库二维表来表现,包括所有格式的办公文档、XML、HTML、Word 文档,邮件,各类报表、图片和音频、视频信息等。

如果要更细致的区分的话,XML、HTML 可划分为半结构化数据。因为它们也具有自己特定的标签格式,所以既可以根据需要按结构化数据来处理,也可抽取出纯文本按非结构化数据来处理。

根据两种数据分类,搜索也相应的分为两种:

(1)结构化数据搜索:因为它们具有特定的结构,所以我们一般都是可以通过关系型数据库(MySQL,Oracle 等)的二维表(Table)的方式存储和搜索,也可以建立索引。

(2)非结构化数据搜索:即对全文数据的搜索,主要有两种方法:顺序扫描、全文搜索;

二、Lucene

Lucene是apache软件基金会4 jakarta项目组的一个子项目,是一个开放源代码的全文检索引擎工具包,但它不是一个完整的全文检索引擎,而是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎,部分文本分析引擎(英文与德文两种西方语言)。Lucene的目的是为软件开发人员提供一个简单易用的工具包,以方便的在目标系统中实现全文检索的功能,或者是以此为基础建立起完整的全文检索引擎。Lucene是一套用于全文检索和搜寻的开源程式库,由Apache软件基金会支持和提供。

我所熟知的以 Lucene 为基础建立的开源可用全文搜索引擎主要有 Solr 和 ES:ES 本身就具有分布式的特性和易安装使用的特点,而 Solr 的分布式需要借助第三方来实现,例如通过使用 ZooKeeper 来达到分布式协调管理。

接下来我们说一下Lucene能实现全文搜索的一个重要的查询结构:倒排索引

举例

通过分词器将每个文档的内容域拆分成单独的词(我们称它为词条或 Term),创建一个包含所有不重复词条的排序列表,然后列出每个词条出现在哪个文档。
结果

1.jpg

这种结构由文档中所有不重复词的列表构成,对于其中每个词都有一个文档列表与之关联。这种由属性值来确定记录的位置的结构就是倒排索引。带有倒排索引的文件我们称为倒排文件。

将上面的内容转换为图的形式来说明倒排索引的结构信息


2.jpg

概念如下:

词典和倒排表是 Lucene 中很重要的两种数据结构,是实现快速检索的重要基石。词典和倒排文件是分两部分存储的,词典在内存中而倒排文件存储在磁盘上。

三、ES中的概念解释

为了大家更好的理解ES,下面介绍一下ES中的概念:

(1)Near Realtime(NRT):近实时,一是从写入数据到数据可以被搜索到有一个小延迟(默认1秒);二是基于ES执行搜索和分析可以达到秒级;

(2)Cluster(集群):ES 集群由一个或多个 ES 节点组成,每个节点配置相同的 cluster.name (默认值为 “elasticsearch”)即可加入集群。确保不同的环境中使用不同的集群名称,否则最终会导致节点加入错误的集群。ES 的集群搭建很简单,不需要依赖第三方协调管理组件,自身内部就实现了集群的管理功能。

(3)Node:一个 ES 服务启动实例就是一个节点(Node)。节点通过 node.name 来设置节点名称,如果不设置则在启动时给节点分配一个随机通用唯一标识符作为名称(默认是随机分配的)。默认节点会去加入一个名称为“elasticsearch”的集群。如果直接启动一堆节点,那么它们会自动组成一个elasticsearch集群,当然一个节点也可以组成一个elasticsearch集群。

(4)Index(索引):简单理解就是一个数据库,索引有名称,包含一堆有相似结构的文档数据,一个index包含很多document,一个index就代表了一类类似的或者相同的document。比如说建立一个product index,商品索引,里面可能就存放了所有的商品数据,所有的商品document。索引是保存相关数据的地方。 索引实际上是指向一个或者多个物理 分片 的 逻辑命名空间 。

(5)Type(类型):简单理解就是一张表,每个索引里都可以有一个或多个type,type是index中的一个逻辑数据分类,一个type下的document,都有相同的field,比如博客系统,有一个索引,可以定义用户数据type,博客数据type,评论数据type。

(6)Document(文档)&field(字段):Document就是一行数据,es中的最小数据单元,一个document可以是一条客户数据,一条商品分类数据,通常用JSON数据结构表示,每个index下的type中,都可以去存储多个document。一个document里面有多个field,每个field就是一个数据字段。

四、ES 集群的选举原理

①节点的角色

节点分为主节点、候选主节点、数据节点和协调节点,其中候选主节点和数据节点是在配置文件中指定的,而主节点是由候选主节点选举出来的,协调节点则可以是任何节点,以下是它们的功能介绍:

数据节点:负责数据的存储和相关的操作,例如对数据进行增、删、改、查和聚合等操作,所以数据节点(Data 节点)对机器配置要求比较高,对 CPU、内存和 I/O 的消耗很大。通常随着集群的扩大,需要增加更多的数据节点来提高性能和可用性。

候选主节点:可以被选举为主节点(Master 节点),集群中只有候选主节点才有选举权和被选举权,其他节点不参与选举的工作。

主节点:负责创建索引、删除索引、跟踪哪些节点是群集的一部分,并决定哪些分片分配给相关的节点、追踪集群中节点的状态等。主节点和其他节点之间通过 Ping 的方式互相检查,主节点负责 Ping 所有其他节点,判断是否有节点已经挂掉;其他节点也通过 Ping 的方式判断主节点是否处于可用状态;稳定的主节点对集群的健康是非常重要的。

协调节点:虽然对节点做了角色区分,但是用户的请求可以发往任何一个节点,并由该节点负责分发请求、收集结果等操作,而不需要主节点转发,这种节点可称之为协调节点,协调节点是不需要指定和配置的,集群中的任何节点都可以充当协调节点的角色。

ES中每个节点既可以是候选主节点也可以是数据节点,通过在配置文件 ../config/elasticsearch.yml 中设置即可,默认都为 true。

node.master: true  //是否候选主节点
node.data: true    //是否数据节点

但是由于数据节点对 CPU、内存核 I/O 消耗都很大,所以如果某个节点既是数据节点又是主节点,那么可能会对主节点产生影响从而对整个集群的状态产生影响。因此为了提高集群的健康性,我们应该对 ES集群中的节点做好角色上的划分和隔离,可以使用几个配置较低的机器群作为候选主节点群。

②发现与选举机制

发现机制(Zen Discovery)

那么有一个问题,ES 内部是如何通过一个相同的设置 cluster.name 就能将不同的节点连接到同一个集群的呢?答案是 Zen Discovery
Zen Discovery是 ES的内置默认发现模块(发现模块的职责是发现集群中的节点以及选举 Master 节点)。它提供单播和基于文件的发现,并且可以扩展为通过插件支持云环境和其他形式的发现。Zen Discovery 与其它模块集成:例如,节点之间的所有通信都使用 Transport 模块完成,节点使用发现机制通过 Ping 的方式查找其他节点。

ES默认被配置为使用单播发现,以防止节点无意中加入集群,只有在同一台机器上运行的节点才会自动组成集群。如果集群的节点运行在不同的机器上,使用单播,你可以为 ES节点提供一些它应该去尝试连接的节点列表即单播列表。当该节点联系到单播列表中的成员时,它就会得到整个集群所有节点的状态,然后它会联系 Master 节点,并加入集群。这意味着单播列表不需要包含集群中的所有节点, 它只是需要足够的节点,当一个新节点联系上其中一个并且说上话就可以了。如果你使用 Master 候选节点作为单播列表,你只要列出三个就可以了。这个配置在 elasticsearch.yml 文件中:

discovery.zen.ping.unicast.hosts: ["host1", "host2:port"]

ES节点启动后先 Ping ,如果 discovery.zen.ping.unicast.hosts 有设置,则 Ping 设置中的 Host ,否则尝试 ping 本地的几个端口。ES支持同一个主机启动多个节点,Ping 的 Response 会包含该节点的基本信息以及该节点认为的 Master 节点。

Master选举

采用分布式系统思路,保证选举出的master被多数派(quorum)的master-eligible node(候选主节点)认可,以此来保证只有一个master。这个quorum通过以下配置进行配置:

conf/elasticsearch.yml:
    discovery.zen.minimum_master_nodes: 2

(1)master选举谁发起,什么时候发起?

master(主节点)选举当然是由master-eligible(候选主节点)节点发起,当一个master-eligible节点发现满足以下条件时发起选举:

总结一句话,即当一个节点发现包括自己在内的多数派的master-eligible节点认为集群没有master时,就可以发起master选举。

(2)当需要选举master时,选举谁?

如果各节点都没有认为的 Master ,则从所有候选主节点中选择,规则很简单,按照 ID(ID为节点第一次启动时随机生成) 的字典序排序,取第一个。之所以这么设计,应该是为了让选举结果尽可能稳定,不要出现都想当master而选不出来的情况。

(3) 什么时候选举成功?

这里有个限制条件就是 discovery.zen.minimum_master_nodes :如果候选主节点数达不到最小值的限制,则循环上述过程,直到候选主节点数足够可以开始选举,如果只有一个 Local 节点那就选出的是自己。如果当前节点被选为Master ,则开始等待节点数达到 discovery.zen.minimum_master_nodes,然后提供服务;如果当前节点不是 Master ,则尝试加入 Master 。

举例说明:

当一个master-eligible node(我们假设为Node_A)发起一次选举时:

a、假设Node_A选Node_B当Master:Node_A会向Node_B发送join请求,那么此时:

b、假设Node_A选自己当Master:

此时NodeA会等别的node来join,即等待别的node的选票,当收集到超过半数的选票时,认为自己成为master,然后变更cluster_state中的master node为自己,并向集群发布这一消息。

③脑裂现象

如果由于网络或其他原因导致集群中选举出多个 Master 节点,使得数据更新时出现不一致,这种现象称之为脑裂,即集群中不同的节点对于 Master 的选择出现了分歧,出现了多个 Master 竞争。

脑裂问题可能有以下几个原因造成:

为了避免脑裂现象的发生,我们可以从原因着手通过以下几个方面来做出优化措施:

阿Q打算把ES的知识做一个系统的学习与讲解,所以后续将持续输出ES的相关知识,如果你感兴趣的话,可以关注gzh“阿Q说”!你也可以后台留言说出你的疑惑,阿Q将会在后期的文章中为你解答。每天学习一点点,每天进步一点点。

上一篇下一篇

猜你喜欢

热点阅读