隐藏

Elasticsearch的增删改查原理分析

发布:2023/1/16 13:39:16作者:管理员 来源:本站 浏览次数:262


Elasticsearch的index


Elasticsearch的索引(index)是用于组织数据的逻辑命名空间(如数据库)。Elasticsearch的索引有一个或多个分片(shard)(默认为5)。分片是实际存储数据的Lucene索引,它本身就是一个搜索引擎。每个分片可以有零个或多个副本(replicas)(默认为1)。Elasticsearch索引还具有“类型(type)”(如数据库中的表),允许在索引中对数据进行逻辑分区。Elasticsearch索引中给定“类型(type)”中的所有文档(documents)具有相同的属性(如表的模式)。


前者显示了一个由三个主分片组成的Elasticsearch集群,每个主分片分别有一个副本。所有这些分片一起形成一个Elasticsearch索引,每个分片是Lucene索引本身。


后者演示了Elasticsearch索引,分片,Lucene索引和文档(document)之间的逻辑关系。

新建索引操作实现原理


当向协调节点发送请求以索引新文档时,将执行以下操作:


   所有在Elasticsearch集群中的节点都包含:有关哪个分片存在于哪个节点上的元数据。协调节点(coordinating node)使用document_id(默认)将文档路由到对应的分片。shard = hash(document_id) % (num_of_primary_shards)

   当节点接收到来自协调节点的请求时,请求被写入到translog,并将该文档添加到内存缓冲区。如果请求在主分片上成功,则请求将并行发送到副本分片。只有在所有主分片和副本分片上的translog被fsynced后,客户端才会收到该请求成功的确认。

   内存缓冲区以固定的时间间隔刷新(默认为1秒),并将内容写入文件系统缓存中的新段(segment)。此分段的内容尚未被fsynced(未被写入文件系统),分段是打开的,内容可用于搜索。

   translog被清空,并且文件系统缓存每隔30分钟进行一次fsync,或者当translog变得太大时进行一次fsync。这个过程在Elasticsearch中称为flush。在刷新过程中,内存缓冲区被清除,内容被写入新的文件分段(segment)。当文件segment被fsynced并刷新到磁盘,会创建一个新的提交点(其实就是会更新文件偏移量,文件系统会自动做这个操作)。旧的translog被删除,一个新的开始。


Update和Delete实现原理


删除和更新操作也是写操作。但是,Elasticsearch中的文档是不可变的(immutable),因此不能删除或修改。


如何删除/更新文档呢?


删除:磁盘上的每个分段(segment)都有一个.del文件与它相关联。当发送删除请求时,该文档未被真正删除,而是在.del文件中标记为已删除。此文档可能仍然能被搜索到,但会从结果中过滤掉。当分段合并时,在.del文件中标记为已删除的文档不会被包括在新的合并段中。


更新:创建新文档时,Elasticsearch将为该文档分配一个版本号。对文档的每次更改都会产生一个新的版本号。当执行更新时,旧版本在.del文件中被标记为已删除,并且新版本在新的分段中编入索引。旧版本可能仍然与搜索查询匹配,但是从结果中将其过滤掉。

Read的实现原理


读操作由两个阶段组成:查询阶段(query)和获取(fetch)阶段。


查询阶段


在此阶段,协调节点将搜索请求路由到索引(index)中的所有分片(shards)(包括:主分片或副本分片)。分片独立执行搜索,并根据相关性分数创建一个优先级排序结果(稍后我们将介绍相关性分数)。所有分片将匹配的文档和相关分数的文档ID返回给协调节点。协调节点创建一个新的优先级队列,并对全局结果进行排序。可以有很多文档匹配结果,但默认情况下,每个分片将前10个结果发送到协调节点,协调创建优先级队列,从所有分片中分选结果并返回前10个匹配。


获取阶段


在协调节点对所有结果进行排序,生成全局排序的文档列表后,它将向所有分片请求原始文档。 所有的分片都会丰富文档并将其返回到协调节点。

一个请求被分发的过程


发送一个请求:


这个请求可能被分发到集群里的任意一个节点:


这时这个节点就成为当前请求的协调者(Coordinator),它决定:


   根据索引信息,判断请求会被路由到哪个核心节点

   以及哪个副本是可用的