ElasticSearch从入门到精通--第四话(核心概念篇)

ElasticSearch从入门到精通–第四话(核心概念篇)

ElasticSearch从入门到精通–第一话(入门篇)

ElasticSearch从入门到精通–第二话(原生API调用–纯代码篇)

ElasticSearch从入门到精通–第三话(集群环境搭建篇)

ElasticSearch从入门到精通–第四话(核心概念篇)

ElasticSearch从入门到精通–第五话(整合SpringBoot高效开发、分页高亮等、Kibana使用篇)

核心概念

索引(Index)

一个索引就是一个用于几分相似特征的文档集合,可以理解为mysql中的一个数据库。

ES中索引的精髓:一切设计都是为了提高搜索的性能

类型(Type)

在一个索引中,可以定义一种或多种的类型,可理解为mysql中的表。一个类型就是索引一个逻辑上的分类,语义我们可以自定义。在不同版本,类型的概念逐渐被淡化了。

版本 Type
5.x 支持多种Type
6.x 支持一种Type
7.x 不再支持自定义的Type,有个默认Type名为_doc

文档(Document)

一个文档就是一个可被索引的基础信息单元,也就是一条数据,理解为mysql中的一行数据。

字段(Field)

相当于是数据表的字段,对文档数据进行不同属性分类的标识,都是以json方式存储的。

映射(Mapping)

Mapping是处理数据格式的方式和规则做一些限制,如:某个字段的数据类型、默认值、分析器、是否要被索引等等。都是可以在映射里面设置的,通常情况下我们可以按照业务场景,建立不同的映射,达到性能最高化。

分片(Shards)

这个可以理解为mysql中数据分表操作,一个索引可以存储的最大数据量中,单个节点处理搜索请求响应太慢。为了解决这个问题,ES提出将索引划分为多份,每一份就是一个分片。创建索引时我们可以指定分片的数量,每个分片本身也是一个功能完善并且独立的索引,这个索引可以被放置到集群中的任何节点上。

分片重要性:

  • 允许水平分割、扩展内容容量
  • 允许在分片之上进行分布式、并行操作,提高性能和吞吐量。

副本(Replicas)

为了提交服务的高可用性,ES允许创建分片时创建一份或多份拷贝,这些就是复制分片(副本)。

  • 副本在分片/节点失败情况下,提供了高可用性,且副本是不与master节点数据在同一个节点的(有点类似kafka集群的分区副本)
  • 扩展搜索量,搜索可以在所有的副本上并行运行

ES集群

在完整性较高的ES集群中,首先是多个ES服务器节点,有个master主节点进行管理集群,然后在多个ES节点上存放着索引的多个分区和其他分区的副本(高可用性角度考虑)

在这里插入图片描述

分布式集群(演变)

创建索引(多分片)

在一个单节点的ES节点上,创建一个索引,并且分配三个主分片和一个副本(每个主分片都有一个副本分片)

PUT请求,请求体中,设置

{
    
    
    "settings":{
    
    
        "number_of_shards":3,
        "number_of_replicas": 1
    }
}

在这里插入图片描述

然后GET请求下

在这里插入图片描述

分片数量是3,然后副本数量是1

可视化工具

那么集群有没有可视化的一些工具呢,当然有,像kibana、ES Head(谷歌插件)都可以使用。

我这边使用的谷歌的浏览器插件,有兴趣的可以看看教程

Google浏览器安装es-head

进去插件后,连接到这个es服务器

在这里插入图片描述

上图中,有一个node-1001的es节点,然后还有上面为灰色的0、1、2(光看users索引的,先别看shopping索引)

灰色的指的是副本未分配,其实原因呢就是副本数据是不能和主分片数据放在一起的(假如主分片的节点宕机,那么副本同样是用不了的,没有必要去分配副本)。然后它的集群健康值就是呈yellow黄色,指的就是当前集群的全部主分片都正常运行,但是副本没有处在正常状态中

故障转移(最少两台es节点)

说白了,就是启动集群,提高服务高可用性,就算某一个es节点宕机,那么其他的es节点仍可提供服务(因为其他es节点中保存着宕机节点的副本数据)

在上面的基础上,增加es节点,就可达到故障转移的作用。es节点加入集群后,副本数据会进行重分配。

尝试再启动一个es节点后,再去可视化界面看看,集群状态

在这里插入图片描述

集群状态变成了green绿色,且副本被分配到了node-1002的节点上面。

代表着每个分片(包括主分片和副本分片)都能对外提供服务,提高系统服务的高可用性。

水平扩容(2台以上es节点)

那么如何为我们正在增长的应用程序按需扩容呢,当启动了第三个es节点时,我们的集群会拥有3个es节点:会为了分散负载而对分片进行重新分配,提高系统吞吐量。

像上面两台es节点时,它的主分片和副本没有均匀放置在整个的集群中,那么就需要进行再扩展节点,达到均匀放置所有分片。

