Elasticsearch 架构原理

为何要学习架构?

Elasticsearch的一些架构设计,对咱们作性能调优、故障处理,具备很是重要的影响。下面将从Elasticsearch的准实时索引的实现、自动发现、rounting和replica的读写过程,shard的allocate控制数据库

使文本能够被搜索?

在传统的数据库中,一个字段存一个值,可是这对于全文搜索是不足的。想要让文本中的而每一个单词均可以被搜索,这意味着数据库须要多个值。apache

支持一个字段多个值的最佳数据结构是倒排索引。倒排索引包含了出如今全部文档中惟一的值或或词的有序列表,以及每一个词所属的文档列表。缓存

倒排索引存储了比包含一个term的文档列表多地多的信息,它可能包含每个term的文档数量,一个term出如今制定文档中的频次,每一个文档中term的顺序,每一个文档的长度,全部文档的平均长度等等。这些统计信息让Elasticsearch知道哪些term更重要,哪些文档更重要,也就是相关性。数据结构

在全文搜索的早些时候,会为整个文档集合创建一个大索引,而且写入磁盘。只有新索引准备好了它就会替代旧的索引,最近的修改能够被检索。架构

不可变性性能

写入磁盘的倒排索引是不可变的,它有以下好处:学习

  • 不须要锁。若是历来不须要跟新一个索引,就没必要担忧多个程序见同时尝试修改。
  • 一旦索引被读入文件系统的缓存,它就一直在那儿,由于不会改变。只要文件系统缓存有足够的空间,大部分的读会直接访问内存而不是磁盘。这有助于性能的提高。
  • 在索引的声明周期内,全部的其余缓存均可用。他们不须要再每次数据变化了都重建,所以数据不会变。
  • 写入单个大的倒排索引,能够压缩数据,较少的磁盘IO和须要缓存索引的大小。

准实时索引的实现?

本文主要介绍Elasticsearch的准实时索引的实现,至于基于Lucene的倒排索引将不在这里介绍,有兴趣的读者能够去Lucene的相关文章,或者阅读《Lucene in Action》等书籍。下面将介绍Elasticsearch索引流程中发生的具体操做,重点在于其中的segment、buffer和translog三部分对性能方面的影响。spa

一、动态更新的Lucnee索引

要作到实时跟新条件下数据的可用和可靠,就须要在倒排索引的基础上,再作一系列更高级的处理。总结一下Lucene的处理办法:新收到的数据写入新的索引文件里。Lucene把每次生成的倒排索引,叫作一个段(segment)。而后另外使用一个commit文件,记录索引内的全部segment。而生成segment的数据来源,则是内存中的buffer,也就是说,动态跟新事后过程以下:1)当前磁盘上有三个segement可用,同时有一个commit文件记录当前的segment2)新收到的数据进入内存buffer,索引状态以下所示。3)buffer刷到磁盘,生成一个新的segment,commit文件同步跟新。这样能够完成跟新,也产生了几个问题:一、每次一有数据就刷新到磁盘,会增大对磁盘的操做架构设计

二、刷新到磁盘的时间占据很大一部分时间三、若是刷新的过程当中刷新失败应该怎么控制呢?设计

二、删除和更新

segment是不可变的,因此文档即不能从旧的段中删除,旧的段也不能更新以反映文档最新的文本。相反,每个提交点包括一个.del文件,包含了段上已经被删除的文档当一个文档被删除,它是实际上只是在.del文件中被标记删除,亦然能够匹配查询,但最终返回以前会被从结果中删除。文档的更新操做是相似的:当一个文档被更新,旧版本的文档被标记为删除,新版本的文档在新的段中索引。也许该文档的不一样版本都会匹配一个查询,可是老版本会从结果中删除。

三、利用磁盘缓存实现的准实时检索

既然涉及到磁盘,那么一个不可避免的问题就来了:磁盘太慢了!对咱们要求的实时性很高的服务来讲,这种处理还不够。因此,在刚刚第3步的处理中,还有一个中间状态:1)内存buffer生成一个新的segment,刷到文件系统缓存中,Lucene便可检索到这个新的segment,索引状态如图所示。2)文件系统缓存真正同步到磁盘上,commit文件跟新。刷到文件系统缓存中这个步骤,Elasticsearch默认1s的时间间隔,这也就是说至关因而实时搜索的,Elasticsearch也提供了单独的/_reflush接口,用户若是对1s间隔仍是不太满意,能够主动调用接口来保证搜索可见。

POST /_refresh <1>
POST /blogs/_refresh <2>
  • <1> refresh全部索引
  • <2> 只refresh 索引blogs

通常来讲咱们会经过/_settings接口或者定制template的方式,加大refresh_interval参数:

PUT /my_logs/_settings{ "refresh_interval": -1 } <1>
PUT /my_logs/_settings{ "refresh_interval": "1s" } <2>
  • <1> 禁用全部自动refresh
  • <2> 每秒自动refresh

四、translog提供的磁盘同步控制

既然refresh只是写到文件系统缓存中,那么最后一步写到实际磁盘又是由什么来控制的呢?若是这期间发生主机错误、硬盘故障等异常状况,数据会不会丢失?这里,其实Elasticsearch提供了另外一个机制来控制。Elasticsearch也把数据写入到内存buffer的同时,其实还另外记录了一个treanslog的日志。也就是说,在内存数据进入到buffer这一步骤时,其实还另外记录了一个translog记录。

相关文章
相关标签/搜索