一种基于矩阵哈希的数据存储和查询方法与流程

文档序号:14950679发布日期:2018-07-17 22:28阅读:206来源:国知局
本发明属于内存数据库
技术领域
:,特别涉及一种基于矩阵哈希算法的数据组织、索引、存储方法。
背景技术
::内存数据库相比于磁盘数据库具有较高的灵活性和易用性,内存数据库从范型上可以分为关系型内存数据库和键值型内存数据库。基于键值的内存数据库(keyvaluestore)具有灵活简洁、节省内存、快速查询等优点,相比于基于关系型的内存数据库有独特优势,因而被广泛应用在各大互联网公司,比如在亚马逊、facebook、youtube、百度、新浪、搜狐等。键值存储系统的数据是以键值对的形式存在,并且用哈希表来进行存储,因此哈希算法作为键值存储系统的核心技术,是直接影响系统性能和网站效率的关键因素。目前存在的实际问题是,随着互联网快速发展,很多互联网公司都积累了大量的数据,由于键值对的数量巨大,而可供使用的内存空间却是有限的,因此当插入一个新的键值对时,键值对的冲突会比较多。这样的冲突会导致新键值对的插入失败、已有键值对的更新查找失败等问题,大大影响了键值存储系统的性能,因而对使用键值存储系统的互联网公司造成较大的经济损失。同时,客户对数据操作的需求和要求越来越高,需要快速得到数据的查询结果,因而对互联网公司的响应能力提出较高要求,如果互联网公司不能做到即时响应,将会大大影响用户体验。以上两个问题广泛存在各大应用键值存储系统的互联网公司中,现有的哈希表设计也不断尝试新的思路以更好的解决这两个关键问题。首先针对冲突问题,已有的哈希表设计广泛通过辅助的数据结构(比如布隆过滤器)减少冲突概率。比较典型的算法设计是快速哈希(fasthashtable)(h.song,s.dharmapurikar,j.turner,andj.lockwood.fasthashtablelookupusingextendedbloomfilter:anaidtonetworkprocessing.acmsigcommcomputercommunicationreview,35(4):181–192,2005.),分段哈希(segmenthash)(s.kumarandp.crowley.segmentedhash:anefficienthashtableimplementationforhighperformancenetworkingsubsystems.inproc.acmancs,pages91–103,2005.),孔雀哈希(peacockhash)(s.kumar,j.turner,andp.crowley.peacockhashing:deterministicandupdatablehashingforhighperformancenetworking.inproc.ieeeinfocom,2008.)。对于一个需要插入的新键值对,这些哈希设计都使用布隆过滤器来决定待插入的哈希表。对于冲突的键值对,要么使用指针挂在链表上,要么丢弃。这些哈希设计虽然使用多子表来减少冲突,但是仍然存在缺点,比如较低的装载率。冲突率也还有较大的减少空间。其次是查询时间问题,比较典型的哈希设计有完美哈希(z.j.czech,g.havas,andb.s.majewski.anoptimalalgorithmforgeneratingminimalperfecthashfunctions.informationprocessingletters,43(5):257–264,1992.)、布谷鸟哈希(b.fan,d.g.andersen,andm.kaminsky.memc3:compactandconcurrentmemcachewithdumbercachingandsmarterhashing.innsdi,volume13,pages385–398,2013.)等,然而这些哈希的缺点在于更新时十分低效,需要大量的哈希计算和内存访问。比如,布谷鸟哈希在更新哈希表时需要近500次哈希计算和内存访问,即使如此,也很有可能更新失败。因此对于这些哈希表设计,如果多次更新失败,则将不得不重建整个哈希表。重建过程将会需要大量时间,对于现实的应用系统是无法接受的。技术实现要素:为解决哈希表冲突和查询时间问题,克服已有哈希表存在的高冲突率、低内存使用效率、低装载率等缺陷,本发明提供一种将多子表哈希、布隆过滤器、位图相结合的新的哈希表设计方案—“矩阵哈希”。本发明采用的技术方案如下:一种基于矩阵哈希的数据存储方法,其特征在于,包括以下步骤:1)建立哈希表数据结构,其包含z个子表,z是偶数,各子表的大小等差递减;对于将第i个子表和第z-i+1个子表结合,得到个大小相等的子表;2)建立辅助数据结构,其包含与所述z个子表对应的z个布隆过滤器,各布隆过滤器的大小等差递减;对于将第i个布隆过滤器和第z-i+1个布隆过滤器结合,得到个大小相等的布隆过滤器;然后将该个布隆过滤器的对应比特追加在一起,形成1个多比特布隆过滤器;3)利用所述哈希表数据结构和所述辅助数据结构插入键值对,实现数据存储。进一步地,每当插入一个新的键值对时,将其插入到装载率最小的子表中。进一步地,在最后一个字表即第z个子表上挂链表,如果待插入的键值对找不到一个空桶,则使用指针将其挂在链表上。进一步地,每个子表有一个位图相对应,位图中的每一个比特与其对应子表中的的一个桶相对应;空桶对应位图中的比特为0,非空桶对应位图中的比特为1。进一步地,增加一个额外的布隆过滤器fhalf,其负责记录子表的第二部分,即以减少查询的子表数。进一步地,键值对的插入方式如下:a)对于一个给定的键值对,首先通过位图检查z个候选桶是否为空,然后将键值对插入到装载率最低的子表中,以平衡所有子表装载率;假设要插入的子表索引为i,如果则更新布隆过滤器fi来表示键x在子表ti中,并更新对应位图;如果则更新布隆过滤器fz-i+1来表示x在子表ti中,并更新fhalf和对应位图;b)如果位图显示键x应该插入的z个桶均已满,则使用踢的机制实现键值对的插入。进一步地,键值对的查询方式为:在查询x时,首先在多比特布隆过滤器fm和fhalf中查询x,如果返回true,且fhalf返回false,则检查子表ti;否则,先检查子表tz-i+1,如果没有匹配,再检查子表ti;如果在z个子表中都无法查找到x,则查找最后一个子表的链表;如果仍然无法找到,则说明x不在哈希表中。进一步地,键值对的删除方式为:在删除x时,首先根据查询操作找到x所在的桶,然后将键值对从桶中移除,并重置位图中x所在桶的对应比特。本发明的有益效果是:1)高装载率+较少指针:用较小的内存空间存储大量的键值对,并且使用的指针数很少。2)低冲突率。3)快速更新:利用很少的内存访问即可更新哈希表。4)零更新失败。5)快速查询:能够用很少的内存访问快速查找到键值对,或者对于不存在的键值对,能够快速返回不存在的结果。6)实用性:很容易在硬件系统中实现。附图说明图1是矩阵哈希的算法示意图。图2是多比特布隆过滤器的结构图。具体实施方式下面通过具体实施例和附图,对本发明做进一步说明。一.数据结构本发明的“矩阵哈希”的数据结构综合使用了多级子表、布隆过滤器和位图。数据结构由哈希表数据结构和辅助数据结构两部分组成。1.哈希表数据结构每个子表的大小,即能够存储的最大元素数目,是等差递减的,因此与子表对应的布隆过滤器也是等差递减的。在插入元素时使用了一个比较简单的均衡策略:每当插入一个新的键值对时,将它插入到装载率最小的子表中,如此就能保证每个子表中的元素数目也是类似算术级数递减形式存在的。假设一共有z个子表,z是偶数。对于矩阵哈希将第i个子表和第z-i+1个子表结合,最终得到了个大小相等的子表。因为结合后的子表形状与矩阵类似,因此我们将这个算法命名为矩阵哈希。为了避免插入失败,允许最后一个子表挂链表。如果待插入键值对最终找不到一个空桶,则可以在第z个子表上挂链表。因为第z个子表是最小的子表,因此指针将会占用最小的内存。图1矩阵哈希的算法示意图,其中,左边是大小呈等差递减的6个子表和6个布隆过滤器,中间是结合后的大小相等的3个子表和3个布隆过滤器。右上方是三个标准布隆过滤器bf1,bf2,bf3结合而成的多比特布隆过滤器。2.辅助数据结构与哈希表结合类似,对于矩阵哈希将第i个布隆过滤器和第z-i+1个布隆过滤器结合,最终得到了个大小相等的标准布隆过滤器。接着,通过将这个布隆过滤器对应比特追加在一起,形成了1个布隆过滤器。在这个布隆过滤器中,每个箱由个比特组成。我称将这一个布隆过滤器为多比特布隆过滤器,并用fm表示。到此,我们已经把原z个等差的布隆过滤器组合成1个多比特布隆过滤器。图2多比特布隆过滤器的结构图。如该图所示,一个箱中的三个比特分别来自三个大小相等的标准布隆过滤器即f1,f2,f3。值得注意的是,布隆过滤器的组合是在片内内存进行的,是物理上的,而子表的结合仅是概念上的。多比特布隆过滤器的算法实现方式如下所示:假设f1,f2,f3均有m个比特。对于f1,先取最高位比特(将f1的m个比特与2m-1做逻辑与操作),然后将所得结果向左移2*m位(所得m个比特乘以22m),接着取次高位比特(将f1的m个比特与2m-2做逻辑与操作),将所得结果向左移2*(m-1)位(所得m个比特乘以22(m-1)),将所得结果与最高比特操作后的值累加,以此类推,每个比特做类似操作,累加,直到最后一个比特,假设所得到的累加值为f1。对f2,f3分别做相同操作,得到累加值为f2,f3。将f1、f2右移一位后结果和f3右移两位后结果,这三者做逻辑或操作即得到多比特布隆过滤器(即为)。由于以上布隆过滤器的设计会导致一个问题:当一个布隆过滤器返回true时,我们需要查询对应的两个子表。比如若x在第i个布隆过滤器中,则需要在子表ti或tz-i+1中查询。为了减少查询的子表数,增加了一个额外的布隆过滤器,称为fhalf,负责记录子表的第二部分,即此外矩阵哈希还在片内使用位图,每个子表有一个位图相对应,位图中的每一个比特与其对应子表中的的一个桶相对应。空桶对应位图中的比特为0,非空桶为1。二.矩阵哈希假阳率推导矩阵哈希有两个布隆过滤器:fm和fhalf。假设n为键值对的个数,z个子表重组成了个子表。假设fm有m个箱,每个箱里有个比特,这个比特分别对应个子表。假设fm有k个子表,fm的假阳率和组成它的独立的个布隆过滤器相等。因此fm的假阳率如用f(fm)表示,公式如下:如果返回true的布隆过滤器的个数为u+1,那么假阳率公式为:f(fm,u)=0.5k*u*(1-0.5k(z-u-1))fhalf同样有k个哈希函数,fhalf的假阳率为:f(fhalf)=0.5k。如果只有fm返回true,并且键值对仅存在于一个子表中,则没有误报,这个事件发生的概率为(1-f(fm))*(1-f(fhalf))。如果只有fm返回true,且报告键值对存在于u+1个子表中,则会有u个误报,这个事件的概率为f(fm,u)*(1-f(fhalf))。如果只有fhalf报告一个误报,这个事件发生的概率为(1-f(fm))*f(fhalf)。如果fm有u个误报,且fhalf有一个误报,这个事件发生的概率为f(fm,u)*f(fhalf)。例如:当z=8并且k=16时,矩阵哈希的假阳率为1-(1-f(fm))*(1-f(fhalf))≈6.1*10-5,这个数字是非常小的。三.键值对的插入、查询、删除方式在键值存储系统中,矩阵哈希算法插入、查询、删除键值对的具体操作实施方式如下:1.键值对的插入方式对于一个给定的键值对,要将键x插入。首先通过位图检查z个候选桶是否为空。然后将键值对插入到装载率最低的子表中,以平衡所有子表装载率。假设要插入的子表索引为i。如果则更新fi来表示x在子表ti中,更新对应位图;如果子表索引需将fz-i+1更新来表示x在子表ti中,并更新fhalf和对应位图。插入过程中,为了将一个箱中与fi对应的比特置为1,将这个箱中的个比特与2i-1做逻辑或操作即可。如果位图显示x应该插入的z个桶均已满,则使用cuckoo哈希(布谷鸟哈希)中踢的机制,并用位图来决定要踢哪一个键值对。使用位图来按顺序检查x对应的z个候选桶,以确定候选桶中原有的元素,比如y,在剩余的z-1个子表中,是否有一个空桶可以将y插入。如果有,则将y踢出,将x插入,并将y插入新的位置。如果找不到这样一个y,则执行盲踢,并重复以上插入的流程。盲踢的次数限制为θ,如超过θ次盲踢,则将键值对挂到最后一个子表的链表上。通过改变θ的值,rht4可以在装载率和插入速度之间进行权衡。因为位图对子表中的空桶和非空桶有一个全局的记录,片内位图的使用显著的减少了踢操作的次数。2.键值对的查询方式如查询x,首先在fm和fhalf中查询x,如果返回true,且fhalf返回false,则检查子表ti。否则,先检查子表tz-i+1,如果没有匹配,再检查子表ti。如果在z个子表中都无法查找到x,则查找最后一个子表的链表。如果仍然无法找到,则说明x不在该哈希表中。值得注意的是,在查询过程中,只需计算k个哈希函数即可,并不需要计算z×k个哈希函数,这是因为:组成一个布隆过滤器的原个布隆过滤器的参数是相同的。如果要读取一个箱中与fi对应的比特,将这个比特与2i-1做逻辑与操作。如果结果为0,则箱中与fi对应的比特为0,反之为1。3.键值对的删除方式如删除x,rht1首先根据上述查询操作,找到x所在的桶,然后将键值对从桶中移除,并重置位图中x所在桶的对应比特。四.实验数据为了更好的评估本发明的矩阵哈希以及现有的哈希设计,我们采用了实际应用的数据。我们获取了网站www.ripe.net在2014.07.08日上午8点的12个转发信息库(fib,forwardinformationbase),对于每一个fib,对每个前缀(prefix)统一人工生成一个流量追踪(traffictrace)。我们使用fib中与我们相关的部分,也就是前缀(prefix)和相关的下一跳。前缀(prefix)作为键,下一跳作为值。我们用β来表示哈希表总的桶数量和总的元素数量的比值。其中1.05≤β≤10。我们用θ表示盲踢操作的阈值。fib中键值对个数为500,000。建立的8个子表的大小差值为5000,子表的总大小为β*n。使θ=0,这意味着不允许盲踢,只能只用位图踢。每次插入键值对,仿存次数的最大值为8+1,如果元素在8个子表中没有找到空的候选位置,则需要被插入到最后一个子表的链表上。冲突率用最后一个子表链表上的数目和总元素数目的比值。布隆过滤器有16个哈希函数。实验结果如下:1.矩阵哈希实验表现:1)装载率和冲突率实验设置β=1.05,θ=0,实验结果表明,矩阵哈希仅用1.05*n的内存就实现了非常高的装载率,其中8个子表的装载率十分均衡,总的装载率是95.19%。冲突率在0.05%左右,仅有几个fib冲突率超过了0.06%。2)插入和查询时间实验设置β=1.05,θ=0,实验将每个fib的所有元素插入到矩阵哈希,实验结果表明,插入元素越多,所需的内存访问越多。大多数元素,每次插入所需的内存访问次数低于6次,查询的内存访问次数在1到1.0019之间,均值为1.00059。3)位图踢和盲踢实验设置β=1.05,实验结果表明,当θ=5时,插入一个键值对的内存次数最多是8*(5+1)+1=49次,查询一个键值对的内存访问次数低于8次,这时最后一个子表的链表上没有元素。θ=0时,尽管盲踢不被允许,在最后一个子表的链表上也仅有很少的元素(0.56%)。插入时内存访问的最坏情况是8+1次。4)冲突率vsβ实验设置θ=0,实验结果表明β越大,冲突率越小,并且当β≥1.18时,冲突率接近为0。2.矩阵哈希与其他哈希对比:实验将矩阵哈希与链式哈希、线性探测、双哈希、布谷鸟哈希、d-left哈希、孔雀鸟哈希六种广为人知的哈希设计相对比。首先定义一下插入失败,对于线性探测、双哈希和布谷鸟哈希,当冲突发生时,会探测另外一个桶,并且这种探测会一直重复。我们将重复探测的次数限定在500以内,这就意味着,对于这三种哈希设计,每次插入内存访问次数的最大值为500,如果超过500次仍有冲突,这三种哈希设计就会放弃继续插入,将第500次循环时未被插入的元素丢弃,也就导致了插入失败。对于孔雀鸟哈希和矩阵哈希,布隆过滤器有16个哈希函数。实验一:(β=1.05,不同的fib)1)装载率实验结果表明:矩阵哈希的装载率一直是最高的。2)插入时间实验结果表明:矩阵哈希,在除了链式哈希之外的其他所有哈希中,插入所需的仿存次数最少。这是因为链式哈希,在插入时只需要一次或两次访存,所以访存时间较短,但链式哈希在其他方面的缺点十分突出。而矩阵哈希,由于布隆过滤器和位图的存在,能达到快速插入。3)查找时间实验结果表明:矩阵哈希有着最短的查找时间,因为矩阵哈希有这较高的装载率和很小的假阳率。实验二(不同的β,fibrrc00)1)装载率实验结果表明:矩阵哈希的装载率一直是最高的,链式哈希和双哈希的装载率差不多,孔雀鸟哈希只有在β比较高时,才达到了较高的装载率。2)插入时间实验结果表明:矩阵哈希,在除了链式哈希之外的其他所有哈希中,插入所需的仿存次数最少。3)查找时间实验结果表明:矩阵哈希有着最短的查找时间。以上实施例仅用以说明本发明的技术方案而非对其进行限制,本领域的普通技术人员可以对本发明的技术方案进行修改或者等同替换,而不脱离本发明的精神和范围,本发明的保护范围应以权利要求书所述为准。当前第1页12当前第1页12
当前第1页1 2 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1