Elasticsearch 文档索引过程描述
1.协调节点默认使用文档ID参与计算(也支持通过routing),以便为路由提供合适的分片。
shard = hash(document_id) % (num_of_primary_shards)
2.当分片所在的节点接收到来自协调节点的请求后,会将请求写入到Memory Buffer,然后定时(默认是每隔1秒)写入到Filesystem Cache,这个从Momery Buffer到Filesystem Cache的过程就叫做refresh;
3.当然在某些情况下,存在Momery Buffer和Filesystem Cache的数据可能会丢失,ES是通过translog的机制来保证数据的可靠性的。其实现机制是接收到请求后,同时也会写入到translog中,当Filesystem cache中的数据写入到磁盘中时,才会清除掉,这个过程叫做flush。
4.在flush过程中,内存中的缓冲将被清除,内容被写入一个新段,段的fsync将创建一个新的提交点,并将内容刷新到磁盘,旧的translog将被删除并开始一个新的translog。
5.flush触发的时机是定时触发(默认30分钟)或者translog变得太大(默认为512M)时。
Update和Delete实现原理
删除和更新操作也是写操作。但是,Elasticsearch中的文档是不可变的(immutable),因此不能删除或修改。那么,如何删除/更新文档呢?
磁盘上的每个分段(segment)都有一个.del文件与它相关联。当发送删除请求时,该文档未被真正删除,而是在.del文件中标记为已删除。此文档可能仍然能被搜索到,但会从结果中过滤掉。当分段合并时(我们将在后续的帖子中包括段合并),在.del文件中标记为已删除的文档不会被包括在新的合并段中。
现在,我们来看看更新是如何工作的。创建新文档时,Elasticsearch将为该文档分配一个版本号。对文档的每次更改都会产生一个新的版本号。当执行更新时,旧版本在.del文件中被标记为已删除,并且新版本在新的分段中编入索引。旧版本可能仍然与搜索查询匹配,但是从结果中将其过滤掉。
indexed/updated文档后,我们希望执行搜索请求。我们来看看如何在Elasticsearch中执行搜索请求。
Read的实现原理
读操作由两个阶段组成:查询阶段(Query Phase)和获取阶段(Fetch Phase)
1.查询阶段(Query Phase)
在此阶段,协调节点将搜索请求路由到索引(index)中的所有分片(shards)(包括:主节点或副本)。分片独立执行搜索,并根据相关性分数创建一个优先级排序结果(稍后我们将介绍相关性分数)。所有分片将匹配的文档和相关分数的文档ID返回给协调节点。协调节点创建一个新的优先级队列,并对全局结果进行排序。可以有很多文档匹配结果,但默认情况下,每个分片将前10个结果发送到协调节点,协调创建优先级队列,从所有分片中分选结果并返回前10个匹配。
2.获取阶段(Fetch Phase)
在协调节点对所有结果进行排序,已生成全局排序的文档列表后,它将从所有分片请求原始文档。
所有的分片都会丰富文档并将其返回到协调节点。
搜索相关性(Search Relevance)
相关性由Elasticsearch给予搜索结果中返回的每个文档的分数确定。用于评分的默认算法为tf / idf(术语频率/逆文档频率)。该术语频率测量术语出现在文档中的次数(更高频率=更高的相关性),逆文档频率测量术语在整个索引中出现的频率占索引中文档总数的百分比(更高的频率 ==较少的相关性)。最终得分是tf-idf分数与其他因素(如词语邻近度(短语查询)),术语相似度(用于模糊查询)等的组合。
网友评论