欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

ElasticSearch之分布式特性

程序员文章站 2024-01-19 17:16:58
...

1. ES 分布式特性

ES 支持集群模式,是一个分布式系统,其好处主要有两个:

  1. 增大系统容量,如内存,磁盘,使得 ES 可以支持 PB 级数据;
  2. 提高系统可用性,即使部分节点停止服务,整个集群依然可以正常服务。

ES 集群由多个 ES 实例组成,不同集群通过集群名称来区分,可以通过 cluster.name 进行修改,默认为 elastic search;每个 ES 实例实际上是一个 JVM 进程,且有自己的名称,可以通过 node.name 进行修改。

 

1.1 Cluster State

ES 集群相关的数据称为 cluster state ,主要记录如下信息:节点信息,包括节点名称,连接地址;索引信息,包括索引名称,索引配置。cluster state 存储在每个节点上。

 

1.2 Master Node

可以修改 cluster state 的节点称为 master 节点,一个集群只能有一个,cluster state 存储在每个节点上,Master 维护最新版本并同步给其他节点。master 节点是通过集群中的所有节点选举产生的,可以被选举的节点称为 master eligible 节点,相关配置为:node.master: true

 

1.3 Coordinating Node

处理请求的节点被称为 coordinating 节点,该节点为所有节点的默认角色,不能取消,路由请求到正确的节点处理,比如创建索引的请求到 master 节点。

 

1.4 Data Node

存储数据的节点称为 data 节点,默认所有节点都是 data 节点,相关配置如下:node.data: true

 

1.5 系统可用性,副本和分片

  1. 服务可用性,2个节点情况下,允许其中一个节点停止服务;
  2. 数据可用性,引用副本(replication)解决,使得每个节点上都有完备的数据

ElasticSearch之分布式特性

 

1.6 增大系统容量

引用分片(shard)将数据分布在所有节点上,分片是 ES 支持 PB 级数据的基石。分片存储了部分数据,可以分布于任意节点上;分片数在索引创建时指定且后续不允许更改,默认为5个;分片有主分片和副本分片之说,已实现数据的高可用;副本分片的数据由主分片同步,可以有多个,从而提高读取的吞吐量。分片数的设定很重要,需要提前规划好。过小会导致后续无法增加节点实现水平扩容;过大会导致一个节点上分布过多分片,造成资源浪费,同时会影响查询性能。

ElasticSearch之分布式特性

 

思考:

  1. 此时增加节点能否提高索引 test_index 的数据容量?

答:不能,因为只有三个分片,已经分布在三个节点上,新增的节点无法利用。

ElasticSearch之分布式特性

 

  1. 此时增加副本数能否提高索引 test_index 的读取吞吐量?

答:不能,因为新增的副本也是分布在这三台节点上,还是利用了同样的资源,如要增加吞吐量,还要增加节点。

ElasticSearch之分布式特性

 

1.7 Cluster Health

通过如下 API 可以查看集群健康状态,包括以下三种:

  1. green:健康状态,所有主副分片都正常分配;
  2. yellow:所有主分配都正常分配,但是有副分配未正常分配;
  3. red:有主分配未分配。
GET _cluster/health

 

1.8 故障转移

  1. 集群由三个节点组成,如图一所示,此时集群状态是 green;
ElasticSearch之分布式特性
图一

 

  1. node1 所在机器宕机导致服务终止,此时集群会如何处理?

a. node2 和 node3 发现 node1 无法响应一段时间后会发起 master 选举,此时这里选择 node2 为 master 节点,此时由于主分片 P0 下线,集群状态变为 red (图二);

ElasticSearch之分布式特性
图二

 

 

b. node2 发现主分片 P0 未分配,将 R0 提升为主分片,此时由于所有主分配都正常分配,集群状态变为 yellow(图三);

ElasticSearch之分布式特性
图三

 

 

c. node2 为 P0 和 P1 生成新的副本,集群状态变为 green (图四);

ElasticSearch之分布式特性
图四

 

 

1.9 文档分布式存储

ElasticSearch之分布式特性

 

上图中,文档是如何存储到分配 P1 的?选择 P1 的依据是什么?

其实,文档如何存储到分配上是需要文档到分配的映射算法,这样才能使得文档均匀的分布在所有分片上,以充分利用资源。对于算法的选择是否可以为随机选择或是 round-robin 算法呢?显然这两种算法都是不可取的,因为需要维护文档到分配之间的映射关系,成本巨大,可选的算法应该是根据文档值实时的计算对应的分片。

ES 通过如下的算法计算文档对应的分片:

shard = hash(routing) % numbers_of_primary_shards

  1. hash 算法可以保证将文档均匀的分散在分片中;
  2. routing 是一个关键参数,默认为文档 ID,也可以自行指定;
  3. numbers_of_primary_shards 为主分片数。

 

1.10 文档的创建与读取流程

a. 文档的创建流程

ElasticSearch之分布式特性

 

b. 文档的读取流程

ElasticSearch之分布式特性

 

c. 文档批量创建流程

ElasticSearch之分布式特性

 

d. 文档批量读取流程

 

ElasticSearch之分布式特性

 

1.11 脑裂问题

