最近一直在做索引压缩方面的事情,无意中看到了Jeff Dean大牛分享的google早期的索引结构,对于我们这种刚刚起步的搜索公司,还是很有启发意义的,收获还是比较大,所以就简单记录下。
淘宝的一篇技术blog分享了一些比较常用的压缩算法:
关于这些算法的相关介绍可以看下www.wikipedia.org,或者搜下对应的paper.
可以看到,对于token的doclist是以Block的方式进行组织的,如果doclist比较长,还会使用skip table来快速查找;
Block的组织方式:
a. block header: 使用变长存储与上一个block的delta, 并存储block 实际的存储长度(可能是作为验证)
b. 第二行使用Gamma来压缩编码类型及在block中出现的docs的数目(因为这些数值都比较小)
c. 使用Rice压缩对应docld delta, 其实这里可以使用比较新的压缩算法PFDelta,更高效一些
d. 使用Gamma来压缩对应token在doc中出现的frequence, 即hit的数目
e. 使用length-limit Huffman 来存储Hit Attribute信息,这里主要是利用Attribute的重复的比例会很高,也就是说大部分hit attribute
都会是相同的,所以用到了Huffman压缩,然后对length进行了限制
f: positions用Huffman-Int 来压缩位置信息,由于position分布不确定性很多,对position的压缩一直是业界的难题,压缩比不会很高。
Huffman-Int : 类似于Gamma压缩,但是对于一元编码部分,使用了Huffman code.
优化
这里其实可以将doclist和hit 信息进行分离存储,因为只有在打分的时候才会用到hit的相关信息,访问次数会比较少,而doclist就会访问比较频繁
可以对其进行Cache,这样Cache命中率会更高一些