ElasticSearch 分布式集群

公号:码农充电站pro
主页:https://codeshellme.github.iohtml

1,ES 的分布式架构

ES 是一个分布式的集群,具备高可用性可扩展性node

  • 高可用性指的是:当某些节点意外宕机或者数据丢失的时候,不影响整个集群的使用。
  • 可扩展性指的是:当业务数据量增长的时候,能够增长节点的数量,从而加强整个集群的能力。

ES 集群git

ES 集群中能够有一个或多个节点,ES 经过集群名字来区分不一样的集群,集群名能够经过 cluster.name 进行设置,默认为 "elasticsearch"。github

2,ES 的节点类型

ES 的一个节点就是一个 Java 进程,因此一台机器能够运行一个或多个节点,生产环境建议一台机器只运行一个节点。算法

每一个节点启动以后,都会分配一个 UID,并保存在 data 目录下。shell

每一个节点都有节点名字,节点名可经过 node.name 设置。缓存

2.1,Master 节点

Master 节点的职责:网络

  • 处理客户端的请求。
  • 决定分片被分配到哪一个节点。
  • 负责索引的建立于删除。
  • 维护集群状态。
  • 等。

集群的状态包括:架构

  • 全部的节点信息
  • 全部的索引及其 Mapping 和 Setting 信息
  • 分片的路由信息

全部的节点有保存了集群的状态信息,但只有主节点可以修改集群状态。app

2.2,Master-eligible 节点

在 ES 集群中,只有 Master-eligible 节点能够被选举为 Master 节点。

每一个节点启动后默认就是 Master-eligible 节点,能够经过设置 node.masterfalse 来禁止成为 Master-eligible 节点。

默认状况下,集群中的第一个节点启动后,会将本身选举为 Master 节点。

集群中的每一个节点都保存了集群的状态,但只有 Master 节点可以修改集群的状态信息。

2.3,Data 与 Coordinating 节点

用于保存 ES 数据的节点,就是 Data 节点,它对数据扩展起到了相当重要的做用。

Coordinating 节点叫作协调节点,它负责接收 Client 的请求,将请求分发到合适的节点,并最终汇总结果返回给 Client。

在 ES 中,全部的节点都是 Coordinating 节点。

2.4,Ingest 节点

Ingest 节点用于对数据预处理,经过添加一些 processors 来完成特定的处理。

Ingest 节点是在 ES 5.0 后引入的一种节点类型,能够达到必定的 Logstash 的功能。

默认状况下,全部的节点都是 Ingest 节点。

2.5,配置节点类型

理论上,一个节点能够扮演过多个角色,但生产环境中,建议设置单一角色。

节点的类型能够经过下面参数进行配置:

节点类型 配置参数 默认值
Master-eligible node.master true
Data Node node.data true
Ingest Node node.ingest true
Coordinating Node 设置上面 3 个都为 false

3,集群的健康状态

咱们能够经过下面的 API 来查看整个集群的健康状态:

在这里插入图片描述

集群有 3 种级别的健康状态:

  • green:全部的主分片与副本分片都正常。
  • yellow:全部的主分片都正常,某些副本分片不正常。
  • red:部分主分片不正常。

咱们也能够经过 Kibana 中的索引管理,来查看每一个索引的健康状态:

在这里插入图片描述

索引的状态级别与集群的状态级别一致。

4,脑裂问题

脑裂问题是分布式系统中的经典问题。

脑裂问题指的是,当出现网络故障时,一些节点没法与另外一些节点链接,这时这两大部分节点会各自为主;当网络恢复时,也没法恢复成一个总体。

在这里插入图片描述

如何避免脑裂问题

要限定一个选举条件,设置 Quorum(仲裁):

  • Quorum = (master 节点总数 / 2)+ 1

只有当 Master eligible 节点数大于 Quorum 时,才能进行选举。

在 ES 7.0 以前,为了不脑裂问题,须要手动设置 discovery.zen.minimum_master_nodes 为 Quorum。

在 ES 7.0 以后,ES 会本身处理脑裂问题,不须要用户处理。

5,ES 中的分片

ES 中的分片(Shard)用于存储数据,是存储的最小单元

分片有两种:主分片(Primary Shard)和副本分片(Replica Shard),副本分片是主分片的拷贝。

主分片用于数据水平扩展的问题,主分片数在索引建立时指定,以后不容许修改

副本分片用于解决数据高可用的问题,副本分片数能够动态调整

分片数能够经过索引的 setting 进行设置,好比:

PUT /index_name 
{
    "settings" : {
        "number_of_shards" : 3,
        "number_of_replicas" : 1
    }
}

其中 number_of_shards 表示主分片数,number_of_replicas 表示每一个主分片的副本分片数。

若是一个集群有 3 个数据节点,某个索引有 3 个主分片,1 一个副本分片,那么它的节点分布会像下面这样:

在这里插入图片描述

其中蓝色框为主分片,白色框为副本分片。

ES 在分配主副分片时,会将副本分片与主分片应该在不一样的节点上

主分片和副本分片分别分布到不一样的数据节点上,这样的话,若是有某个数据节点宕机,也不会影响整个系统的使用。

ES 7.0 开始,默认的主分片数为 1,默认的副本分片数为 0。在生产环境中,副本分片数至少为 1。

5.1,生产环境如何设置分片数

分片数设置不合理引起的问题:

在这里插入图片描述

5.2,集群节点的变化

在这里插入图片描述

