倒排列表压缩算法汇总——分区Elias-Fano编码貌似是最牛叉的啊!

来看看倒排索引压缩。压缩是拿CPU换IO的最重要手段之一,不论索引是放在硬盘还是内存中。索引压缩的算法有几十种,跟文本压缩不同,索引压缩算法不仅仅需要考虑压缩率,更要考虑压缩和解压性能,否则会解压太慢而起不到CPU换IO的作用。早期的索引设计里,在尝试了几十种编码之后,基本都确定性采用差分编码+可变长字节编码。差分的目的在于让索引的文档ID尽可能小,因为压缩小的整数总是比大整数更有效。在索引构建算法中,有一类工作叫做“文档重排”,目的就是通过对文档索引顺序的重新排列,使得索引posting list中的文档ID之差最小,这样就可以让压缩算法更有效的工作,从而使得索引总体积最小。当然这样的工作在实际中价值有限,因为索引的构建速度以及增量构建同样非常重要,耗费大量时间在文档重排上,对于静态数据集合才更加有效。可变长字节编码大概是最早的索引压缩编码,思路简单到无以复加的地步——每个字节的第一位为flag,表示是否继续使用下一个byte,剩下7位为有效位,所有的有效位组成数字的2进制表示。但是它却非常有效,因为解压速度非常快。采用差分和可变长组合手段,假定文档ID采用32位整数,那么索引体积基本上可以压缩到之前的1/2到1/4之间。这种压缩手段占据了主流,几乎所有的开源搜索(Lucene,Sphinx),商业搜索都采用这种方式进行,Google则引入了Group可变长字节编码,以4个整数为一组进行压缩,这样压缩率更高。我们可以找到阿里实现的Group可变长字节编码的实现,因此很可能淘宝商品搜索也采用了这种方式。

大约2007年开始,一种名为PForDelta的索引压缩算法开始引起更多人的重视,这是一种压缩率更高并且解压速度更快的算法。有研究表明,索引压缩的过程中相邻文档ID差值为1的情况大约占10%,而PForDelta算法对小差值的情况,特别有优势。假定一个索引块为8个值(已经做过差分),80%的情况下值小于32,小于32的值均可以用一个b = 5bit的数来表示。建立这样一个结构:8*b-bit的常规部分,看作是一个位数组,每个元素占b-bit定长空间,余下的为异常部分,看作是一个整形数组,每个元素占4字节定长空间。假定有这样一个序列:23, 41, 8, 12, 30, 68, 18, 45,通过PForDelta方法的构造得到如下压缩结构:

椭圆框所示的部分为常规部分,常规部分的第一个值1,表示从该地址开始,跳过1个地址,就可以找到下一个异常值的位置,同理第三个值3表示,跳过3个地址,就是下一个异常值的位置。常规值从前到后存储,异常值从后向前存储。PForDelta压缩是基于块来进行,目前常用的选择是128。把处理异常值的方式做改进,采用可变长字节或者其他算法(目前最先进的是S9或者S16)压缩,就是改进型的NewPFor和OptPFor压缩算法。

PForDelta及其系列改进从07年发明以来已经逐渐成熟,后边的工程实践中引入了SSE指令加速,使得解压速度可以更快。一些主流商业搜索引擎已经广泛采用,也包含上面提到的淘宝商品搜索。然而,技术革新的步伐并没有停止。PForDelta这一族算法,压缩是按照区块来进行的,这意味着如果希望仅仅访问其中某一个元素,那么需要把整个区块进行解压。有时候我们并不希望总是全部解压,从而可以做到对压缩数字的随机读取。在2012年的时候,出现了Quasi-succinct索引。它可以提供元素的随机访问而不需要全部解压。注意这里又出现了succinct字样,是因为该索引对于压缩接近信息熵的下界,这符合succinct的定义。Quasi-succinct索引的性能跟最好的区块压缩算法压缩解压性能基本一致,采用的是Elias-Fano编码,但是压缩率缺却并不高,因此会导致索引体积膨胀——尽管如此,索引所占的体积仍然少于常规的可变长字节编码。Elias-Fano编码针对随机元素的解压非常快速,但是如果需要解压全部元素,它的速度还是不能最先进的批量解压算法例如NewPFor和OptPFor快。

