基于固态硬盘的高维数据索引结构设计方法

文档序号:6444221阅读:160来源:国知局
专利名称:基于固态硬盘的高维数据索引结构设计方法
技术领域
本发明涉及数据库索引结构,具体涉及一种基于固态硬盘的高维数据索引结构设计方法。
背景技术
R树,是目前应用最广的高维数据索引结构之一。传统的R树设计均假设外存为磁盘。随着闪存技术的成熟,基于闪存的固态硬盘得到了广泛使用。由于闪存的自身特点,固态硬盘的随机更新较慢。R树结构由于有大量随机更新操作,所以传统的R树设计不能很好地适应固态硬盘的特性。
上至大型数据中心,小到嵌入式系统,闪存(flash memory)作为硬盘(hard disk) 的理想替代品,被广泛应用于不同的系统中。这样大规模的应用主要得益于其出色的I/O 特性,高度的可靠性及其低功耗特性。基于闪存的磁盘,如固态硬盘(SSD),作为对传统磁盘的替代,越来越广泛地被应用于各种场合。下表列出了固态硬盘在2KB大小块访问下的I/ 0数据,单位是MB/sec。SSD品牌顺序读随机读顺序写随机写 ADATA 148.8130.1
Samsung 8.26.560.1Mtron 20 17 23 0.3 Intel_36_\A_26_2.5
从表中数据可以看出,1)固态硬盘具有不对称的IO特性其读操作的速度远超其写操作的速度,特别是随机写操作;2)闪存的随机读性能与顺序读操作相差不多。这些特性也使得之前针对磁盘的优化在固态硬盘上失效了。如何针对固态硬盘的读写特性设计相应的数据结构和算法成为近年来研究工作的热点。
R树(R-Tree),作为一个针对高维数据的通用索引结构,已经被整合进了诸多数据库系统,如PostgreSQL,MySQL等中。图1是一棵R树的示例。在R树上的修改常常散落在整棵树的各个角落,因此这些修改会导致大量的随机写操作。而随机写操作是固态硬盘上最慢的操作,这大大地恶化了闪存上R树的整体性能。从I/O的角度上看R树与一维索引结构B树相比有如下的特点
重叠读。在R树中,同一层级的节点的最小包容矩形(MBR)常常存在重叠,这导致查询一个节点可能需要更多次的读取祖先节点的操作(很可能超过树的高度),是为R树和 B树的一个显著差异。
最小包容矩形的级联更新。树叶节点的更新可能会导致这该节点最小包容矩形大小的变化,而此更新可能会导致父亲节点的边界的扩大。这样的更新很可能一直传递到根节点。因此,R树中高层节点的更新比B树上要频繁得多。
RFTL方法是R树上针对闪存特定优化的经典工作,该工作使用日志链的方式来管理R树的更新操作。在这种方式中,更新被记为“日志”顺序写回,从而形成一个日志的序列,每个结点的更新其附在每个节点之后来完成消减随机写的目的。当这个日志链的长度超过一个预先设定的阈值时,日志链中的内容才会被真正更新到节点中。当读取一个结点中的信息时,除了要读出原始数据,还要将日志链中的数据也全部读出。然而这个方法的最大的问题是随着日志链长度的增加,在日志链上的读操作将会急剧增加。特别是节点越接近根节点,日志链越长(因为R树高层的更新非常频繁),而另一方面,高层节点又正是读密集的节点,这样会导致读操作的代价急剧增加。
近些年来,技术的进步使得固态硬盘的读写的差距减小,过多的读操作的引入会降低整体的性能。如何在不大量增加读操作的基础上降低随机写操作是在固态硬盘上移植 R树的关键问题。发明内容
(一)要解决的技术问题
本发明的目的在于提出一种基于固态硬盘的高维数据索引结构设计方法,在不大量增加读操作的基础上降低随机写操作,以在固态硬盘上移植R树。
(二)技术方案
为了解决上述技术问题,本发明提供一种基于固态硬盘的高维数据索引结构设计方法,包括步骤
将索引结构分为原始R树区和节点差异日志区两个部分,分别存储原始版本数据和原始版本与最近版本的差异日志;
在内存中设计一个哈希表来存储节点及其更新在所述节点差异日志区存储位置对应关系的信息;一旦一个新的更新完成,读出这个节点更早时候的更新日志,然后将其和现在的日志合并并重新存入,作为到目前为止该节点的所有更新日志。
优选地,所述节点差异日志区分为日志页来进行使用,一个日志页能够存储多个节点差异的信息。
优选地,当日志达到一定量时,将所述节点差异日志区与原始R树区进行合并日志操作。
优选地,每次更新包括多个更新项,每个更新项记录了对R树节点的一个分支的更新操作,包括三种不同的更新操作插入分支、更新分支和删除分支。
优选地,每个更新项的前两位标识操作类型,接下来的位标识分支号和值。
优选地,对同一分支的更新会合并成一个更新项记录,记录的值为最后更新的值。
优选地,该索引结构满足应用程序查询请求的方法包括步骤
读取节点的号;
读出该节点原始版本信息;
查询哈希表中该节点对应的日志;
如果有对应的日志项,读取日志项;
将原始版本与日志合并;
输出该节点的最新版本。
优选地,该索引结构满足应用程序更新请求的方法包括步骤
输入待处理的更新请求;
找到更新请求对应的节点;
调用R的更新算法,计算出该节点当前版本;
将当前版本与基准版本比较记录差异;
查出原有差异日志项;
记录新的差异日志项,并将原有项作废;
更新哈希表项;
如果日志区总大小超过限制,执行合并日志操作。
优选地,用R树的其他变种,包括R+树、R*树来替代R树。
(三)有益效果
本发明在原有R树的基础上,加入节点差异日志区,并设计了节点差异日志将随机更新的操作转化为随机更新,以提高更新的效率。已存在的针对闪存的R树虽然也使用了日志存储设计,但是由于会形成日志链,所以会过多地增加读取操作。本发明中的节点差异日志可以将针对某一节点的日志存储在一定范围内,所以节点差异日志R树的读操作最多只是原R树的两倍。


