#学习索引ALEX

本文介绍了ALEX,一种可动态更新的自适应学习索引,通过机器学习模型优化查询性能,尤其在只读和读写工作负载中表现出色。文章详细阐述了其优势、创新点、算法和应用场景,展示了学习索引在高效数据处理中的潜力。
摘要由CSDN通过智能技术生成

ALEX:An Updatable Adaptive Learned Index

写在前面

因为毕设论题,以及对数据处理的兴趣,开始学习学习索引,记录学习过程🌹😀。

前言

接触到的第一篇文章就是ALEX,即可更新的自适应学习索引。那么Trace the origin:学习索引是什么?索引就是一个模型,一个键值对模型。B+ Tree、哈希索引、BitMap索引都是键值对的映射,就是y=f(x),确定f模型。模型可以学习查找键 (Key) 的排序顺序或结构,并使用这个信息来有效地预测值记录 (Value) 的位置或存在。也就是说用模型代替索引结构的思想。最初的文章The Case for Learned Index Structures认为,当数据分布本身存在一定规律的时候, 就可以利用已有的规律进行检索, 而不用通用数据结构。学习型索引将索引结构看作模型, 将传统树型结构的页面大小看做是机器学习模型的最大误差, 只要使得模型的预测误差小于页面大小就等于保证了查询精度。见下图B树与学习索引。
在这里插入图片描述

一、ALEX的优势是什么?

ALEX是一个完全动态的数据结构,它采用间隙数组、数组扩容等方式,解决单点查询、短范围查询、插入、更新和删除的工作负载实现学习索引时出现的实际问题,能够实现高性能和低内存占用。它在只读工作负载上,ALEX在性能上比Kraska等人的学习索引高出2.2倍,索引大小减少了15倍。在读写工作负载的范围内,ALEX比B+Tree高出4.1倍,而性能从未更差,索引大小减少了2000倍。

二、创新

The Case for Learned Index Structures中提出了一个模型,我们将其称为“学习索引”。Kraska等人提出用机器学习(ML)模型的层次结构取代标准数据库索引。给定一个键,层次结构中的中间节点是用于预测要使用的子模型的模型,而该层次结构中的叶节点是用于预测键在密集排列数组中的位置的模型(图1)。该学习索引的模型是从数据中训练的。他们的关键见解是,使用(即使是简单的)适应数据分布的模型来对键的实际位置做出“足够好”的猜测,从而显著提高性能。但是,他们的解决方案只能处理对只读数据的查找,不支持更新操作。
在这里插入图片描述

  • 针对模型优化的存储布局:类似于B+Tree,ALEX构建了一个树,但允许不同节点以不同的速率增长和收缩。为了在数据节点中存储记录,ALEX使用了一个带间隙的数组,一个间隙数组,它(1)平摊每次插入移动键的成本,因为间隙可以吸收插入;(2)使用基于模型的插入允许更准确地放置数据,以确保记录尽可能靠近预测位置。为了高效搜索,空白实际上是由相邻的键填充的。
  • 针对模型优化的搜索策略:ALEX利用基于模型的插入与从预测位置开始的指数搜索相结合。当模型准确时,这总是胜过二分搜索。
  • 通过动态数据分布和工作负载保持模型的准确性:即使在数据分布倾斜或索引初始化后发生动态变化时,ALEX也提供了健壮的性能。ALEX通过利用自适应扩展和节点分裂机制,以及基于简单成本模型的智能策略触发的选择性模型再训练来实现这一目标。我们的成本模型考虑了实际的工作量,因此可以有效地响应工作量的动态变化。ALEX实现了上述所有优点,而无需为每个数据集或工作负载手动调整参数。

三、ALEX概述

ALEX是一个内存中可更新的学习索引,其任何操作都由遍历到数据节点(也就是叶节点),然后由节点内操作组成,所以RMI成本是通过结合外遍历和内节点模型来构造的,如下图所示。
在这里插入图片描述