根据这样的配置(3 个主分片,1 个副本分片),若是只有一个节点,则会致使副本分片没法分配(ES 会将主副分片分配在不一样的节点上),集群状态为 yellow

若是此时增长一个数据节点,那么副本分片就得以分配,集群具有了故障转移能力,集群状态转为 green

在这里插入图片描述

若是此时再增长一个数据节点,那么主节点会从新分配分片的分布。同时,集群的总体能力也获得了提高。

在这里插入图片描述

5.3,故障转移

若是此时有一个节点发生故障,好比主节点发生了故障:

在这里插入图片描述

此时集群的状态会变为 yellow,而后会从新选举主节点(假设选举了 Node2 为主节点),而且原来的 Node1 节点上的 p0R1 分片,会被分配到 Node2Node3 上。

在这里插入图片描述

集群调整完毕后,会从新恢复到 green 状态。

6,分片的内部原理

ES 中的一个分片对应了 Lucene 中的一个 Index。

6.1,Lucene Index

在 Lucene 中,单个倒排索引文件称为 Segment

Segment 是不可变的,当有新的文档写入时,会生成新的 Segment(放在文件系统缓存中)。

多个 Segment 汇总在一块儿称为 Lucene 中的 Index,也就是 ES 中的分片。

在这里插入图片描述

6.2,Refresh 刷新

ES 的文档在写入时,会先放在 Index Buffer(内存) 中,当 Index Buffer 的空间被占用到必定程度/时间周期后,会 Refresh 到 Segment 中,Index Buffer 则会被清空。

在这里插入图片描述

Refresh 的刷新频率能够经过 index.refresh_interval 参数进行设置,默认为 1 秒。

或者当 Index Buffer 被占用到 JVM 的 10%(默认值),也会触发 Refresh。

当文档被 Refresh 到 Segment 后,就能够被 ES 检索到了。

6.3,Transaction log

写入文档时,会先放在 Index Buffer 中,而 Index Buffer 是在内存中,为了防止内存意外(好比断电)丢失,在写入 Index Buffer 的同时,也会写到 Transaction log(磁盘)中。

在这里插入图片描述

一个 Transaction log 默认是 512M。

6.4,Flush 操做

ES 的 Flush 会触发如下操做:

  • 调用 Refresh
  • 调用 fsync,将文件系统缓存中的 Segment 写入磁盘。
  • 清空 Transaction log。

Flush 操做默认 30 分钟调用一次,或者当 Transaction log 满(默认 512 M)时也会触发 Flush。

6.5,Merge 合并

当愈来愈多的 Segment 被写入到磁盘后,磁盘上的 Segment 会变得不少,ES 会按期 Merge 这些 Segment。

文档的删除操做并不会立刻被真正的删除,而是会写入 del 文件中,Merge 操做也会删除该文件。

Merge 操做能够由 ES 自动触发,也能够手动强制 Merge,语法以下:

POST index_name/_forcemerge

7,文档的分布式存储

文档会均匀分布在分片上,充分利用硬件资源,避免资源利用不均。

文档到分片的路由算法:

  • shard_index = hash(_routing) % number_of_primary_shards
  • Hash 算法能够保证文档均匀的分散到分片上。
  • 默认的 _routing 值为文档 id。
  • _routing 的值也能够自行指定。

正是由于文档的路由算法是基于主分片数来计算的,因此主分片数一旦肯定之后,就不能修改。

_routing 的设置语法以下:

POST index_name/_doc/doc_id/routing=xxx
{
  # 文档数据
}

文档的 Write 操做(插入,更新,删除)的流程:

  1. 客户将文档的 Write 请求发送到 Coordinating 节点(Coordinating 节点负责处理客户请求,而不是 Master 节点)。
  2. Coordinating 节点经过 Hash 算法找到该文档的主分片
  3. 在主分片上进行 Write 操做,主分片 Write 成功后,将该 Write 请求发送到全部的副本分片
  4. 全部副本分片进行相应的 Write 操做,成功后,将结果返回给主分片。
  5. 主分片将因此的执行结果反馈给 Coordinating 节点。
  6. Coordinating 节点将最终的结果反馈给客户端。

在这里插入图片描述

8,分布式查询及相关性算分

8.1,Query Then Fetch 过程

ES 的搜索过程分两个阶段:

  • Query 阶段:
    • 用户将查询请求发送到 Coordinating 节点,Coordinating 节点会随机选择 N(主分片数) 个分片,发送查询请求。
    • 收到查询请求的分片执行查询,并进行排序。而后每一个分片都会返回 From + Size 个排好序的文档 ID 和排序值(score),给 Coordinating 节点。
  • Fetch 阶段:
    • Coordinating 节点会将从全部分片获得的文档从新排序,从新获得 From + Size 个文档的 ID。
    • Coordinating 节点以 Multi Get 的方式,到相应的分片获取具体的文档信息,并返回给用户。

这两个阶段合称为 Query Then Fetch

在这里插入图片描述

8.2,Query Then Fetch 的问题

在这里插入图片描述

8.3,算分不许的解决办法

在这里插入图片描述

(本节完。)


推荐阅读:

ElasticSearch 文档及操做

ElasticSearch 搜索模板与建议

ElasticSearch 聚合分析

ElasticSearch 中的 Mapping

ElasticSearch 数据建模


欢迎关注做者公众号,获取更多技术干货。

码农充电站pro

相关文章
相关标签/搜索