再启动一个es节点,看可视化界面

在这里插入图片描述

会发现,所有分片被分配到这三个节点中

再次理解,水平扩容:就是增加es节点,然后分片分配给这个新的es节点上面,达到水平扩展

扩展多台es

当要扩展的数量相对主分片数量较多时,因为刚开始创建索引时主分片数量被确定了,那就是定义了这个索引能够存储的最大数据量。但是读操作、搜索和返回数据是可以同时被主分片或副本分片处理,所有我们可以去扩展副本分片的数量,达到高吞吐的目的。

将副本的数量,设置为2

{
    
    
    "number_of_replicas": 2
}

在这里插入图片描述

设置每个主分片可以有2个副本,(1+2)*3=9个分片

在这里插入图片描述

应对故障

假如某一台es节点宕机了,master宕机,那么集群会选取一个slave节点成为master节点

在这里插入图片描述

可以看到,node-1001节点已经没了,然后选举node-1003为新的master节点

当宕机的节点重新进入集群后,node-1001是作为slave节点存活的。

node-1001的yml配置中,记得配置

discovery.seed_hosts: ["localhost:9303", "localhost:9302"]

在这里插入图片描述

主节点仍然是node-1003节点

路由计算

首先要明了,数据要放入某个分片时,一定先放入到主分片中的,因为副本分片只是一个备份,要记得。那么多主分片时,它是如何知道要放入到哪个主分片呢?就涉及到了路由计算.

(路由计算)数据存入时的算法:hash(routing)%主分片的数量

每个数据都有一个routing的参数,默认情况下就是文档的_id值即可,将id计算出hash值,然后对主分片的数量进行取余,取余的值就是具体的分区。那么主分片的数量一旦定义好,就不能轻易去更改了,一旦更改,那么之前计算好的所有路由值都会失效,文档就无法被索引了

数据写流程

数据传送过来后经过路由计算出要将数据存入到哪个es节点的分片上,那么再把数据发送给相应的es节点上的分片中存入数据,然后将数据发送给副本分片,副本进行同步数据。

  • 客户端请求集群节点(任意)-协调节点
  • 协调节点将请求转换到指定的节点
  • 主分片需要将数据保存
  • 主分片把数据发送给副本
  • 副本保存数据,进行反馈
  • 主分片进行反馈
  • 客户端收到反馈

集群中,有一些可选的参数

  • consistency:即一致性。默认设置下,主分片执行写操作时,规定必须要有一定数量的副本处于存活状态才能执行。(为了避免网络分区故障导致的数据不一致),副本存活数量是(primary+number_of_replicas)/2+1

    • 取值one:表示主分片状态ok就允许执行写操作
    • 取值all:表示主分片和副本全部存活状态才允许执行写操作
    • 取值quorum:部分数量副本存活允许写操作(默认值)

数据读流程

  • 客户端发送查询请求到协调节点中
  • 协调节点计算数据(hash(routing)%主分片数量)所在的分片及副本的全部位置
  • 轮询方式查询节点
  • 将请求转发给某个es节点
  • es节点返回结果,返回给客户端

倒排索引

ES使用的一种倒排索引的结构,适用于快速的全文索引。

原理:通过分词器将数据进行拆解,然后拆解后的词汇分别与文档ID做绑定,达到倒排的目的。当然,不同的分词器有不同的分词策略,根据不同的算法进行拆解。

  • 词条:索引中最小存储和查询单元
  • 词典:字典,词条的集合,B+,Hash算法
  • 倒排表:拆解后的词汇分别与ID做绑定的集合表。

近实时搜索

  • 在 Elasticsearch 中,写入和打开一个新段的轻量的过程叫做 refresh 。 默认情况下每个分片会每秒自动刷新一次。这就是为什么我们说 Elasticsearch 是 近 实时搜索: 文档的变化并不是立即对搜索可见,但会在一秒之内变为可见。

  • 这些行为可能会对新用户造成困惑: 他们索引了一个文档然后尝试搜索它,但却没有搜到。这个问题的解决办法是用 refresh API 执行一次手动刷新: /users/_refresh

  • 并不是所有的情况都需要每秒刷新。可能你正在使用 Elasticsearch 索引大量的日志文件,你可能想优化索引速度而不是近实时搜索, 可以通过设置 refresh_interval , 降低每个索引的刷新频率

     {
          
          
    	 "settings": {
          
          
    	 	"refresh_interval": "30s" 
    	 } 
     }
    
  • refresh_interval 可以在既存索引上进行动态更新。 在生产环境中,当你正在建立一个大的新索引时,可以先关闭自动刷新,待开始使用该索引时,再把它们调回来

    # 关闭自动刷新
    PUT /users/_settings
    {
          
           "refresh_interval": -1 } 
    
    # 每一秒刷新
    PUT /users/_settings
    {
          
           "refresh_interval": "1s" }
    

猜你喜欢

转载自blog.csdn.net/weixin_45248492/article/details/127734290