一串文本,先经过分词 分成词项 被称为term。我们要搜索一个词项的时候,如果挨个遍历时间复杂度是0n 为了解决查询速度,可以将词项按从小到大排序,排序过后通过二分查找的方法,将时间复杂度优化为 ologn,这就组成了一个term dictionary,词项对应的doc id就叫posting list,这两个共同组成了倒排索引。由于term dictionary数据量很大,放在内存不现实,只能放在磁盘,这样的话查询速度很慢,为了解决这个问题,引入了term index。
term index主要是将词项和词项之间相同的前缀提取出来,构建成一个精简的目录树,存放词项在磁盘中的偏移量,也就是指向磁盘的位置,这个目录树放在内存中,用来加速搜索。我们查询某个词项的时候只需要搜索term index,就能找到词项在term dictionary中的大概位置,再跳转到term dictionary。前面的倒排索引搜索到的是doc id,为了找到文档内容本身,需要有一个地方存储完整的文档内容,就是stored fields 行式存储,这样我们就可以通过doc id找到完整的文档内容,但是用户经常要查询排序后的内容,可以从业务上先从stored搜索出来在进行排序,但也有更高效的做法。我们可以直接将某个字段集中存放。
这四个东西共同组成了一个符合文件 segment,具备完整搜索功能的最小单元。我们可以用多个文档生成一份segment,如果新增文档,就写一个新的segment,老segment只负责读,segment多了就并发的读多个。随着数据量增大,segment越来越多,文件句柄消耗的越来越多,不定期合并segement merging,这个就叫lucene 单机文本检索库。
es分为主节点,数据节点,协调节点
es的写入流程 写入请求先发到集群中的协调节点,协调节点根据hash路由判断该写入哪个数据节点中的分片,找到主分片写入,底层是lucene,所以最终是写到了segment内将数据固化为倒排索引 stored field doc values这些结构。
主分片写完后 将数据同步给副本分片,副本分片写入万抽,主分片会响应协调节点返回一个ack,最后协调节点相应客户端应用写入完成。
es搜索分为查询阶段和获取阶段
客户端发起搜索请求,请求会先发到集群的协调节点,协调节点根据index name了解被分成了几个分片,以及这些分片在哪数据节点上,将请求转发到分片上。请求到达分片后,分片底层lucene会并发的搜索segment,利用倒排索引找到文档id,结合doc values获得排序信息,并将结果聚合返回给协调节点,协调节点将多个分片中拿到的数据进行一次聚合,舍弃不需要的数据。
获取阶段 协调节点拿着文档id请求数据节点中的分片,lucene会从segment内的stored field读取到完整文档,返回给协调节点,最终将数据返回给客户端。
以上来源个人总结,转载请注明出处,一经发现将提起法律诉讼
标签:search,elastic,segment,面试官,文档,term,分片,词项,节点 From: https://blog.csdn.net/qq_37034181/article/details/142659325