sphinx2.0.1搜索引擎的学习研究与索引结构的修改

来源:互联网 发布:搜索软件下载安装 编辑:程序博客网 时间:2024/05/16 07:42

           转载或引用此文,请务必注明出处,谢谢!


           经过半年时间的学习研究,完成了sphinx 2.0.1版本源代码的阅读分析,并根据工作的需要,对这个版本进行了修改。


           sphinx的倒排索引采用了紧凑的磁盘存储方式,由于应用环境的特殊,docid是非连续的,其使用过程中我们对它的速度并不满意,其并发和单次查询时间在倒排列表较大的情况下,无论使用进程模式或是线程模式,都不能满足要求,为此才产生了修改其所索引结构的想法。   


            sphinx的倒排列表存放于spd文件,docid以增量压缩的方式存储,在源码分析过程中,可以看到为了对查询树进行query_node(查询词)间的"与"、"或"运算,sphinx采用了多层调用,多路归并的方法来完成,这个过程中,为了找到符合某属性条件的docid,会进行docid->属性之间的二分查找(查询spa文件的hash索引,该索引在系统启动时创建),当查询节点较多,要求返回结果较大的情况下,二分查找带来的时间消耗是“巨大”的。


           spa文件粗略来说是docid+属性,docid采用递增方式存储,ATTR_NUM0(docid+属性) + ATTR_NUM1(...)  + ....,我们注意到spd中每个词的docid倒排列表,也是使用增量方式存储的,二者存在着共性,因此产生了以ATTR_NUMx来替代docid的思路,由于spa文件的每个docid属性节点大小固定,因此在系统启动时被加载到固定大小的数组中。在查询时,取得ATTR_NUMx就意味着直接取到了属性字段,省去了二分查找带来的巨大时间消耗。


            为此需要对sphinx的索引创建模块indexer进行修改,在写docid倒排列表时,先取到每个docid在spa文件中的ATTR_NUM存放到一个AVL树中(key为docid,值为ATTR_NUM,这颗树在索引完成后销毁),当在写spd文件的docid时,通过docid查询出ATTR_NUM,将ATTR_NUM以增量方式写入。


            虽然这里只是一种很小的改动,但这种改动却带来了较大的性能提升。

      

            在这个改动的过程中,有一个隐蔽的问题,就是spd文件中标示每个倒排列表结束的0,在检索过程解压倒排列表的时候,当遇到0时既标示倒排列表结束。也就是0在这里有特殊的含义。我们通过查看spd的文件结构知道,spd在写入倒排列表前,会在文件的最开始写入一个无用的占位字节,它的目的就是为了防止出现偏移为0这类问题,而spa文件它从第一个字节起就是有实际意义的,所以,很可能会出现docid差值为0的情况,解决这个问题,比较简单,只需要在写入ATTR_NUM增量时做一个+1操作,在检索过程中,先判断是否是遇到0,当不是0的情况下,将这个获取到的ATTR_NUM再减1,以此来解决这个隐蔽的问题。

 

           还有一些较大的索引结构修改与工作内容有关,不便在此讨论,但欢迎交流。

         

          另有一个搜索引擎技术方面的交流群:107868420 欢迎加入!