Elias-Fano编码过程如下:把一组整数的最低l位连接在一起,同时把高位以严格单调增的排序划分为桶。用0表示桶的存在,用1表示桶里的元素,有多少元素就有多少个1。

图中的序列为2,3,5,7,11,13,24,如果期望定位大于6的位置,那么根据6/2^2就可以定位到大于6的桶,然后在桶内线性扫描即可。可以看到,低l位的存在,就是起到了桶定位的用途,从而避免全部解压,这可以类比于常规索引中的跳跃表,跳跃间隔为2^l。

Quasi-succinct索引在MG4J的开源搜索引擎中得到了应用,MG4J是个人认为的Java版本的开源搜索引擎中最具备研究和学习价值的,不仅仅在于高于Lucene的代码质量,更在于对于数据结构与算法孜孜不倦的创新。当然,由于不善宣传,出自学校而并没有吸引更多的开发人员加入社区,
知晓并愿意改进MG4J的人寥寥无几,这跟Lucene形成了鲜明的对比。因此,即便在技术领域,先进性也往往让步于宣传。

Partitioned(分区块) Elias-Fano编码,这篇文章获得了2014年SIGIR会议最佳论文,它是针对Elias-Fano编码进行的改进。仍然由Quasi-succinct的作者提出,主要解决Quasi-succinct索引的压缩率问题——回归区块压缩手段,把数字序列划分区块,每个区块内单独用Elias-Fano编码,同时,为了确保仍然具备随机访问的特性,把区块的边界数字再次单独拿Elias-Fano编码压缩,因此形成了一个二级结构。根据作者的试验,分区Elias-Fano编码比最快的PForDelta编码OptPFor速度和压缩率上均有超越,但压缩率大大超过后者(2倍以上)。因此,在随机访问,压缩率,解压性能上达到了很强的综合性能,荣膺最佳论文实至名归。

创新依然在继续,自从SSE加速指令引入到PForDelta的实现之后,针对SIMD指令如何设计良好的压缩算法也成为工程和学术的研究重点。亚马逊旗下搜索引擎A9.com就曾经提出了针对SIMD加速的可变长字节编码实现,而在2013年底,加拿大LICEF研究中心的Lemire提出了基于SIMD bitpacking的压缩编码SIMD-BP128,其解压速度是迄今为止最快的,超过OptPFor的2倍(一秒钟可以解压10亿整数),当然在压缩率上并没有达到高指标。

压缩可以说是索引设计中的第一考虑要素,盘点上面的列表,NewPFor,OptPFor,Quasi-succinct(Elias-Fano),Partitioned Elias-Fano,SIMD-BP128,都是业界最先进的选择,设计时需要根据自己的要求做出取舍。

转自:http://chuansong.me/n/2035211

时间: 2024-10-22 18:47:55

倒排列表压缩算法汇总——分区Elias-Fano编码貌似是最牛叉的啊!的相关文章

这就是搜索引擎--读书笔记七--倒排列表压缩算法

倒排列表压缩算法 目前有很多种倒排列表算法可以选择,但是我们对评判算法的优劣需要定量指标.一般会考虑3个指标:压缩率.压缩速度以及解压速度. 压缩率是指数据压缩前和压缩后大小的比例,显然,压缩率越高,就越节约磁盘空间.而压缩速度是压缩单位量的数据所花的时间,但是压缩往往是在建立索引过程中进行的,这是一个后台进行的过程,不需要及时响应用户查询,即使速度慢一些也没有关系.所以普遍来说,压缩速度不是一个重要指标. 那么我们来看看解压速度.顾名思义,解压就是将压缩数据恢复到原始数据.这是一个实时响应过程

搜索引擎基础概念(3)—— 倒排列表

