SIndex: A Scalable Learned Index for String Keys
—— 一种针对字符串的可计量学习索引
(上海交通大学 并行和分布式系统研究所)
基于当前学习索引研究热点聚焦在数字key 的查询,而不能有效执行变长字符串索引,论文团队提出了SIndex,一种针对变长字符串的并发学习索引。技术的核心是字符串分组内使用共享前缀,并使用各个关键独特的部分进行模型训练。通过在现实世界和综合数据集上的评估,结果显示SIndex 可以比其他索引结构高出91% 的性能。
随着变长字符串长度的增加,算术运算和内存访问的“挑战性”会逐步增加,此外,模型的精度还有下降的趋势,这会引发更多次的数据访问。一个直观的解决方案就是使用深度神经网络来提升位置预测精度,以期减小数据的访问次数。然而,这种方法的使用开销巨大…
受到现有字符串索引的启发,SIndex 利用共同前缀来提升查找效率。特别地,SIndex 使用公有前缀贪心地将key 聚类分组。然后,在每个组中,SIndex 使用每个key 独特的部分作为特征进行模型训练。
论文有三点贡献:
- 提出了支持变长字符串的学习索引
- 这种创新的学习索引在效率上有保证
- 在现实数据集中得到了验证
下图展示了XIndex 和MassTree 在变长字符串下只读(1a)和读写(1b)情况下的性能对比:
有三点原因导致了性能下降:
- 随着字符串长度的增加,模型耗费显著增加。即使是线性模型,128byte 时候的时间消耗也是8byte 时候时间消耗的23 倍
- 模型的误差也随着字符串的增加而增加,从8byte 到128 byte,平均误差从24 增长到68,意味着在预测pos 之后,还需要多增加访问次数才能访问到真正想要访问的数据
- 在字符串索引下,二分查找的时间开销也随着字串的增长而增加,这是因为字符串比较开销很大程度上源自字符串的长度
总结一下,字符串索引的关键挑战在于变长度,它决定了模型的特征大小和字节间的比较次数。团队最关键的insight 在于一些比较和计算是没必要的,在很多情况下,字串中的子串可以有效地标识这个字串,这可以大大提升字串索引的效率。
SIndex 的结构
和XIndex 相似,SIndex 也是采用了两层设计。顶层是根节点设计,底层是若干组节点。每个组存储着特定范围内的记录,要么是以有序数组存储,要么是以线性模型存储,亦或者是由于插入而引入的delta index。如果delta index 的大小超过了用户设定的阈值,SIndex 执行压缩。
SIndex 专门为字符串索引采用了三种重要的设计策略:
- SIndex 使用部分key 减小模型构建消耗和比较消耗
- SIndex 利用贪心分组策略适应性地将key 分到不同组里
- SIndex 在根节点中使用线性模型(而不是RMI 模型)来索引分组
下面介绍算法的三个核心:
1. Partial Key
在每个组里面,SIndex 会抽取子串进行模型训练计算和比较(这些子串长度是最短的,同时长度也是固定的)
- 剥离公共前缀
- 保留最具有区分效应的子串以保持string index 原有的顺序
下面是辨识出Partial Key 的算法:
SIndex 从Partial Key 可以获得两点好处:
- 简化计算(特征向量较短)
- 二分搜索的开销减小(比较次数减少)
2. Greedy Grouping
SIndex 通过贪心分组保证key 的长度和模型误差在可控范围内。贪心分组算法如下:
3. 根节点的线性模型
SIndex 在根节点使用分段线性模型来索引组节点。每个线性模型对不重叠范围内的key 做索引。在训练阶段,这些线性模型使用组枢纽作为数据进行训练。SIndex 使用相同的贪心分组算法决定把哪个组枢纽分给哪个模型。然后他在每个模型里面应用Partial Key。在交互阶段,SIndex 使用二分搜索查找适合该查询的线性模型。
4. 优化
为了加速模型交互性能,SIndex 利用SIMD 指令集加速模型计算。
下面是关于SIndex 的一些评估
- 实现:使用C++ 实现,将类似于前缀长度和有效长度当作组元数据存储
- 数据集:
- One comprises synthetic datasets where all keys are randomly generated, denote as “R[key length]-[dataset size]”
- The other is a real-world dataset containing 92M URLs of quotes from Memetracker [14]. The maximum length of URLs is 128 bytes and the average length is 62 bytes.
- 参照:和XIndex、Mass-tree、Wormhole 对比
- 接着说了一些参数和硬件配置
总体表现
在这个部分,团队测定了在只读和读写负载两种情况下的性能。
只读情况:
- 在随机数据集上,SIndex 比XIndex、Masstree 和Wormhole 索引的性能好。
- 在URL 数据集上,SIndex 比XIndex、Masstree 性能好,但是比Wormhole 性能要差些。(URL 数据类型有着相对复杂的数据分布,导致了较大的偏差;且所需要的Partial Key 较长,这也是开销的一大来源)
读写负载
- 写包括insert、update 和delete(比例:2:1:1),团队测试了在不同读写比情况下SIndex 的性能
- 图6 显示了在90: 10 的读写负载的情况下,各种方法吞吐量随着线程数增加的变化,SIndex 比XIndex 的性能好,但是比Wormhole 和Masstree 的性能要差。这可能是压缩过程对于合并delta index 来说还不够快。
- 图7 显示了SIndex 展示了良好的拓展性(因为无需执行压缩)
性能细分(拆解各个设计策略对性能的优化程度)
- 图8 可视化了SIndex 各个步骤把性能提升上来的效果
下面是已有的一些相关工作
- 学习索引的一些相关工作,例如PGM-Index、FITing-Tree、ALEX 等,可网络搜索中科院软件所的一篇综述类文章《学习索引:现状与研究展望》
- 传统索引:B+ 树、Trie 树等
本论文提出了SIndex——一种应用于字符串索引的支持并发的学习索引。为了解决传统字符串学习索引带来的问题,团队提出三点创新设计:
- partial keys for reducing the cost of model inference and data access
- a greedy grouping strategy for limiting the length of partial keys in each group
- a piecewise linear model for the root for reusing the partial key and the greedy grouping strategy
评估结果表明SIndex 在综合现实数据集上使用字串索引时能保持良好性能。
代码开源在https://ipads.se.sjtu.edu.cn:1312/opensource/xindex/-/tree/sindex 上。