首先,与B+Tree一样,ALEX对每个叶子使用一个节点。这允许单个节点更灵活地扩展和分割,也限制了插入期间所需的移位数量。在一个典型的B+Tree中,每个叶节点存储一组键和有效载荷,并在数组的末尾有“空闲空间”来吸收插入。ALEX使用了类似的设计,但更仔细地选择了如何使用自由空间,它支持叶节点的间隙阵列数组布局,不仅可以很快生成可更新的数据结构,而且查找也会更快。UALI使用指数搜索在叶节点层上找到键,以纠正RMI的错误预测,然后将键插入到模型预测键应该插入的位置的数据节点中。
其次,学习索引仅支持静态递归模型索引(static recursive model index,SRMI),其中SRMI的层级数量和模型数量在初始化时是固定的。如果数据分布难以建模,则其会在插入时表现不佳。ALE可在运行时动态、高效地调整RMI结构,并使用线性成本模型,该模型基于从RMI中测得的简单统计数据预测查找和插入操作的延迟。ALEX使用这些成本模型来初始化RMI结构,并根据工作负载动态地调整RMI结构。该内存学习索引可以用于动态工作负载,将学习索引的核心见解与经过验证的存储和索引技术相结合,从而在时间和空间上提供良好的性能。

四、ALEX算法

4.1Lookups and Range Queries(查找和范围查询)

为了查找一个键,从RMI的根节点开始,我们迭代地使用模型来“计算”指针数组中的一个位置,然后我们跟随指针到下一级的子节点,直到我们到达一个数据节点。我们利用模型在数据节点中预测搜索键在键数组中的位置,如果需要的话进行指数搜索,找到键的实际位置.如果找到key,我们从payloads数组中读取相同位置的相应值并返回记录。否则,我们返回一个空记录。范围查询首先执行查找以找到其值不小于范围的开始值的第一个键的位置和数据节点,然后向前扫描直到到达范围的结束值,使用节点的位图跳过间隙,并且如果必要的话使用存储在节点中的指针跳转到下一个数据节点。

4.2Insert(插入)

由于在数据节点上进行查找和插入,我们计算每次插入的指数搜索迭代和移位的次数。根据这些统计数据,我们使用节点内成本模型计算数据节点的经验成本。一旦数据节点满,我们将预期成本(在节点创建时计算)与经验成本进行比较。如果它们没有明显的偏离,那么我们得出模型仍然是准确的结论,我们执行节点扩展(如果扩展后的大小小于最大节点大小),缩放模型而不是再训练。为简单起见,ALEX总是将一个数据节点一分为二。数据节点可以在概念上分解为2的任意幂,但决定最优的扇形可能是耗时的,我们实验证明,在大多数情况下,根据成本模型,2的扇形是最好的。

4.2.1Insert in non-full Data Node(插入非完整数据节点)

在非完整数据节点中,为了找到新元素的插入位置,我们使用数据节点中的模型来预测插入位置。如果预测的位置不正确(如果在那里插入不会保持排序顺序),我们进行指数搜索以找到正确的插入位置。如果插入位置是一个间隙,那么我们将元素插入间隙中并完成。否则,我们通过在最近间隙的方向上将元素移动一个位置来在插入位置处形成间隙。然后我们将元素插入到新创建的间隙中。Gapped Array以高概率实现O(log n)插入时间。

4.2.2Insert in full Data Node(插入完整数据节点)

1)节点满度的标准
间隙阵列上的插入性能会随着间隙数量的减少而下降,所以ALEX不会等待数据节点100%满。在间隙阵列上引入了密度下限和上限:dl,du ∈(0,1],约束dl <du。密度被定义为被元素填充的位置的分数。如果下一次插入导致超过du,则节点已满。我们设置dl =0.6和du =0.8,以实现平均数据存储利用率为0.7,类似于B+Tree,根据我们的经验,B+ Tree总是产生良好的结果,并且不需要调整。相比之下,B+树节点通常具有dl =0.5和du =1。