图1为一棵R树的示意图2为本发明中索引结构的示意图3为本发明一实施例中节点差异日志R树的详细结构;
图4为本发明中节点差异日志的格式;
图5为本发明一实施例中一个插入操作在日志区导致的写操作;
图6为变化日志区与数据区的比例观察DLR方法的性能示意图7为节点大小对索引性能的影响示意图8为更新的比例从0变化到1,各方法的表现示意图9为全部使用插入操作并改变插入操作量,各方法的表现示意图10为将真实数据插入到各个索引结构中观察建立索引的时间,各方法的表现示意图11为图10的各种情况下读操作的次数,各方法的表现示意图12为图10的各种情况下写操作的次数,各方法的表现示意图。
其中,图8-12的柱状图每个对比项从左到右依次为本发明方法DLR、RFTL方法和经典R树方法。
具体实施方式
下面结合附图和实施例,对本发明的具体实施方式
作进一步详细描述。以下实施例用于说明本发明,但不是限制本发明的范围。
RFTL方法中过长的日志链是造成读性能下降的主要因素。本发明的核心思想是将以前散落在日志链不同部位的片段合并到一起,这样将能保证访问每一层最多只会造成一次读操作。此外,不同节点的压缩日志将尽可能的合并在一个页面中,从而显著降低了写的次数。
如图2所示,是本发明索引结构设计的一个概览。最上层是应用程序,它会发出请求,请求分为两类查询请求与更新请求。虚线框内是本发明的索引结构来响应这些请求。 本发明将索引结构分为原始R树区与节点差异日志区两个部分,分别存储原始版本数据和原始版本与最近版本的差异日志。当日志达到一定量时,日志会与原始R树区进行合并日志操作。
节点差异日志R树的详细结构如图3所示。从图中容易看出,原始R树区是一个普通的R树,在上面存放着最近一次合并后的树结构,该数据作为基准数据。当有读取操作时,基准数据将与日志数据合并,得到当然版本数据,返回给应用程序。
日志部分以日志的形式存储了当前版本与基准数据的差异。该部分顺序使用,其目的是降低在原始R树上散乱的随机写操作带来的性能恶化。日志部分分为日志页来进行使用,一个日志页可能存储多个结点差异的信息。如图中最上端的日志页里存储了结点1 与结点4的日志信息。一个页面存储多个日志的好处是提高页面的使用效率。同一个结点的日志不会跨页存储。日志区域有一定的大小限制。如果该区域装满,它将被整合到原始 R树上。
为了便于在日志区查找最新结果,我们在内存中设计了一个哈希表来存储节点及其更新在日志部分存储位置对应关系的信息。一旦一个新的更新完成,我们将读出这个节点更早时候的更新日志,然后将其和现在的日志合并并重新存入闪存,作为到目前为止该节点的所有更新日志。在这个更新的过程中,我们也将尽可能的让它和其他页面一起共享一个页面。日志区的格式被仔细地设计过,以致在给定区域上可以存放相当数量的修改结^ ο
图4给出了节点差异日志的格式。每条差异日志对应一个节点,同样,一个节点也只对应一条差异日志。每条差异日志包含了一个节点号和一些更新的记录项。节点号代表了该日志对应哪个结点,而更新记录项记录了该节点当前版本与基准版本之间的若干差异。实际实现中节点号会存储于哈希表中,哈希表的指针指向第一个更新项,同时哈希表会记录更新项的数目,以便于确定最后一项更新的位置。
每个更新项记录了对树节点的一个分支的更新操作。总共有三种不同的更新操作插入分支,更新分支和删除分支。每一个单元的前两位(bit)标识操作类型,接下来的位标识分支号和值。这样的设计可以保证一个节点日志最长不会超过一个节点页面的大小,达到我们减少读取日志操作的目的。对于插入操作来讲,值代表着新插入的数据值,更新是更新后的数据,而删除操作的值可以忽略。几次对同一分支的更新会合并,比如对同一分支的两次更新会合并成一个更新项记录,记录的值为最后更新的值。
容易看出,本发明不需要修改R树部分的原始代码,只需要在它的读写接口做小规模的修改。同样容易看出,我们的实现比起传统R树而言,至多会在每一层多一次读操作。另一个将日志区单独实现的好处是这样的实现保证了两部分最大限度的松耦合,从而保证R树的代码最大程度的得以复用。我们的方法有很强的灵活性和鲁棒性。事实上,只需要修改R树中搜索算法的读写接口就可以很容易地移植到R树的其他变种上,例如R+树, R*树等。
下面讨论节点差异日志R树如何满足应用程序的请求。下面介绍如何在读取一个节点的操作。读取节点的过程主要需要修改原R树的ReadNode函数。修改后的ReadNode见算法1。注意到在原始R树中可能该节点为NULL,这对应这一个节点新近被插入并被写入日志区但尚未整合到原始R树中。从算法中容易看出,我们的算法的读次数最多比原始的R树多一倍。ReadNode算法是R树的读操作的唯一需要修改的地方,因此我们这里省略了具体的R树的读操作的算法。
算法1读节点
输入读取节点的号
输出返回该节点的当前版本
1.读出原始版本信息
2.查询哈希中对应的日志
3.如果有对应的日志项
4.读取日志项
5.请原始版本与日志合并
6.返回节点的最新版本
算法2展示了节点差异日志R树中最核心的技术如何处理一条更新请求。通过以上介绍的读节点操作我们容易定位节点插入的位置,我们首先模拟在原始R树上插入的结果。不同之处在于,我们记录插入以及有插入导致的节点分裂所造成的所有的节点更新和生成结果,而不是直接修改R树。对于那些生成的新节点,我们直接将其写入日志区。这样做是正确的,因为该节点的父亲节点的修改结果也已经被更新到了日志区,因此通过这个更新,我们将能访问到这个节点。当日志区满的时候,它将被合并到原始的R树中,日志区被回收。最坏的情况下,我们将造成和原始R树一样的写操作。然而实际中,相同节点的多次写操作都会被合并成一次写,这在R树中是非常普遍的,尤其是对于高层节点。此外这里的写操作非常接近与顺序写。综上所述,这个策略将大大提高R树的更新性能。
算法2更新操作
输入待处理的更新请求
输出更新请求被索引处理
1.找到更新请求对应的树节点
2.调用R的更新算法,计算出节点当前版本
3.将当前版本基准版本比较记录差异
4.查出原有差异日志项
5.记录新的差异日志项,并将原有项作废
6.更新哈希表项
7.如果日志区总大小超过限制,执行合并日志操作
图5展示了一个插入操作在日志区导致的写操作的例子。1个条目将被插入4号节点,插入前树的结构如本节开始所示。删除的单元表示过期的页面,空格部分表示空闲空间。节点索引常驻内存以加速对应操作。插入后的日志区如图5所示。原有的节点4对应的日志项被标识为过期。新的差异日志由于不足以写入到节点2的日志剩余的空间里,所以新开辟一个页面写入。此时,哈希表项中的指针更新为新日志的位置。
当日志区大小超过分配的总日志区大小时,就需要进行日志与原始R树的合并。 合并后原始R树区将全部更新成最新版本,而节点差异日志区将被清空。合并操作,与上文介绍的节点读操作类似。
本部分的实验将本发明方法与经典R树和RFTL作比较。本发明方法简称为 DLR(Different-logging R 树)方法。实验使用 Visual Studio 2008 环境下的 C++开发。 软件环境为Windows 7操作系统。硬件环境为,一台配置了 2. 0主频的双核CPU和IGB内存的台式机。固态硬盘使用ADATA品牌,容量大小为30GB。
实验包括模拟数据集也包含真实数据集。模拟数据集是在10000*10000的二维区域上生成一些点,并将他们插入到索引结构中。我们比较各个方法运行的时间,来展示我们设计的DLR方法的性能。默认的树节点大小为4KB,默认生成点的个数为100K个。
首先,我们进行方法最优参数的确定。执行模拟数据的插入操作。变化日志区与数据区的比例观察DLR方法的性能得到图6。可以看出索引的性能在日志区大小为数据区的20%时索引性能达到最高。
过大的日志区会造成日志区与数据区不能及时合并而降低索引的读取效率。反之过小的日志区,会造成频繁的合并操作,起不到日志区的效果。接着,我们观察节点大小对索引性能的影响如图7所示。节点大小在4KB时性能达到最优。过大和过小的节点大小都会影响索引的I/O性能。
接着在模拟数据集上,我们比较各个方法的运行时间。我们产生了一组更新与查询混合的数据。更新的比例从0变化到1,各方法的表现如图8所示。
本发明方法一直是最好的方法。当没有更新操作时,各个方法表现相同。随着更新操作比较的提高,传统R树和DLR树的表现均变差。我们可以发现,只有当更新操作比较较大时RFTL才超过传统R树。这是因为RFTL会产生过多的读操作。
接着,我们全部使用插入操作,并改变插入操作量。得到图9,随着插入量的增加, 各个方法的时间都有所提高。对于各种插入量来说,我们的方法表现总是最好的,由此可以看出,本发明方法有着较好的可扩展性。
下面我们使用真实数据集来评估各个方法的性能。各个真实数据集是从R-tree portal网站上下载的。对于数据集的描述列出如下表。
权利要求
1.一种基于固态硬盘的高维数据索引结构设计方法,其特征在于,包括步骤 将索引结构分为原始R树区和节点差异日志区两个部分,分别存储原始版本数据和原始版本与最近版本的差异日志;在内存中设计一个哈希表来存储节点及其更新在所述节点差异日志区存储位置对应关系的信息;一旦一个新的更新完成,读出这个节点更早时候的更新日志,然后将其和现在的日志合并并重新存入,作为到目前为止该节点的所有更新日志。
2.如权利要求1所述的方法,其特征在于,所述节点差异日志区分为日志页来进行使用,一个日志页能够存储多个节点差异的信息。
3.如权利要求1所述的方法,其特征在于,当日志达到一定量时,将所述节点差异日志区与原始R树区进行合并日志操作。
4.如权利要求1所述的方法,其特征在于,每次更新包括多个更新项,每个更新项记录了对R树节点的一个分支的更新操作,包括三种不同的更新操作插入分支、更新分支和删除分支。
5.如权利要求4所述的方法,其特征在于,每个更新项的前两位标识操作类型,接下来的位标识分支号和值。
6.如权利要求5所述的方法,其特征在于,对同一分支的更新会合并成一个更新项记录,记录的值为最后更新的值。
7.如权利要求1所述的方法,其特征在于,该索引结构满足应用程序查询请求的方法包括步骤读取节点的号; 读出该节点原始版本信息; 查询哈希表中该节点对应的日志; 如果有对应的日志项,读取日志项; 将原始版本与日志合并; 输出该节点的最新版本。
8.如权利要求1所述的方法,其特征在于,该索引结构满足应用程序更新请求的方法包括步骤输入待处理的更新请求;找到更新请求对应的节点;调用R的更新算法,计算出该节点当前版本;将当前版本与基准版本比较记录差异;查出原有差异日志项;记录新的差异日志项,并将原有项作废;更新哈希表项;如果日志区总大小超过限制,执行合并日志操作。
9.如权利要求1所述的方法,其特征在于,用R树的其他变种,包括R+树、R*树来替代 R树。
全文摘要
本发明是一种基于固态硬盘的高维数据索引结构设计方法,包括步骤将索引结构分为原始R树区和节点差异日志区两个部分,分别存储原始版本数据和原始版本与最近版本的差异日志;在内存中设计一个哈希表来存储节点及其更新在所述节点差异日志区存储位置对应关系的信息;一旦一个新的更新完成,读出这个节点更早时候的更新日志,然后将其和现在的日志合并并重新存入,作为到目前为止该节点的所有更新日志。本发明在原有R树的基础上,加入节点差异日志区,并设计了节点差异日志将随机更新的操作转化为随机更新,以提高更新的效率。本发明中的节点差异日志可以将针对某一节点的日志存储在一定范围内,节点差异日志R树的读操作最多只是原R树的两倍。
文档编号G06F17/30GK102542057SQ20111045204
公开日2012年7月4日 申请日期2011年12月29日 优先权日2011年12月29日
发明者吕雁飞, 崔斌, 李井 申请人:北京大学
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1