导言

之前写了一篇关于 ES 的一些基础知识篇,归于入门等级。传送门: ElasticSearch基础-入门篇。

本篇主要解说 ES 的一些深化特性以及原理,归于进阶篇。

一、仿制模型

1.1 仿制组

在入门篇中咱们讲过,ES 中每个索引都能够多个分片,每个分片能够有多个副本,副本分片是分片的完好副本,能够为查找恳求提供服务,一个主分片与其副本本分片统称为仿制组,主分片和副本在操作文档时有必要保持同步,否则就会导致不同副本之间数据不一致。还有需求留意一点便是主分片永久不可能与其副本分片在同一节点上。

1.2 ES中的仿制

仿制也是在索引等级配置的。ES 中的每个索引操作首要使用路由算法(一般基于文档ID)解析到一个仿制组,一旦确定了仿制组,该操作将在内部转发到该组当时的主分片(primary)。primary 担任验证操作并转发到其他的副本(replica)。primary 遵从如下操作流程。

  1. 验证传入操作是否符合 ES 的接口规范,假如不符合,直接拒绝。

  2. 在本地履行操作(索引、更新或删去文档)。这还将验证字段的内容(如关键字对索引而言过长),并在需求时拒绝。

  3. 将操作转发到当时同步副本组中的每个 replica。假如有多个副本,是并行完成的。

  4. 一旦一切的副本成功地履行了操作并对 primary 进行了响应,primary 就承认完成了恳求并返回给用户。

1.3 ES中读取数据

当发送读取恳求时,会将其传送到特定节点(和谐节点),担任和谐恳求。根本流程如下:

  1. 将读取恳求解析到相关分片组(一个或多个)。

  2. 从同步副本组中挑选一个相关的 shard 的活动分片(能够是 primary,也能够是 slave)。ES 会依据各种指标挑选最佳副本。

  3. 向所选分片发送读取恳求。

  4. 将结果整合。假如是依据文档 ID查询,只会有一个相关分片,没有此过程。

到这里,就领会到了副本的威力。假如只要一个主分片,一切查询都落到主分片上,随着工作负载的增加,此战略无法有效扩展,副本分片就会分管压力。

二、段(segment)

ES 底层依靠 lucene 来提供查找能力,一个分片便是一个 lucene 实例,一个 lucene 实例由多个段(segment) 组成,一个 segment 是有完好功用的倒排索引。

Segment 是最小的数据存储单元。其间包含了文档中的词汇字典、词汇字典的倒排索引以及 Document 的字段数据。Segment 直接提供了查找功用

三、缓冲区(buffer)

ES 索引的过程不会直接写入磁盘,而是先写入一个缓冲区,定时刷新到磁盘或者等缓冲区满了今后刷新到磁盘中的 segments 中,这个缓冲区便是 indexing buffer。节点上一切分片共享该区域。这部分空间是能够经过 GC 被反复使用的。索引缓冲区的大小经过配置indices.memory.index_buffer_size 指定,默许值为10%。

四、业务日志(translog)

ES 每次调用 lucene 的接口写入或删去数据后,都会先写入内存缓冲区,并将操作日志写入 translog,每个分片都对应一个translog,防止意外断电或程序溃散等原因导致数据丢掉。

translog 存储尚未在 lucene 中安全保存的一切操作 (即,不是 lucene 提交点的一部分)。尽管这些操作是可用于读取,假如分片停止,则需求重放它们而且有必要康复。

translog 默许是每隔 5s 写一次磁盘,假如出现宕机等问题,这可能会导致 5s 的数据丢掉。

五、近实时性

ES 写入的数据默许不会当即查询到(有的API是能够的),而是默许 1s 后才能查询到,这便是 ES 的近实时性。

文档物理性的写入磁盘 代价是很高的,所以有了以上咱们所讲的缓冲区、业务日志等概念。ES 将数据从缓冲区写到了 Cache 中,数据才能够被查找到的。数据先写入缓冲区,默许 1s 缓冲区中的数据会刷到Cache,Cache 会刷新到磁盘中。

六、文档写入流程

文字无比单调,还是图来的完全!

ElasticSearch深入-进阶篇

七、refresh和flush

打眼一看 refresh 和 flush 都是将某些操作的结果能够当即被查询到,那么为什么要有两个 API,它们之间终究有什么区别呢?

7.1 refresh

其实上文现已提到过了 refresh 了,默许情况下,ES 会每秒 refresh 一次,每次 refresh 都会把 buffer 的内容拷贝到新创建的 segment 中去,这个时分新的文档就会被查找了。

7.2 flush

ES 中的 flush 操作是指将索引中的数据当即写入磁盘,以保证数据不会丢掉。

flush 操作意味着,一切在 buffer 的文档被写到新的 segment 中,也便是一切在内存中的 segment 被提交到了磁盘进行存储,此刻 translog 也能够被清除了。有没有想过每次文档写入都会写入 translog,这将导致 translog 越来越大,为了防止这个问题,ES 会在 translog 达到了一定大小的时分,触发 flush 操作。默许 30 分钟,也会触发 flush 操作将内存中的数据写入磁盘。

八、GET API的实时性

默许情况下,Get API (经过索引ID查询)是实时的,不受 refresh 操作的影响,即数据没有进行 refresh 操作,也能够被查询到,这又是怎样个事呢?

经过上文的解说,想必我们都现已猜到了,没错便是经过 translog 来完成的实时性。GET API 默许是实时的(realtime=true), 则先从 translog 中读取 source, 没有读取到才从索引中读取,能够将 realtime 设置为 false 来禁用默许。