倒排列表 倒排列表用来记录有哪些文档包含了某个单词.一般在文档集合里会有很多文档包含某个单词,每个文档 会记录文档编号(DocID),单词在这个文档中出现的次数(TF)及单词在文档中哪些位置出现过等信息,这样与一个文档相关的信息被称做倒排索引项(Posting),包含这个单词的一 系列倒排索引项形成了列表结构,这就是某个单词对应的倒排列表.图 1-1 是倒排列表的示意图,在文档集合中出现过的所有单词及其对应的倒排列表组成了倒排索引. 图1-1 倒排列表示意图 在实际的搜索引擎系统中,并不存储倒排

倒排表压缩算法

倒排表内存放的都是整型数字,所以对倒排表的压缩其实就是对数字的压缩.而二进制数字都是存储在long(8byte) ,int(4byte),short(2byte)类型里面,这种存储方式最大的弊端就是每个数字不管大小消耗的空间都是等价的,比如int的1和int的100000000都是4个字节,而数字1其实仅仅用到了一个字节,其他3个字节的空间纯属浪费.倒排表压缩的核心思路就是在这些没用到的字节上做文章. 整型压缩分为两种方式,一种是以byte为最小单位压缩,一种是以bit为最小单位压缩. 基于by

倒排列表求交集算法汇总

http://bbs.sjtu.edu.cn/bbstcon,board,Algorithm,reid,1225812893.html 我总结了一下,归纳如下: 1.1 SvS and Swapping SvS Algorithm 1 Pseudo-code for SvS SvS(set, k) 1: Sort the sets by size (|set[0]| ≤ |set[1]| ≤ . . . ≤ |set[k]|). 2: Let the smallest set s[0] be t

ES里设置索引中倒排列表仅仅存文档ID

index_options The index_options parameter controls what information is added to the inverted index, for search and highlighting purposes. It accepts the following settings: docs Only the doc number is indexed. Can answer the question Does this term e

Poseidon 系统是一个日志搜索平台——认证看链接ppt,本质是索引的倒排列表和原始日志数据都存在HDFS,而文档和倒排的元数据都在NOSQL里,同时针对单个filed都使用了独立索引,使用MR来索引和搜索

Poseidon 系统是一个日志搜索平台,可以在百万亿条.100PB 大小的日志数据中快速分析和检索.360 公司是一个安全公司,在追踪 APT(高级持续威胁)事件,经常需要在海量的历史日志数据中检索某些信息,例如某个恶意样本在某个时间段内的活动情况.在 Poseidon 系统出现之前,都是写 Map/Reduce 计算任务在 Hadoop 集群中做计算,一次任务所需的计算时间从数小时到数天不等,大大制约了 APT 事件的追踪效率.Poseidon 系统就是解决这个需求,能在数百万亿条规模的数据

倒排列表求交集算法 包括baeza yates的交集算法

#ifndef __INTERSECT_HPP__ #define __INTERSECT_HPP__ #include "probe.hpp" namespace themas { /* * like stl's set_intersect */ template<class InputIterator, class OutputIterator> void linear_intersect(InputIterator begin1, InputIterator end1

Lucene 4.X 倒排索引原理与实现: (2) 倒排表的格式设计

1. 定长编码 最容易想到的方式就是常用的普通二进制编码,每个数值占用的长度相同,都占用最大的数值所占用的位数,如图所示. 这里有一个文档ID列表,254,507,756,1007,如果按照二进制定长编码,需要按照最大值1007所占用的位数10位进行编码,每个数字都占用10位. 和词典的格式设计中顺序列表方式遇到的问题一样,首先的问题就是空间的浪费,本来254这个数值8位就能表示,非得也用上10位.另外一个问题是随着索引文档的增多,谁也不知道最长需要多少位才够用. 2. 差值(D-gap)编码

关于信息检索-倒排文件系统架构解析

信息检索 信息检索我们常见的模型包括: bool model static langulage model vector space model 这里面主要涉及到的问题就是:query expresion,term correlation analysis,similarity computing,feature selection.那么对于similarity computing 阶段,主要的制约条件是内存限制,所以我们要改进term在document中的搜索时间,从而减少similarity