分布式搜索之索引分区

来源:互联网 发布:家庭网络需要交换机吗 编辑:程序博客网 时间:2024/04/30 07:33

转自:http://geek.renren.com/?tag=%E5%80%92%E6%8E%92%E7%B4%A2%E5%BC%95

  • 什么是倒排索引(Inverted Index) ?
是搜索引擎最核心的数据结构,通过对document里面的数据进行切词并建立term到document的反向映射,来达到根据用户的query来快速定位想要查找的document。为了方便理解大家可以假设这个结构是 SortedMap<term,SortedList<docId>>  (实际的倒排索引是一个多层映射的结构,就lucene而言,映射结构是:term->list<docid>,docid->list<position>,position->payload。同时也使用了很多压缩的手段来压紧每层结构)

  • 为什么要进行索引的分区(partition )?
随着数据量和请求量变得越来越大的时候,单机的容量和处理能力已经不能承受的时候,我们需要对索引进行切分。
  • 如何进行索引的切分?
partitioning by  terms : 通过将term划分成多个索引。假定我们的term都是英文的,这样所有的term都是a-z开头的,如果我们想切分成26份索引,很容易想到的就是把所有开头第一个字母(a-z)相同的term和对应的倒排列表放在一份索引里面。这样一个单一term查询只会落到一份索引上进行查询,可以带来更好的并发度。但是带来的问题就是数据很难均匀分布,每份索引的数据量很难保证大体相等,当然我们也可以通过预先统计好的数据来进行更平均的切片。最大的问题是我们的查询通常不是只有一个term,如果我们的查询包含多个term,我们就需要把这多个term对应的倒排列表通过网络传输到一个进程空间来进行合并,而有很多term对应的倒排列表非常长,这样会导致网络上的开销和本地的合并都是不可接受的
partitioning by document : 一种更普遍的做法是按照文档划分,每个节点包含某个文档子集的索引(比如按照id % N 或者按照id的range划分)。这样在一个索引中,一个term对应的倒排列表只是符合条件文档的一个子集。这样每次查询需要把查询分发到所有的索引节点上,在把结果呈现给用户之前进行来自不同节点结果的合并。该策略在降低节点之间的通讯量的同时增加了更多的本地磁盘的访问次数,而且需要处理全局idf的问题。   但是带来的好处是每份索引更加平均,而且每次查询都是是由多个索引节点并发计算来完成的,可以大大缩短查询时间。


原创粉丝点击