ES索引改写-近实时查找

零、省流版本

ES的数据更新依赖于被改写到磁盘的段,每个段都会记录自上一次提交以来记录的文档的删去以及修正,并终究在写入磁盘时收效。为减少段的数量,ES会守时进行段兼并。

这意味着,ES只有当内存中的段被持久化到磁盘上并发生提交点时,这部分数据才干被检索到。当改写操作发生时,段将会被提交,索引会守时主动改写,一起也能够经过指令手动触发。

一、分片与分段

我们在创立一个ES索引的时分通常会根据需求设置索引的分片数以及分片的副本数,其间,分片数表明这个索引的数据将会被水平拆分成几部分,副本数则表明这个分片会一起有几个备份。需求留意的是,分片的副本在检索时会起到与主分片完全相同的效果,也就是说,分片的副本数越多,这个索引能承担的查找并行度也就越多,可是副本数的增多也会进步对网络带宽以及存储的耗费,实践设置时需求自行取舍。

索引与分片的比较

被混杂的概念是,一个 Lucene 索引我们在 Elasticsearch 称作 分片。 一个 Elasticsearch 索引 是分片的集合。 当 Elasticsearch 在索引中查找的时分, 他发送查询到每一个属于索引的分片(Lucene 索引),然后像 履行分布式检索 说到的那样,兼并每个分片的成果到一个全局的成果集。

分片数仅能够在创立索引时设置,副本数则能够动态调整。

例如,下图是一个3分片2副本的ES索引,它建立在一个3节点的集群中。

ES索引刷新-近实时搜索

我们知道倒排索引是不可变的,不可变当然有许多好处,例如:

  • 不需求考虑并发问题,也就不需求锁。
  • 因为索引不会改动,所以一旦缓存就能够确保后续恳求到索引的数据不会查询磁盘,进步性能。
  • 不需求重建缓存,因为数据不会发生改变。

可是不可变会有许多缺点,比如最重要的是对文档的更新或者删去怎么表现到倒排索引中?ES的解决方案是,用更多的索引,经过新的索引来弥补最近的修正,每一个倒排索引都是分片中的段。

二、更新不可变的数据-追加索引

ES对改动的策略是用新的索引来弥补数据的改变,当数据的检索发生的时分,每一个倒排索引都会被检索并回来自己保存的成果,数据的改变则是会在成果兼并时被表现。

增加文档

新的文档会首要被存储在内存的段中,此刻这个文档对检索是不可见的,内存中的段会不守时的被提交,此刻这个段会被写入到磁盘,一起能够被检索到。

删去文档

当我们进行删去文档的操作时,这个文档并不会被当即删去,而是在.del文件中将这个文档标记为已删去,也就是说在进行检索的时分,这个文档依然会被检索到,只是在分片进行数据兼并时会过滤掉这个数据,数据真实的删去发生在段兼并的时期。

更新文档

文档的更新会使用版本的概念,当更新恳求抵达时,ES会根据新的内容创立一个新的文档,然后更新版本号,随后旧的文档将会被标记为删去,新的文档被加入到索引傍边。在段兼并发生之前,进行检索时依然会检索到旧的文档,就是新旧文档会一起在段中被查找到,分片进行数据兼并时会过滤掉旧的文档。

段的提交与创立

段的提交流程大致如下所示:

  • 新的段被写入磁盘
  • 包含新的段的姓名的提交点被写入磁盘
  • 磁盘进行同步,将文件体系缓存的数据刷入磁盘

段创立的时机与索引改写以及装备相关:

  • 基于段兼并:当触发了段兼并的操作时,ES会创立一个相对较大的段来兼并小段。
  • 基于索引改写:当索引改写时,会将旧的段提交并写入到文件体系的缓存,一起在内存中创立一个新的段用于存储新增的数据。

段和提交点的关系如下图所示,提交点中包含了所有已提交的段的信息,以及文档的更新删去等信息

ES索引刷新-近实时搜索

段的效果

假如每个分片只有一个索引,那么每当修正(增加,更新,删去)发生时,就需求重建整个索引,这样从修正发生到能被检索到修正的进程就会比较长。

分段使得每个段都是完结的倒排索引,修正文档时就不需求对旧的索引进行更新,极大的缩短了修正发生到能够被检索到的时间。只要段完结了提交,就能够被检索到。

三、近实时查找

轻量级提交

经过对分片中的数据进行分段,进一步水平拆分数据,使得从增加数据到数据能被检索到的延迟进一步被降低了,可是还不够快,因为段的提交的最终一步:磁盘同步依然是一个很重的操作,假如在每次索引一个新的文档的时分就履行一次磁盘同步会对性能形成很大的损失。

为了解决这个问题,ES使用了更轻量级的解决方案,先把数据写入到文件体系缓冲区中,此刻尽管还没有同步到磁盘中,可是已经能够被翻开和读取数据了。

Lucence允许在一次完好的提交没有完结时就对查找可见,也就是在文件被写入缓冲区时就能被检索到,一起文件写入到缓冲区是一个轻量级操作,它的价值比同步到磁盘小的多,能够被频频的履行。

ES索引刷新-近实时搜索

改写API

经过轻量级操作写入和翻开一个段的进程叫做改写,默许情况下分片会每秒主动改写一次,这使得文档的改变在一秒内会变为可见,但并不是当即可见的。

除去装备的主动改写以外,还能够经过下面的API手动改写索引的数据。尽管改写是比提交轻量的操作,它依然有性能的开销,因此在生产环境应当防止手动改写,尽量经过合理的主动改写装备来进行。

这是ES近实时查找的特性,应当了解并接受它,而不是强迫它成为实时的

POST /_refresh  改写所有的索引
POST /index/_refresh 只改写方针索引