【深度】ES到底是如何对倒排索引进行速度和空间优化

ES的核心是倒排索引。

就是一个词term被什么文档所包含。

term -> documents(posting list)

这些数据存储在磁盘上。

以上是最基础的版本。

倒排索引虽然很快,但是空间消耗很大。

需要优化

  • 保证搜索速度更快(优势更明显)
  • 空间占用减小(缺点缩小)

ES的优化设计

ES对性能和空间节省做了大量的优化。

搜索速度优化

数据按规律排序存储

将全部数据按一定规则(Term的前缀)拆分到不同的磁盘Block中。

使用一种快速算法可以快速定位到这个term所在的磁盘Block。

这种算法就是FST(Finite State Transducers)。

将所有Term做成FST(实际是取到能区分磁盘Block的前缀部分即可)

磁盘空间优化
Term Dictionary的磁盘空间优化

由于Term词典是采用前缀规律组织起来的,因此,一个Block内的Term一定有一段相同的前缀

Term词典只需要存储差异化的后缀即可,从而节省存储空间。

Posting Lists (文档ID)的磁盘空间优化

采用整形数id

这个文档ID和ES索引里的唯一_id 不一样。

ES索引里的_id可以是string类型,压缩率不高。

(segment是存储文档的最小组织单元,可以存储2^32个文档。里面的id是唯一的整形数id。以便于被高效压缩)

id采用delta-encoding编码

  1. id是排序的。
  2. 采用增量编码(delta-encoding)对id的存储空间进行压缩。

原输入[id1, id2, id3...]

delta-encodinig: [id1, id2-id1, id3-id2]

由于是相对值,实际每个值会相比原来更小(例如,如果所有值都小于255,则每个只需要1个字节进行存储。原来 4 bytes * len(list) -> 现在 1 byte * len(list))

3 Frame of Reference

上面可以发现,如果一个相对值比较大(瓶颈),则会导致整体都必须按这个最大值的类型进行存储。

这里采用分而治之,减少这种瓶颈带来的波及。

将所有id分为多个block,每个block最大256个ids。

计算每个block最大需要多少bit来存储,将这个值写到block的开头(这个header采用1个字节存储即可)

相比只用delta-encoding,delta值(相对值)从字节(Byte)单位精细到比特(Bit)单位。

整体流程

从优化前的24字节降为仅需7字节。

参考:Frame of Reference and Roaring Bitmaps | Elastic Blog

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值