2)节点扩展机制
在这里插入图片描述

为了扩展包含n个键的数据节点,我们分配了一个新的更大的Gapped Array,其中有n/dl个插槽。然后,我们缩放或重新训练线性回归模型,然后使用缩放或重新训练的模型在这个新的更大的节点中进行基于模型的所有元素的插入。在创建之后,新数据节点处于密度下限dl。图4示例数据节点扩展,其中数据节点内的间隙阵列从左侧的两个槽扩展到右侧的四个槽。

3)节点拆分机制。
为了将一个数据节点一分为二,我们将keys分配给两个新的数据节点,使得每个新节点负责原始节点的key空间的一半。ALEX支持两种拆分节点的方法:
(1)横向拆分:(a)如果分裂数据节点的父内部节点尚未处于最大节点大小,则我们用指向两个新数据节点的指针替换父节点指向分裂数据节点的指针。父内部节点的指针数组可能具有指向拆分数据节点的冗余指针。见图Figure 3.如果是这样,我们给两个新节点中的每个节点给予一半的冗余指针。否则,我们通过将父节点的指针数组的大小加倍并为每个指针制作冗余副本来创建指向拆分数据节点的第二个指针,然后将冗余指针中的一个指向两个新节点中的每一个。图5a示出了不需要父内部节点的扩展的侧向拆分的示例。(b)如果父内部节点已经达到最大节点大小,那么我们可以选择拆分父内部节点,如图5b所示。请注意,通过将所有内部节点大小限制为2的幂,我们总是可以以“边界保持”的方式分割节点,因此不需要对任何模型进行再训练,以降低分割的内部节点。
(2)向下拆分:拆分将数据节点转换为具有两个子数据节点的内部节点,如图5C所示。两个子数据节点中的模型在它们各自的键上进行训练。B+ Tree没有类似的拆分机制。

4.3Delete, update, and other operations(删除、更新和其他操作)

要删除一个键,我们需要查找该键的位置,然后删除它及其有效负载。删除不会移动任何现有关键帧,因此删除操作比插入操作简单得多,不会导致模型精度降低。如果数据节点由于删除而达到密度下限dl,则我们收缩数据节点(即,与扩展数据节点相反)以避免低空间利用率。此外,我们可以使用节点内成本模型来确定两个数据节点应该合并在一起并可能向上增长,从而将RMI深度局部减少1。然而,为了简单起见,我们不实现这些合并操作。修改键的更新是通过组合插入和删除来实现的。仅修改有效负载的更新将查找键并将新值写入有效负载。

4.4Handling out of bounds inserts(处理越界插入)

低于或高于现有键空间的键将分别插入到最左边或最右边的数据节点中。一系列越界插入(例如仅追加插入工作负载)将导致性能低下,因为该数据节点没有拆分越界键空间的机制。
在这里插入图片描述
首先,当检测到现有键值空间之外的插入时,ALEX将扩展根节点,从而扩展键值空间,如Figure 6所示。我们向右扩展子指针数组的大小。指向现有子级的现有指针不会被修改。为扩展指针数组中的每个新槽创建新数据节点。如果此扩展将导致根节点超过最大节点大小,ALEX将创建新的根节点。新根节点的第一子指针将指向旧根节点,并且为新根节点的每隔一个指针槽创建新数据节点。在此过程结束时,越界键将落入新创建的数据节点之一。

其次,ALEX的最右边的数据节点通过维护节点中的最大键的值并保持插入超过该最大值的次数的计数器来检测仅追加插入行为。如果大多数插入超过了最大值,这意味着只添加行为,所以数据节点向右扩展而不进行基于模型的重新插入;扩展的空间最初保持为空,以预期更多的附件状插入物。

总结

ALEX的设计方法概述就到这结束了,ALEX的代码我也运行成功了,接下来跑一下几个代表性的数据集,追寻学习索引前沿发展的脚步嘎嘎🦆

  • 32
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值