脑裂问题,英文为:split-brain,是分布式系统中的经典问题,如下图所示:

  1. node1 因网络原因,无法与 node2 和 node3 进行通信;
  2. node2 和 node3 会从新选举 master,比如 node2 成为新的 master,此时会更新 cluster state;
  3. node1 自己组成集群后,也会更新 cluster state。

同一个有两个 master,而且维护不通的 cluster state,网络恢复后无法选择正确的 master。

ElasticSearch之分布式特性

解决方案:

在可选举 master-eligible 节点数大于等于 quorum 时才可以进行 master 选举。

  1. quorum = master-eligible 节点数 / 2 + 1,例如3个 master-eligible 节点时,quorum = 2;
  2. 设定 discrovery.zen.minimum_master.nodes 即可避免脑裂问题。

ElasticSearch之分布式特性

 

1.12 倒排索引的不可变更

倒排索引一旦生成,不能更改,其好处有:

  1. 不用考虑并发写文件的问题,杜绝了锁机制带来的性能问题;
  2. 由于文件不再更改,可以充分利用文件系统缓存,只需载入一次,只要内存足够,对该文件的读取都是从内存读取,性能高;
  3. 利于生成缓存数据;
  4. 利于对文件进行压缩存储,节省硬盘和内存存储空间;

其坏处为需要写入新文档时,必须重新构建倒排索引文件,然后替换老文件,新文档才能被索引,导致文档实时性差。解决方案为新文档直接生成新的倒排索引文件,查询时同时查询所有的倒排索引文件,然后做结果的汇总计算即可。

ElasticSearch之分布式特性

 

1.13 文档搜索实时性

新文档直接生成新的倒排索引文件,搜索的时候查询所有的索引文件即可。

ElasticSearch之分布式特性

Lucene 便是采用了这种方案,它构建的单个倒排索引称为 segment,合在一起称为 Index,与 ES 的 Index 概念不同,ES 的一个 shard 对应 Lucene Index,Lucene 会有一个专门的文件来记录所有的 segment 信息,称为 commit point。

ElasticSearch之分布式特性

 

文档搜索实时性 - refresh

segment 写入磁盘的过程依然很耗时,可以借助文件系统缓存的特性,现将 segment 在缓存中创建并开放查询来进一步提高实时性,该过程在 ES 里面称为 refresh。

在 refresh 之前文档会先存储在一个 buffer 中,refresh 时将 buffer 中的所有文档清空并生成 segment。

ES 默认每1秒执行一次 refresh,因此文档的实时性提高到1秒,这也是 ES 被称为近实时(Near real time)的原因。

refresh 发生的时机主要有以下几种情况:

  1. 间隔时机到达时,通过 index.setting.refresh.interval 来设定;
  2. index buffer 占满时,其大小通过 indices.memory.index_buffer.size 设置,默认为 JVM heap 的 10%,所有 shard 共享;
  3. flush 发生时也会触发 refresh。

ElasticSearch之分布式特性

 

文档搜索实时性 - translog

如果在内存中的 segment 还没有写入磁盘前发生宕机,那么其中的文档就无法恢复了,ES 为了解决这个问题,引入了 translog 机制。

  1. 写入文档到 buffer 时,同时将该操作写入 translog ;
  2. translog 会即时写入到磁盘(fsync),6.X 默认每个请求都会落盘,可以修改为每5秒写一次,这样的风险便是会丢失5秒的数据,相关配置为:index.translog.*;
  3. ES 会在启动时检查 translog 文件,并从中恢复数据。

ElasticSearch之分布式特性

 

文档搜索实时性 - flush

flush 负责将内存中 segment 写入到磁盘,主要做如下的工作:

  1. 将 translog 写入磁盘;
  2. 将 index buffer 清空,其中的文档生成一个新的 segment,相当于一个 refresh 操作;
  3. 更新 commit point 并写入磁盘;
  4. 执行 fsync 操作,将内存中的 segment 写入到磁盘;
  5. 删除旧的 translog 文件。

flush 发生的时机主要有以下几种情况:

  1. 间隔时机到达,默认时 30 分钟,5.X 之前可以通过 index.translog.flush_threshold_period 修改,之后无法修复;
  2. translog 占满时,其大小可以通过 index.translog.flush_threshold_size 控制,默认 512 MB,每个 index 都有自己的 translog。

ElasticSearch之分布式特性

 

文档搜索实时性 - 删除与更新文档

segment 一旦生成就不能更改,那么要删除文档该如何操作呢?更新文档又该如何操作呢?

a. Lucene 专门维护一个 .del 文件,记录所有已经删除的文档,注意 .del 文档上记录的是文档在 Lucene 内部记录的 ID;在查询结果返回前会过滤掉 .del 中的所有文档

b. 更新文档时,会首先删除文档,然后创建新的文档。

 

1.14 Segment merge

随着 segment 的增多,由于一次查询的 segment 的数量增多,查询速度会变慢;ES 会定时在后台进行 segment merge 的操作,减少 segment 的数量;通过 force_merge API 可以手动强制做 segment merge 的操作。

 

1.15 ES Index VS Lucene Index

ElasticSearch之分布式特性

 

相关标签: ELK 分布式特性