搜索中一些工程问题

1、 倒排拉链如果很长如何处理

(1)倒排拉链的长度是有限制的,这个长度限制是亿级别的,所以一般不会超出,如果真的超出就会截断

(2)可能超出长度的是一些停用词,如果超出就会截断,并且停用词在建立倒排的时候,位置信息只建立一个,因为这些词一般无意义只是为了召回,如果位置信息太多,在后续计算proximity score的时候比较耗时,这些需要处理的词是挖掘好的词表

2、如何提升索引检索的性能

(1)索引分区

索引可以分区,按照termid分区即可,这样取一个term的doclist的时候,首先将term转化为termid,然后termid%分区数就可以hash到这个termid的索引块,然后在这个索引块中进行二分查找找到这个termid对应的doclist

(2)索引查找

索引查找主要使用的是跳表查找,先看一下数据结构

首先word的doclist在物理机上存储的基本单位是section,每个section中存储一定量的doclist,假设某个word的doclist有1024个,每个section可以存储512个docid,那么这个word需要两个section,如果有多个section,那么多个section可以使用跳表连接起来

在section内部,doclist也是有大小顺序的,这样这些doclist也可以再次使用跳表结构

其中section级别的跳表有1级,doclist级别的跳表有2级

 

struct qsrchSEGItem {
    uint32_t _M_offset;
    uint32_t _M_size;
    // 当前segment最小docid
    uint32_t _M_skipdoc;         
};
struct qsrchDOCHead {
    uint64_t _M_basedoc:32;
    // 当前section最小docid
    uint64_t _M_skipdoc:32; 
    …
}

1、首先倒排列表被分配到多个sectiont中,每个section默认8192个倒排id,如果倒排id有10000个那么这个倒排列表被分配到2个sectiont中

2、sectiont之间是和sectiont内部的doc是逆序排列的,也就是有序的,这样就可以形成跳表结构了

3、查询sectiont,每次查询先查询sectiont的最大id以及sectiont的size,如果目标在id-size之间,就定位了sectiont

4、在sectiont内部查找目标,原理同查找section差不多

(3)查找顺序

查找的时候先把倒排拉链按照长短排序,先找用短的查找长的;而且在查找的时候一个doc查完才查另一个doc,例如

word1 :  1 3 5 6

word2 : 1 3 5 8 10 12

word3: 1 2 5 7 10 14 16 18

先把word按照查找倒排长短排序,短的在前,然后word1中先用1查找word2中的1,找到以后再查找word3中的1,如果都查找到则这个docid 1为有效docid。

然后word1中用3查找word2中的3,找到以后再找word3中的3,发现没有找到那么docid3 不是有效id

(4)索引压缩

索引压缩的基本单位是section,索引压缩的主要用途是为了减少磁盘io操作,否则磁盘占用的块会比较多,比较消耗io

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章