sat培训中心Elasticarch之数据压缩算法
1、term index的压缩
Lucene使⽤FST算法以字节的⽅式来存储所有的Term,重复利⽤Term Index的前缀和后缀,使Term Index⼩到可以放进内存,减少存储空间,不过相对的也会占⽤更多的cpu资源。FST在Lucene4.0以后的版本中⽤于快速定位所查单词在字典中的位置。
Finite StateTransducers,简称 FST,通常中⽂译作有穷状态转换器,在语⾳识别和⾃然语⾔搜索、处理等⽅向被⼴泛应⽤。
FST的功能类似于字典,可以表⽰成FST<Key, Value>的形式。其最⼤的特点是,可以⽤O(length(key))的复杂度来找到key对应的value,也就是说查找复杂度仅取决于所查找的key长度。
假设我们现在要将以下term index映射到term dictionary的block序号:
“cat” —— > 5
“deep” —— > 10
“do” —— > 15
pregnant
“dog” —— > 2
“dogs” —— > 8
最简单的做法就是定义个Map<string, integer="">,⼤家找到⾃⼰的位置对应⼊座就好了,但从内存占⽤少的⾓度想想,有没有更优的办法呢?答案就是FST。
good guy对于经典FST算法来说,要求Key必须按字典序从⼩到⼤加⼊到FST中。上⾯的例⼦中key已经排好序了。
按照以下步骤建⽴FST:
1.建⼀个空节点,表⽰FST的⼊⼝,所有的Key都从这个⼊⼝开始。
2.如果还有未处理的Key,则枚举Key的每⼀个label。处理流程如下:
2.1如果当前节点存在含此label的边,则
cha cha2.1.1如果Value包含该边的out值,则
Value = Value – out
2.1.2否则
神探夏洛克字幕令temp=out–Value;
out =Value,并使下⼀个节点的所有边out都加上temp。
如果下⼀节点是Final节点 则FinalOut += temp
2.1.3进⼊下⼀个节点
2.2否则: 新建⼀个节点另其out = Value, Value = 0。
好习惯伴我成长
外套英语最后加⼊dogs,得到最后的结果:让杜雅尔丹
从上图可以看出,每条边有两条属性,⼀个表⽰label(key的元素),另⼀个表⽰Value(out)。注意Value不⼀定是数字,还可⼀是另⼀个字符串,但要求Value必须满⾜叠加性,如这⾥的正整数2 + 8 = 10。字符串的叠加⾏为: aa + b = aab。
建完这个图之后,我们就可以很容易的查找出任意⼀个key的Value了。例如:查找dog,我们查找的
路径为:0 → 4 → 8 → 9。 其权值和为:2 + 0 + 0 + 0 = 2。其中最后⼀个零表⽰ node[9].finalOut = 0。所以“dog”的Value为2。
2、posting list的压缩
2.1 Frame Of Reference
Lucene除了上⾯说到⽤FST压缩term index外,对posting list也会进⾏压缩。
我爱你英文有⼈可能会有疑问:“posting list不是已经只存储⽂档id了吗?还需要压缩吗?”。设想这样⼀种情况,Lucene需要对⼀千万个同学的性别进⾏索引,⽽世界上只有男/⼥这样两个性别,每个posting list都会有数百万个⽂档id,这⾥显然有很⼤的压缩空间与价值,对于减少索引尺⼨有⾮常重要的意义。
Lucene使⽤Frame Of Reference编码来实现对posting list压缩,其思路简单来说就是:增量编码压缩,将⼤数变⼩数,按字节存储。韩国语在线翻译
⽰意图如下:
6.png