这篇文章主要讲的是对海量互联网数据建立分布式索引的一些注意的问题和解决方案,涉及到服务器的物理架构、倒排索引的具体结构以及各个索引服务器之间的通信之间的问题。
文章主要有三个创新的地方:
当然,之前还有大段的文字从互联网数据的规模、增长速度和变化频率论证了建立索引的时间对整个搜索过程有着重要的影响。另外,还交代了作者进行试验的一些服务器物理架构特点和以及索引文件的分布式组织,其中索引文件的组织作者采用的策略是每个请求server负责一部分子文档集合(local inverted files),也就是说每个server有一个词典,而不是所有server共用一个词典(global inverted files)。实验服务器的架构如图:
1.流水线技术
这里主要是讲建立索引的过程分为三个步骤:loading,processing,flushing。其中读入的就是爬虫爬来的一大堆存在硬盘上的网页文件,而处理又包括两个过程:分词和排序,分词用于生成单词加文档标识和位置等信息的结构(postings),排序是对上一步得到的单词进行派讯,这部分是在内存中完成的,最后是将postings写回到硬盘上。
采用流水线最好的地方显而易见:高并发,分成三块理论上可以达到3倍的效率,实际改善会收到时间消耗最大的那部分的操作的影响。另外,在采取最简化的模型分析中(单CPU、单磁盘、单网络连接),作者用数学的方法证明了流水线技术的改善情况和读入写回的缓存大小有关,并对此进行了实验。下面两个图分别为流水线模型和缓存大小和索引建立时间的关系。
流水线技术一个不足的地方是,同样的缓存下,采用流水线技术产生的postings的大小是不用的情况下的1/3,这样在第二个建立索引的第二个阶段,就需要花更多的时间来进行merging,好在这个多出来的成本要小于流水线技术带来的收益。下表是改善情况:
2.索引的存储模型
这部分作者使用了一个小型的实验数据库Berkeley DB,用其来存储索引文件,而Berkeley DB提供了很多数据访问的编程接口,其主要内部结构是键值对,而且无论键值都支持无限长度,所以通常把单词和其所有的反向链表都存储在键值对中。Berkeley DB提供了包括B树和线性哈希表的在内的四种访问方式,在这个试验中作者采用了B树的访问方式,因为其支持前缀搜索并且和哈希表相比,有更强的局部性。对于存储模型有三种方式:
其中单负载的情况比较极端,一看就是作比较用的,而第一种和第三种则各有利弊,作者的在试验中证明第三种较好,第一种和第三种的图示如下:
接下来作者从索引大小、求交速度和更新速度三个方面对比了这三种存储方式。
Scheme Index size Zig-zag joins Hot updates
single payload −− + +
full list +− − −
mixed list +− +− +−
虽然单负载看上去很美好,但是显然造成了很大的空间的浪费,而混合模式在这三种情况表现都不错,其中索引大小方面主要得益于其每个键值对的值的长度都差不多相同,不会产生full list中一个过长一个过短的情况。而求交对出现次数较多的一些词有帮助,因为其可能存放在多个键值对中,于是可以不从第一个开始找起。而更新的消耗是有值的长度决定的,所以混合模式同样表现不错。三种情况下的空间消耗如图:
但是,这里我有两点疑问:1.老实讲,我觉得这种结构带来的效果不明显,因为这种只能存储后续单词包括前续单词的情况,比如cat catch catcher,但是这种数目很少,而更多的相同前缀用这种结构不能实现比如:construct、confident、conflict、contribute,明显后者的出现情况大于前者,所以可以采取树的形式利用前缀2.为什么要说明前缀的长度?很明显,下一个词的前缀长度就是之前的所有前缀长度之和。
3.全局数据收集
这部分的内容比较简单,作者的主要意思是使用一个单独的服务器,专门负责在index服务器建立索引阶段收集每部分的数据然后整合成一个全局的数据,再分发给每一个index服务器。当然,这里作者进行了一个引申的讨论,就是这个收集数据额过程是在merge过程(第二部分)还是在flush(第三部分)做比较好呢?
最后,考虑到merge过程中收集数据会造成同步的问题阻塞线程,所以建议采用第二种方案,但是我看了这部分就觉得,这个很好处理啊,直接把同步的操作异步化就OK了啊,果然,作者接下来就提出了改善第一个方案的方法,就是用缓存来将同步的传数据操作异步化,这样即不会阻塞,也避免了在flush阶段传数据操作的IO消耗。
最后作者还进行了一个总结:数据收集的消耗比例随着文本数目的增多而下降是因为词数是文本数的次线性增长,而建立索引的消耗和文本数对数相关,所以数据收集的时间和建立索引的时间次线性相关。
这篇文章看下来收获还是蛮大的,对接下来学习lucene的倒排索引结构应该也有所帮助。