CN113505130A - 一种哈希表的处理方法 - Google Patents
一种哈希表的处理方法 Download PDFInfo
- Publication number
- CN113505130A CN113505130A CN202110776008.7A CN202110776008A CN113505130A CN 113505130 A CN113505130 A CN 113505130A CN 202110776008 A CN202110776008 A CN 202110776008A CN 113505130 A CN113505130 A CN 113505130A
- Authority
- CN
- China
- Prior art keywords
- bucket
- partner
- hash table
- hash
- split
- Prior art date
- Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
- Granted
Links
Images
Classifications
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F16/00—Information retrieval; Database structures therefor; File system structures therefor
- G06F16/20—Information retrieval; Database structures therefor; File system structures therefor of structured data, e.g. relational data
- G06F16/22—Indexing; Data structures therefor; Storage structures
- G06F16/2228—Indexing structures
- G06F16/2255—Hash tables
-
- Y—GENERAL TAGGING OF NEW TECHNOLOGICAL DEVELOPMENTS; GENERAL TAGGING OF CROSS-SECTIONAL TECHNOLOGIES SPANNING OVER SEVERAL SECTIONS OF THE IPC; TECHNICAL SUBJECTS COVERED BY FORMER USPC CROSS-REFERENCE ART COLLECTIONS [XRACs] AND DIGESTS
- Y02—TECHNOLOGIES OR APPLICATIONS FOR MITIGATION OR ADAPTATION AGAINST CLIMATE CHANGE
- Y02D—CLIMATE CHANGE MITIGATION TECHNOLOGIES IN INFORMATION AND COMMUNICATION TECHNOLOGIES [ICT], I.E. INFORMATION AND COMMUNICATION TECHNOLOGIES AIMING AT THE REDUCTION OF THEIR OWN ENERGY USE
- Y02D10/00—Energy efficient computing, e.g. low power processors, power management or thermal management
Landscapes
- Engineering & Computer Science (AREA)
- Theoretical Computer Science (AREA)
- Software Systems (AREA)
- Data Mining & Analysis (AREA)
- Databases & Information Systems (AREA)
- Physics & Mathematics (AREA)
- General Engineering & Computer Science (AREA)
- General Physics & Mathematics (AREA)
- Information Retrieval, Db Structures And Fs Structures Therefor (AREA)
Abstract
本发明提供一种哈希表的处理方法,所述哈希表为聚合的可拓展哈希表,包括多个可拓展哈希表,每个可拓展哈希表构成所述聚合的可拓展哈希表的一层,所述可拓展哈希表包括不少于一个的桶,所述桶用于存储键值对数据;所述可拓展哈希表具有相同编号的桶构成所述聚合的可拓展哈希表的一个段;所述聚合的可拓展哈希表包括共享目录,所述共享目录用于管理聚合的可扩展哈希表的全局深度以及段的指针。本发明有效降低了rehash造成的延迟陡增和吞吐骤降,同时保证了哈希表的高性能。
Description
技术领域
本发明涉及持久化哈希技术领域,具体涉及一种哈希表的处理方法。
背景技术
动态哈希表被广泛应用在各种存储系统,尤其是内存数据库中,以实现高效的查询服务。随着新一代非易失性内存(Non-Volatile Memory)的出现,部分研究人员和企业都在探索将哈希表移植到NVM上,以实现非易失性内存数据库。NVM也称作持久化内存(Persistent Memory,简称PM)。NVM拥有远高于DRAM的存储密度,更低的功耗以及持久化的能力。尽管NVM表现出与DRAM相近的写延迟和3到4倍高的读延迟,但其延迟在百纳秒级,远远低于传统的持久化存储,例如固态硬盘,磁盘等。那么,在NVM上构建内存数据库既可以利用NVM的低延迟来提供高效的服务,又可以利用其非易失性来实现数据库的快速恢复,还能够利用NVM的大容量以容纳更多的数据到内存中。而这核心则是构建高效的查询结构,如持久化哈希表。当前大量的研究工作都针对NVM的特性,提出并设计了持久化内存友好的动态哈希结构,例如PFHT[1],PATH[2],Level Hashing[3],CLevel[4],CCEH[5],Dash[6],和P-CLHT[7]。
目前已有的持久化哈希表设计,往往将精力集中于减少对NVM的访问,以避免因NVM的延迟而导致的性能下降。然而一个关键问题则被忽略了,即动态哈希表需要通过rehash(重新哈希)来扩张容量,而rehash会造成暂时性的尾延迟陡升和吞吐量的骤降。延迟是指一次操作从开始到完成的时间,这些操作包括插入、删除、更新以及查询等。尾延迟用于衡量绝大部分操作可以在多长时间内完成,例如,在获得20000次操作的延迟后,将这些延迟排序,取时间最长的0.1%的操作的延迟,计算其平均值,该平均值即可作为尾延迟指标,即99.9%的操作延迟小于该尾延迟。吞吐量是指单位时间内完成的操作数,单位通常采用MOPS(Million Operations Per Second,百万次操作每秒)。
与静态哈希不同,动态哈希在运行时能够动态调整哈希大小,以实现较高的空间利用率,在无法预估数据规模的情况下,动态哈希是一类适合采用的索引方案。然而,动态哈希往往通过rehash扩增或者缩小容量,而rehash的开销极大。在NVM上,这个问题会因为NVM相对DRAM更高的延迟而恶化。维持较低且稳定的尾延迟对于用户体验是至关重要的,因此设计出对rehash友好的持久化哈希表对存储系统设计人员和用户都是大有裨益的。
目前已经有较多持久化哈希表被提出,但这些哈希表对rehash问题的处理都存在一定的问题。典型的问题如:完全未考虑rehash而导致哈希表在rehash时吞吐近乎归零;设计了复杂的rehash算法但忽略了NVM的物理特性而导致算法效果不佳;以牺牲无rehash时的性能为代价换取rehash时较低的尾延迟和较高的吞吐。
然而对于一个高效的持久化哈希表,其应在不进行rehash时保证低延迟和高吞吐,在进行rehash时则最大限度避免延迟和吞吐的抖动,提供稳定的延迟和吞吐。目前已有的持久化哈希表均无法同时实现以上目标。
参考文献:
[1]Biplob Debnath,Alireza Haghdoost,Asim Kadav,Mohammed G.Khatib,andCristian Ungureanu.2015.Revisiting Hash Table Design for Phase ChangeMemory.In Proceedings ofthe 3rdWorkshop on Interactions ofPM/FLASHwithOperating Systems and Workloads(INFLOW’15)(Monterey,California).New York,NY,USA,Article 1,9pages.
[2]P.Zuo and Y.Hua.2018.A Write-Friendly and Cache-Optimized HashingScheme for Non-Volatile Memory Systems.IEEE Trans.Parallel Distrib.Syst.29,5(2018),985–998.https://doi.org/10.1109/TPDS.2017.2782251
[3]Pengfei Zuo,Yu Hua,and Jie Wu.2018.Write-Optimized and High-Performance Hashing Index Scheme for Persistent Memory.In 13th USENIXSymposium on Operating Systems Design and Implementation(OSDI’18).Carlsbad,CA,461–476.,
[4]Zhangyu Chen,Yu Huang,Bo Ding,and Pengfei Zuo.2020.Lock-freeConcurrent Level Hashing for Persistent Memory.In 2020USENIX Annual TechnicalConference(ATC’20).799–812.
[5]Moohyeon Nam,Hokeun Cha,Young ri Choi,Sam H.Noh,and BeomseokNam.2019.Write-Optimized Dynamic Hashing for Persistent Memory.In 17th USENIXConference on File and Storage Technologies(FAST’19).Boston,MA,31–44
[6]Baotong Lu,Xiangpeng Hao,TianzhengWang,and Eric Lo.2020.Dash:Scalable Hashing on Persistent Memory.Proceedings oftheVLDB Endowment 13,10(April 2020),1147–1161
[7]Se Kwon Lee,Jayashree Mohan,Sanidhya Kashyap,Taesoo Kim,and VijayChidambaram.2019.Recipe:Converting Concurrent DRAM Indexes toPersistentMemory Indexes.In Proceedings ofthe 27th ACM Symposium on OperatingSystems Principles(SOSP’19(Huntsville,Ontario,Canada).New York,NY,USA,462–477Emprical
[8]Ronald Fagin,Jurg Nievergelt,Nicholas Pippenger,and H.RaymondStrong.1979.Extendible Hashing—a Fast Access Method for DynamicFiles.ACMTrans.Database Syst.4,3(Sept.1979),315–344.
[9]Ori Shalev and Nir Shavit.2006.Split-Ordered Lists:Lock-FreeExtensible Hash Tables.J.ACM 53,3(May 2006),379–405.
[10]Tudor David,Rachid Guerraoui,and VasileiosTrigonakis.2015.Asynchronized Concurrency:The Secret to Scaling ConcurrentSearch Data Structures.In Proceedings of the Twentieth InternationalConference on Architectural Support for Programming Languages and OperatingSystems(ASPLOS’15)(Istanbul,Turkey)(ASPLOS’15).New York,NY,USA,631–644
[11]N.Nguyen and P.Tsigas.2014.Lock-Free Cuckoo Hashing.In 2014IEEE34th International Conference on Distributed Computing Systems(ICDCS’34).627–636.https://doi.org/10.1109/ICDCS.2014.70
[12]Panagiota Fatourou,Nikolaos D.Kallimanis,and ThomasRopars.2018.An Efficient Wait-Free Resizable Hash Table.In Proceedings of the30th on Symposium on Parallelism in Algorithms and Architectures(SPAA’18)(Vienna,Austria).New York,NY,USA,111–120
发明内容
为解决上述现有技术中存在的问题,提供一种哈希表的处理方法,所述哈希表为聚合的可拓展哈希表,包括多个可拓展哈希表,每个可拓展哈希表构成所述聚合的可拓展哈希表的一层,所述可拓展哈希表包括不少于一个的桶,所述桶用于存储键值对数据;所述可拓展哈希表具有相同编号的桶构成所述聚合的可拓展哈希表的一个段;所述聚合的可拓展哈希表包括共享目录,所述共享目录用于管理聚合的可扩展哈希表的全局深度以及段的指针;所述处理方法包括:
计算输入键值对中键的哈希值H;
取H的最低G位为下标,在共享目录中索引相应的指针,获得相应的指针所指向的段;
取H的最高log2K位为下标,在段内索引一个桶;
在桶内进行线性查找、插入或删除;
其中,G为哈希表的全局深度,K为哈希表的层数。
在一些实施例中,当插入操作需要一个桶分裂并且共享目录容量不足时,利用全分裂方法扩张哈希表容量,所述全分裂方法包括:
生成一个分裂桶所在段的伙伴段,伙伴段中与分裂桶同层的桶构成分裂桶的伙伴桶;
将共享目录的容量倍增;
将所述伙伴段的指针加入共享目录;
将新的键值对插入伙伴桶中,根据键的哈希值迁移分裂桶中的部分键值对到伙伴桶中;
将伙伴段的其它后代桶的祖先指针指向其最年轻的祖先桶;
将全局深度加1,分裂桶的局部深度加1,将伙伴桶深度设置为与分裂桶相同。
在一些实施例中,当插入操作需要一个桶分裂且共享目录容量充足时,利用基础分裂方法扩张容量,所述基础分裂方法包括:
生成一个分裂桶所在段的伙伴段,伙伴段中与分裂桶同层的桶构成分裂桶的伙伴桶;
将伙伴段的指针加入共享目录;
将新的键值对插入伙伴桶中,根据键的哈希值迁移分裂桶中的部分键值对到伙伴桶中;
将伙伴段的其它后代桶的祖先指针指向其最年轻的祖先桶;
将分裂桶的局部深度加1,将伙伴桶深度设置为与分裂桶相同。
在一些实施例中,当插入操作需要一个桶分裂并且其所在段的伙伴段已经存在时,利用快速分裂方法扩张容量,所述快速分裂方法包括:
将分裂桶对应的后代桶设置为伙伴桶,将伙伴桶的祖先指针设置为无效;
将新的键值对插入伙伴桶中,将分裂桶的部分键值对移至伙伴桶中;
将分裂桶的局部深度加1,将伙伴桶深度设置为与分裂桶相同。
在一些实施例中,其中基于锁访问所述哈希表。
在一些实施例中,所述哈希表存储于NVM,所述锁放置于DRAM。
在一些实施例中,所述锁包括全局锁,所述全局锁用于所述共享目录的扩张;所述锁包括段锁,所述段锁用于分配新的段。
在一些实施例中,所述锁包括用于访问每个所述桶的读者锁,所述读者锁用于在访问桶时保护当前读操作以及避免阻塞其它读操作;所述锁包括每个桶的写者锁,所述写者锁用于在插入操作和/或删除操作时的并发控制。
本发明提供一种计算机可读存储介质,其上存储有计算机程序,其中,该程序被处理器执行时实现上述方法的步骤。
本发明提供一种计算机设备,包括存储器和处理器,在所述存储器上存储有能够在处理器上运行的计算机程序,其特征在于,所述处理器执行所述程序时实现上述方法的步骤。
本发明具有如下特点和有益效果:本发明克服了现有技术结构上的缺陷,实现了细粒度的桶分裂方法,做到了极细粒度的rehash,有效降低了rehash造成的延迟陡增和吞吐骤降,同时保证了哈希表的高性能。
附图说明
图1示出了现有技术CCEH、P-CLHT以及CLevel在rehash时导致的尾延迟陡增。
图2示出了现有技术的可拓展哈希。
图3示出了根据本发明一个实施例的共享目录多级可拓展哈希的结构示意图。
图4示出了根据本发明一个实施例的全分裂方法。
图5示出了根据本发明一个实施例的基础分裂方法。
图6示出了根据本发明一个实施例的快速分裂方法。
图7示出了根据本发明一个实施例的吞吐测试的测评结果。
图8示出了根据本发明一个实施例的平均延迟测试的测评结果。
图9示出了根据本发明一个实施例的尾延迟测试的测评结果。
具体实施方式
下面结合附图和具体实施例对本发明加以说明。应当理解,此处所描述的具体实施例仅用以解释本发明,并不用于限定本发明。
非易失性内存(Non-Volatile Memory,简称NVM)也称作持久化内存(PersistentMemory,简称PM),具有可字节寻址,大容量和持久化的特点。纯内存存储系统,例如键值数据库,可以充分利用这些特性来存储大量的数据,并且实现宕机后的瞬时恢复。动态哈希是这些存储系统的一个核心组件,能够提供极高的索引性能,其在运行时通过rehash(重新散列)扩增或者缩小容量,动态改变大小,以实现较高的空间利用率。然而,rehash的开销极大,rehash可造成剧烈的性能下降,尽管目前已有部分工作针对该问题提出了改进,但仍不能有效缓解rehash导致的性能下降。
发明人在对已有的持久化哈希表进行评测时发现,当不存在rehash时,这些哈希表可表现出较好的吞吐和较低的延迟。而当进行rehash时,这些哈希表的吞吐出现大幅度的下降,延迟出现大幅度的升高。而rehash在一个哈希表的生命周期中可能连续发生,这使得已有的持久化哈希表无法实现稳定的高性能。
这些问题的成因在于已有哈希表的结构不允许高效的rehash算法,使得rehash算法严重妨碍了普通操作(插入,删除,查找)的效率。而由于rehash需要对整个哈希表进行操作,因此整个rehash往往需要较长时间,进而导致哈希表的性能在rehash期间出现严重下降。
为了保证rehash算法的高效,哈希表的结构应当允许rehash算法以尽可能小的粒度完成rehash,即细粒度rehash,而非对整个表进行操作,以此避免rehash对普通操作造成较大的影响。然而目前已有的持久化哈希表中,大部分不具备这样的结构。因此大部分持久化哈希表都需要对整表进行rehash。而对于小部分允许细粒度rehash的哈希表则存在平均延迟较高、吞吐较低的问题。为了同时保证高性能和细粒度的rehash,需要在哈希结构上进行新的设计,而不能仅仅在算法层面进行优化。
发明人在研究中认识到:粗粒度的rehash方案导致性能下降。rehash由内存分配和哈希表项迁移两步组成。迁移的表项总数决定了rehash的粒度。过粗粒度的rehash往往导致极端的尾延迟。延迟是指一次操作从开始到完成的时间,这些操作包括插入、删除、更新以及查询等。尾延迟用于衡量绝大部分操作可以在多长时间内完成,例如,在获得20000次操作的延迟后,将这些延迟排序,取时间最长的0.1%的操作的延迟,计算其平均值,该平均值即可作为尾延迟指标,即99.9%的操作延迟小于该尾延迟。一些现有方案,例如P-CLHT,按整表为粒度进行rehash,每次rehash均需迁移全部表项。在整个rehash过程中,P-CLHT不能响应任何操作,进而导致极端的尾延迟。
图1示出了现有技术方案CCEH、P-CLHT以及CLevel在rehash时导致的尾延迟陡增。图1中,横轴表示采样批次,纵轴表示尾延迟时间,单位是毫秒(ms),现有技术CCEH、P-CLHT以及CLevel以三条不同的图例曲线展示。从中看出,P-CLHT在第4次、第17次以及第64次采样时均出现极端的尾延迟波峰,相比没有rehash的情况,有时尾延迟陡增超过1000倍。CLevel则采用了无锁rehash的方案,且仅迁移1/3表项。然而,从图1中仍能看到,CLevel也不能有效避免rehash导致的波峰。因为CLevel在rehash过程中需要等待内存分配,而出于避免持久化内存漏持的考虑,持久化内存上的内存分配性能极低。更为重要的是,尽管CLevel仅搬运1/3表项,随着总表的增大,每次rehash需要搬运的数据总量仍然是不断上升的,这也就导致rehash持续时间越来越长。
一些持久化哈希的方案,如CCEH和Dash,将基于整表的rehash方案替换为段分裂(segment split)。这样的rehash方案可实现固定复杂度的表项迁移,因为段大小为定值,分裂时仅需搬运正在分裂的段内的全部表项。这样极大缓解了rehash导致的尾延迟陡升。从图1中可以看到,CCEH的尾延迟峰值远低于P-CLHT和CLevel(注意y轴为指数轴)。然而这样的方案并不完美,搬运整个段内的数据虽然是较细粒度的,但由于其频繁发生,因此导致了尾延迟平均值的升高。图1中可以看到,CCEH的延迟曲线在40到60次采样中是高于CLevel和P-CLHT的,而该段采样中,CLevel和P-CLHT并未发生rehash。
发明人在研究中还认识到:已有持久化哈希的并发方案对持久化内存并不友好。目前大部分持久化哈希都通过锁进行并发控制。这些锁存放于持久化内存中,这样带来的问题是:频繁的取锁和释放锁将造成大量的持久化内存读写,一方面损害了哈希的性能,另一方面也对持久化内存的寿命造成极大的负面影响。即便是如CLevel的无锁并发方案,其并发控制的元数据仍存放于持久化内存中,且由于这些元数据记录了CLevel的结构信息和状态信息,也无法将其迁移至DRAM。因此一个持久化内存友好的哈希结构,应当将这些问题纳入考虑。
为了解决以上问题,本发明提供一种数据存储系统,设计了共享目录多级可拓展哈希表,将多个可拓展哈希通过共享目录的方式聚合为一个独立的哈希表,而各个可拓展哈希均可独立进行扩张而不相互干扰,这使得rehash操作可采用桶级别的粒度进行,因此同时保证了高性能和细粒度rehash,避免了rehash造成的性能抖动。
为了方便理解本发明,以下先介绍可拓展哈希。
常见的链式哈希的rehash操作往往对整张哈希表进行操作,这样的粒度过于粗放。而可拓展哈希(extendible hashing[9]),使用更细粒度的桶分裂(bucket split)来代替这样粗放的rehash。一个可拓展哈希由一个目录(directory)和若干桶(bucket)组成。目录中存放指向桶的指针,全体指针和桶都按序编号。图2是一个可拓展哈希的例子,图2中的可拓展哈希101具有一个目录1011和两个桶,分别标记为Bucket 0和Bucket 1,目录1011中存放指向Bucket 0的指针Pointer 0以及指向Bucket 1的指针Pointer 1,指针的编号展示在目录1011上方。可拓展哈希使用参数全局深度G决定当前指针的数量,指针的数量为2G。图2中,可拓展哈希101的全局深度G等于1,指针数量为2G=21=2,每一个桶也保存着各自的局部深度L,其中L=1。在可拓展哈希中,每一个可拓展哈希对应了一棵前缀树,但由于树是二维的,哈希是一维的,为了保证前缀关系,需要记录当前哈希表对应的前缀树的高度以及每一个桶所处的位置,这就是全局深度和局部深度。在计算机科学中,前缀树又称字典树,是一种有序树,用于保存关联数组,其中的键通常是字符串,与二叉查找树不同,键不是直接保存在节点中,而是由节点在树中的位置决定。一个节点的所有子孙都有相同的前缀。G和L以及桶的编号共同决定一个桶应当被指向的指针。初始化时,共有2G个桶和指针被分配。指针和桶均按顺序编号,每个指针指向与自身编号相同的桶。
当一个桶无法容纳更多键值对而溢出时,可拓展哈希执行桶分裂(bucketsplit),添加一个新的桶以扩增容量,溢出的桶称为分裂桶,新增的桶称为伙伴桶。分裂桶和伙伴桶的局部深度都设置为分裂桶分裂前的局部深度加1。由于存在新增桶,目录可能无法提供足够数量的指针以指向新桶,此时需要执行目录倍增以增加指针的数量。此时G应当加1。
图2中示出了桶分裂触发目录倍增的例子。图2中,Bucket 1无法容纳更多的键值对,需要进行桶分裂,该桶即为分裂桶,为了清楚显示,将其填充为黑色。图2中的102示出了桶分裂后的可拓展哈希,其中,增加了分裂桶Bucket 1的伙伴桶Bucket 3,桶的总数由2个变为3个。由于101中的目录1011只能存放两个指针,不能存放3个指针,因此将目录1011倍增,1021示出了倍增后的目录。其深度G变为2,可容纳2G=22=4个指针,分别是Pointer 0,Pointer 1,Pointer 2,Pointer 3,指针的编号以二进制表示,分别为00,01,10,11。分裂桶Bucket 1的局部深度L原来为1,桶分裂后,Bucket 1局部深度L增加1,变为2,其伙伴桶Bucket 3的局部深度与Bucket 1相同,Bucket 3的局部深度L也为2。
每一个桶和每一个指针的编号需要进行匹配:如果局部深度与全局深度相等,则该桶被与该桶完全相同编号的指针指向;如果局部深度小于全局深度,则取指针编号二进制表示的最低L位,若最低L位与桶编号相等,则指向该桶。图2中桶Bucket 0编号为0,局部深度为1,而指针Pointer 0和Point 2的最低1位均为0,因此均指向Bucket 0。
以上介绍了可拓展哈希。本发明设计了共享目录多级可拓展哈希,在不牺牲哈希表本身性能的情况下规避rehash造成的性能下降。以下说明本发明的共享目录多级可拓展哈希的结构。
根据本发明的一个实施例,共享目录多级可拓展哈希是一个多级的结构,每一级都是一个独立的可拓展哈希表。但为了避免元数据的过大开销,根据本发明的一个实施例,这些哈希表共享同一个目录。该目录的大小由全局深度控制。
在共享目录多级可拓展哈希中,每一级的桶都分别从0号开始进行编号,所有编号相同的桶构成一个段。每一个段也有编号,其编号与段内所有桶的编号相同。通过利用段,可引入内存预分配,以降低rehash时内存分配的开销。
每一个桶维护各自的局部深度,而段不维护任何与深度有关的信息。在共享目录多级可拓展哈希中,全局深度和局部深度分别表征当前哈希表对应的前缀树的最大深度和当前桶的所处深度。
每一个桶需要维护一个祖先指针,该指针指向该桶最年轻的祖先桶。如果一个桶的祖先指针是有效的,那么当一个线程访问该桶时,应当跳转访问其祖先指针指向的祖先桶。如果一个桶的祖先指针是无效的,那么该桶可被直接访问。祖先指针需要依据分裂方法进行调整。
以上概要介绍了共享目录多级可拓展哈希的结构,以下结合图3具体说明。图3示出了根据本发明的一个实施例的共享目录多级可拓展哈希的结构,在该图中,有两个可拓展哈希,分别是Table 0和Table 1,Table 0和Table 1的全局深度都是2,因此,Table 0和Table 1的共享目录都能存储4个指针,分别是Pointer 0、Pointer 1、Pointer 2以及Pointer 3。Table0和Table 1都具有4个桶,分别是Bkt0、Bkt1、Bkt2以及Bkt3。Table 0和Table 1通过目录共享的方式被聚合为一个哈希表。Table 0和Table 1构成了两层,分别是level 0和level 1。在整个聚合起来的哈希表中,Table0和Table 1编号相同的桶放置在同一个段中,构成4个段,分别是seg 0、seg 1、seg2以及seg3。而每个桶和段都有各自相应的编号。目录存储着指向段的指针。这些指针的编号和段的编号是一一对应的。在实际应用中,可以聚合更多的可拓展哈希表,根据本发明的一个实施例,可以聚合1024个可拓展哈希表。
以下说明共享目录多级可拓展哈希的分裂方法。共享目录多级可拓展哈希通过分裂方法进行扩张,该方法需要维护段、祖先指针的正确性。在共享目录多级可拓展哈希中,共存在三种分裂方法,分别是全分裂(Full split)方法、基础分裂(Basic split)方法以及快速分裂(Fast split)方法。这些方法均需要维护祖先指针、局部深度以及全局深度G的正确性。
全分裂(Full split)方法是当哈希表的目录容量不足时执行,执行过程如图4。图4中以两层的共享目录多级可拓展哈希为例,进行全分裂前,哈希表包含两个段,分别是seg0和seg1。哈希表的全局深度G=1,共享目录包含2G=21=2个指针,每个段包含两个桶。当seg1的黑色桶无空间容纳待插入的键值对时,需要进行分裂,黑色桶即成为分裂桶。此时需要一个伙伴桶来容纳从分裂桶中移走的键值对。但此时伙伴桶并不存在,因此需要分配新的伙伴段并扩张目录以容纳该伙伴段。经过全分裂后,Seg3是新生成的伙伴段,桶403与分裂桶属于同一层,是分裂桶的伙伴桶。哈希表的全局深度由G=1变为G=2,目录容纳的指针个数倍增,由2G=21=2个变为2G=22=4个。新生成的伙伴段中,与分裂桶同一级的伙伴桶可容纳来自分裂桶的键值对。而其余的桶作为后代桶,应将各自的祖先指针指向自己的最年轻祖先,所有对这些后代桶的访问都应被重定向至其祖先指针指向的祖先桶,以避免访问出错。图4中,后代桶402的最年轻祖先桶是桶401,桶402的祖先指针指向401。分裂完成之后,全局深度和分裂桶的局部深度应当加1,伙伴桶深度与分裂桶保持一致,全局深度由1变为2,分裂桶的局部深度由1变为2,伙伴桶的局部深度与分裂桶相同,也为2。
为避免误解,以下对“最年轻的祖先”进行简要说明。对于一个普通的可拓展哈希,除了初始化时已经存在的两个桶,其余桶内的键值对必定有一部分来自于已经存在的桶。例如,图2中,Bucket 1分裂后将一部分键值对迁移至Bucket 3,那么就将Bucket 1称为Bucket 3的祖先桶。这个过程随着装载的数据量不断增多,可以不断往下执行。如果Bucket3分裂,则会产生Bucket 7(图中未示出),并将Bucket 3内的部分键迁移至Bucket7,而Bucket 3内迁移走的键可能是之前来自Bucket 1的,因此Bucket 1和Bucket 3都是Bucket7的祖先桶。但由于Bucket 1的键值对不是直接迁移至Bucket 7的,而是经过Bucket 3迁移至Bucket 7,因此Bucket 3是Bucket 7的最年轻祖先桶。
基础分裂(Basic split)方法是当伙伴段不存在,但目录容量充足时执行,执行过程如图5。图5中,黑色桶为分裂桶,此时缺少一个伙伴段,因此需要分配一个新的伙伴段并加入目录中,然后迁移分裂桶的部分键值对至伙伴桶。图5中,生成的新的伙伴段是seg2,seg2中的桶505与分裂桶属于同一层,是分裂桶的伙伴桶。与全分裂类似,不是伙伴桶的后代桶应当将各自的祖先指针指向各自最年轻的祖先,所有的访问都定向至这些祖先。图5中,在基础分裂前,后代桶502的祖先指针指向桶501;在基础分裂后,后代桶504的祖先指针指向桶503。分裂完成之后,全局深度不变,分裂桶的局部深度加1。伙伴桶深度和分裂桶相同。
快速分裂(Fast split)方法是当一个桶所在的段的伙伴段已经存在的情况下执行,执行过程如图6。图6中,黑色桶601需要进行分裂以扩张容量,黑色桶是分裂桶,灰色桶是分裂桶的后代桶。桶603是桶601的后代桶,桶604是桶602的后代桶。当分裂桶601分裂后,其后代桶603成为伙伴桶,应当依照可拓展哈希的结构要求,将伙伴桶603的祖先指针无效,并将分裂桶601的部分键值对移动至伙伴桶中。桶602与其后代桶604未参与分裂,因此祖先链接关系维持不变。分裂完成后,伙伴桶603即处于生效状态,哈希表的全局深度不变,分裂桶的局部深度加1,伙伴桶深度和分裂桶相同。
以下说明共享目录多级可拓展哈希的并发控制,共享目录多级可拓展哈希采用细粒度锁的并发控制。但与传统的持久化哈希表不同,本发明使用的锁放置于DRAM而非NVM,原因在于:NVM延迟高,寿命短,而锁是一个需要频繁读写的数据结构,将其放置于NVM对性能和NVM的寿命都有严重的影响;并且,本发明中的锁不包含任何哈希表的结构信息,在宕机恢复时不需要使用到锁,因此可以将锁放置于DRAM,提升哈希的性能。
根据本发明的一个实施例,共享目录多级可拓展哈希对桶、段和目录均使用锁进行并发控制。
对于普通操作,一律采用桶级细粒度锁。获取锁后,每一个操作都应重新计算哈希值并确认此时访问的桶是正确的桶。
对于分配新的段,需要获取段锁,分配好新的段并添加至目录后则可释放相应的段锁。
对于目录扩张,需要使用全局锁,在目录扩张完成之后可释放全局锁。
为了减少持久化内存访问和加速桶分裂,根据本发明的一个实施例,本发明进行了进一步的优化,包括分段向量、指纹、内存预分配以及大段。
根据本发明的一个实施例,采用分段向量作为共享目录以减小目录倍增的开销。我们将目录划分为两个部分:元目录和许多固定大小的段指针数组,每个数组成为子目录。目录倍增时,只需要向元目录中添加新的子目录即可。如果元目录大小不足,则对元目录进行扩增。由于元目录的大小经过子目录的压缩是极小的,因此扩增元目录的开销极低。一个1KB的元目录可索引1013量级键值对。
根据本发明的一个实施例,共享目录多级可拓展哈希采用指纹技术(Fingerprinting)加速键值对的查找和比对。指纹可用于在查找过程中筛除不匹配的键值对,避免冗余的键值对比较。一个指纹是一个键值对信息的汇总。根据本发明的一个实施例,取一个键值对的哈希值作为其指纹,只有指纹匹配的两个键需要进行逐字节的比对。另外,由于储存了完整的哈希值,在桶分裂期间,无需读取每一个键值对并重新计算哈希值以判断是否应当迁移这些键值对,这样进一步减少了对持久化内存的访问。
根据本发明的一个实施例,使用持久化的段池存储预先分配好但尚未初始化的段,以降低桶分裂期间等待内存分配造成的阻塞。使用内存预分配并不是困难,但并非所有的哈希方案都可以采用内存预分配。例如,CLevel扩大的容量以指数增长,这意味着预分配内存的容量也指数增长,这样的内存预分配量在哈希表容量达到一定大小时将变得不可接受。
使用大段的好处是可以提高目录的缓存效率,进而提升哈希表的性能。但是受制于其段分裂的巨大开销,现有技术的CCEH不能使用大小超过16KB的段。根据本发明的一个实施例,由于采用细粒度的桶分裂,因此可以使用大小达256KB的段,使得目录大小可进一步缩小,其原因是:总容量一定时,当段的大小增大,则段的数量减少,保存段指针的目录容量也可以随之减少。若采用256KB段,索引1600万键值对时目录大小仅6.7KB,可完全容纳于L1数据cache。
本发明提供一种访问共享目录多级可拓展哈希的方法,根据本发明的一个实施例,访问一个全局深度为G,共计K层的共享目录多级可拓展哈希的流程如下:
计算输入键值对中键的哈希值,记为H;
取H的最低G位为下标,在目录中索引相应的指针,并解引获得相应的段;
取H的最高log2K位为下标,在段内索引一个桶;
在桶内进行线性查找、插入和删除;
访问结束。
根据本发明的一个实施例,对共享目录多级可拓展哈希的访问具体分为读取、插入以及删除操作,以下具体说明各操作的执行方法。
读取、插入、删除操作均包含确认访问的桶和在桶内查找目标键两步。确认桶的方法如下:
记全局深度为G,哈希内共包含K层;
1)计算输入键值对键的哈希值,记为H;
2)取H的最低G位为下标,在目录中索引相应的指针,并解引获得相应的段;
3)取H的最高log2K位为下标,在段内索引一个桶。
在找到需要访问的桶之后,读取、插入以及删除操作分别进行下述操作。
读取方法是在以上确认桶的操作后执行,包括:
1)检查当前桶的祖先指针是否为有效,若为有效,则将当前访问的桶设置为祖先指针所指向的桶;若无效,则保持当前访问的桶不变;
2)获取当前访问桶的读者锁,以保护当前读操作且避免并阻塞其余读操作;
3)在桶内搜索需要找的键值对,搜索时首先比较指纹,如果指纹能够匹配,则进一步逐字节比较输入键和桶内键,完全匹配则返回相应的值,否则返回“键值对不存在”。
插入流程与读取流程类似,包括:
1)检查当前桶的祖先指针是否为有效,若为有效,则将当前访问的桶设置为祖先指针所指向的桶;若无效,则保持当前访问的桶不变;
2)获取写者锁;
3)在桶内寻找空槽时,应当对桶内的键值对进行校验,其原因在于:本发明为减少对持久化内存的读写,被迁移走的哈希表项仍然留在分裂桶中,当该桶需要插入新键值对时,通过比对哈希值和桶编号可发现不属于该桶的键值对,即那些已被迁移走但尚未删除的键值对,那么可以用新插入的键值对代替这些旧键值对。例如,桶局部深度为2,桶编号的二进制是01,如果有一个键的哈希值是110010101010,这个键的最高2位是11,与桶编号不匹配,则说明此键值对是已被迁移但还未删除的键值对。记当前桶的局部深度为L,则对于已存在的键值对,应计算其哈希值最高log2L是否与桶编号相匹配,若不匹配,则可用输入键代替此不匹配的键。若不存在这样的键,则应该寻找空槽。若没有空槽,则需要执行分裂方法。
删除流程与读取流程基本一致,区别在于删除需要获取写者锁,且需要将匹配的键删除。
为了验证本发明的技术效果,发明人对系统进行了测试,测试环境如下:
系统和硬件配置:服务器配置的CPU为Intel Xeon Gold 5215CPU(2.5GHZ),64GB内存,Intel DC Persistent Module 128G×2。系统版本为CentOS Linux release7.6.1810,内核版本为4.18.8,文件系统为ext4。NUMA节点共计两个,每个节点包含20个逻辑CPU。
非易失性内存:使用Intel最新推出的3D XPoint进行评测(Intel Optane DCPersistent Memory)。固件版本为01.02.00.5355。对于使用方法:采用App Direct模式进行设备的配置,以DAX的模式对其挂载ext4文件系统。之后,创建一个80GB的大文件并使用mmap的方式去将其映射到内存中使用。对于所有向非易失性内存中写入的数据,均通过clflush/clwb/clflushopt/ntstore以及mfence去保证其可靠性,防止宕机后数据存在于cache中来不及刷回而导致丢失。
对比系统和工作负载:与四个最新的持久化哈希进行对比,分别是CLevel,CCEH,Dash以及P-CLHT。P-CLHT是一个高效的cache友好的持久化链式哈希。CCEH和Dash则基于可拓展哈希,对可拓展哈希结构进行了修改,都采用段分裂作为rehash的方案。CLevel则采用了逆二叉树的结构,rehash异步进行。
实现:CLevel、CCEH、P-CLHT均使用libpmemobj++实现,因此为了公平比较,本发明也采用libpmemobj++实现。Dash使用libpmemobj实现,该库相比libpmemobj++具有更优的性能,因此发明人也使用该库实现了Dalea-obj,用于与Dash进行单独比较。发明人使用C++标准库内的读写锁作为并发控制,使用std::hash<string>作为哈希函数。
发明人对系统进行压力测试,无重复地插入6400万随机键值对,并测试positiveget(搜索存在的键值对)和negative get(搜索不存在的键值对),采样其带宽和延迟变化,与已有方案P-CLHT,CLevel和CCEH进行对比。
图7示出了根据本发明一个实施例的吞吐测试的测评结果,其中,Dalea表示本发明,P-CLHT,CLevel和CCEH是现有方案。吞吐量的测试方法是记录一段时间内完成的操作总数,用总数除以时间,即得出吞吐量的指标。这个指标衡量给定时间,最多可以完成多少操作。图7中,横轴示出了三种不同的操作,分别是Put、Get-Pos以及Get-Neg。Put指插入键值对的操作,Get-Pos指搜索存在的键值对的操作;Get-Neg指搜索不存在的键值对的操作。纵轴表示吞吐量,单位是MOPS,是指Million Operations Per Second,意思是百万次操作每秒。从图7中可以看出,本发明的Put操作接近1MOPS,Get-Pos操作超过5MOPS,Get-Neg操作超过7MOPS,其吞吐量超出了现有方案。
图8示出了根据本发明一个实施例的平均延迟测试的测评结果,其中,Dalea表示本发明,CLevel和CCEH是现有方案。平均延迟指标的测试方法是采样。采样的方式是将一定量的操作构成一个批次(实验中是20000次),统计这个批次操作的总时间,再用该总时间除以批次的大小(20000),得到每一个操作的平均延迟。这个指标衡量完成一个操作平均需要多长时间。图8中,横轴表示采样批次,纵轴表示平均延迟时间,单位是微秒(us)。从图中可以看出,本发明的平均延迟在20us上下,整体低于现有方案CLevel和CCEH,且波动较小,相对平稳。
图9示出了根据本发明一个实施例的尾延迟测试的测评结果,其中,Dalea表示本发明,CLevel和CCEH是现有方案。本发明测试的尾延迟是P999指标,即99.9percentile,其衡量方法与平均延迟相同,但是计算方法不同。在获得20000次操作的延迟后,需要将这些延迟排序,取最大的0.1%的操作的延迟,计算其平均值作为尾延迟。这个指标衡量了绝大部分操作可以在多长时间内完成,即最慢的操作有多慢。从图9中可以看出,本发明的尾延迟在1ms上下,整体低于现有方案CLevel和CCEH,且波动较小,相对平稳。
应该注意到并理解,在不脱离后附的权利要求所要求的本发明的精神和范围的情况下,能够对上述详细描述的本发明做出各种修改和改进。因此,要求保护的技术方案的范围不受所给出的任何特定示范教导的限制。
Claims (10)
1.一种哈希表的处理方法,所述哈希表为聚合的可拓展哈希表,包括多个可拓展哈希表,每个可拓展哈希表构成所述聚合的可拓展哈希表的一层,所述可拓展哈希表包括不少于一个的桶,所述桶用于存储键值对数据;所述可拓展哈希表具有相同编号的桶构成所述聚合的可拓展哈希表的一个段;所述聚合的可拓展哈希表包括共享目录,所述共享目录用于管理聚合的可扩展哈希表的全局深度以及段的指针;所述处理方法包括:
计算输入键值对中键的哈希值H;
取H的最低G位为下标,在共享目录中索引相应的指针,获得相应的指针所指向的段;
取H的最高log2K位为下标,在段内索引一个桶;
在桶内进行线性查找、插入或删除;
其中,G为哈希表的全局深度,K为哈希表的层数。
2.根据权利要求1所述的处理方法,当插入操作需要一个桶分裂并且共享目录容量不足时,利用全分裂方法扩张哈希表容量,所述全分裂方法包括:
生成一个分裂桶所在段的伙伴段,伙伴段中与分裂桶同层的桶构成分裂桶的伙伴桶;
将共享目录的容量倍增;
将所述伙伴段的指针加入共享目录;
将新的键值对插入伙伴桶中,根据键的哈希值迁移分裂桶中的部分键值对到伙伴桶中;
将伙伴段的其它后代桶的祖先指针指向其最年轻的祖先桶;
将全局深度加1,分裂桶的局部深度加1,将伙伴桶深度设置为与分裂桶相同。
3.根据权利要求1所述的处理方法,当插入操作需要一个桶分裂且共享目录容量充足时,利用基础分裂方法扩张容量,所述基础分裂方法包括:
生成一个分裂桶所在段的伙伴段,伙伴段中与分裂桶同层的桶构成分裂桶的伙伴桶;
将伙伴段的指针加入共享目录;
将新的键值对插入伙伴桶中,根据键的哈希值迁移分裂桶中的部分键值对到伙伴桶中;
将伙伴段的其它后代桶的祖先指针指向其最年轻的祖先桶;
将分裂桶的局部深度加1,将伙伴桶深度设置为与分裂桶相同。
4.根据权利要求1所述的处理方法,当插入操作需要一个桶分裂并且其所在段的伙伴段已经存在时,利用快速分裂方法扩张容量,所述快速分裂方法包括:
将分裂桶对应的后代桶设置为伙伴桶,将伙伴桶的祖先指针设置为无效;
将新的键值对插入伙伴桶中,将分裂桶的部分键值对移至伙伴桶中;
将分裂桶的局部深度加1,将伙伴桶深度设置为与分裂桶相同。
5.根据权利要求1所述的处理方法,其中基于锁访问所述哈希表。
6.根据权利要求5所述的处理方法,所述哈希表存储于NVM,所述锁放置于DRAM。
7.根据权利要求6所述的处理方法,所述锁包括全局锁,所述全局锁用于所述共享目录的扩张;所述锁包括段锁,所述段锁用于分配新的段。
8.根据权利要求6所述的处理方法,所述锁包括用于访问每个所述桶的读者锁,所述读者锁用于在访问桶时保护当前读操作以及避免阻塞其它读操作;所述锁包括每个桶的写者锁,所述写者锁用于在插入操作和/或删除操作时的并发控制。
9.一种计算机可读存储介质,其上存储有计算机程序,其中,该程序被处理器执行时实现根据权利要求1至8任一项所述方法的步骤。
10.一种计算机设备,包括存储器和处理器,在所述存储器上存储有能够在处理器上运行的计算机程序,其特征在于,所述处理器执行所述程序时实现权利要求1至8任一项所述方法的步骤。
Priority Applications (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN202110776008.7A CN113505130B (zh) | 2021-07-09 | 2021-07-09 | 一种哈希表的处理方法 |
Applications Claiming Priority (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN202110776008.7A CN113505130B (zh) | 2021-07-09 | 2021-07-09 | 一种哈希表的处理方法 |
Publications (2)
Publication Number | Publication Date |
---|---|
CN113505130A true CN113505130A (zh) | 2021-10-15 |
CN113505130B CN113505130B (zh) | 2023-07-21 |
Family
ID=78012428
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CN202110776008.7A Active CN113505130B (zh) | 2021-07-09 | 2021-07-09 | 一种哈希表的处理方法 |
Country Status (1)
Country | Link |
---|---|
CN (1) | CN113505130B (zh) |
Cited By (1)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
US12007911B2 (en) | 2022-03-10 | 2024-06-11 | Samsung Electronics Co., Ltd | System and method for efficiently obtaining information stored in an address space |
Citations (4)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN110083601A (zh) * | 2019-04-04 | 2019-08-02 | 中国科学院计算技术研究所 | 面向键值存储系统的索引树构建方法及系统 |
CN111459846A (zh) * | 2020-03-12 | 2020-07-28 | 华中科技大学 | 一种基于混合dram-nvm内存的动态哈希表操作方法 |
US20200272424A1 (en) * | 2019-02-21 | 2020-08-27 | Research & Business Foundation Sungkyunkwan University | Methods and apparatuses for cacheline conscious extendible hashing |
CN112395213A (zh) * | 2020-11-18 | 2021-02-23 | 之江实验室 | 一种基于内存面向热点数据的aceh索引结构及方法 |
-
2021
- 2021-07-09 CN CN202110776008.7A patent/CN113505130B/zh active Active
Patent Citations (4)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
US20200272424A1 (en) * | 2019-02-21 | 2020-08-27 | Research & Business Foundation Sungkyunkwan University | Methods and apparatuses for cacheline conscious extendible hashing |
CN110083601A (zh) * | 2019-04-04 | 2019-08-02 | 中国科学院计算技术研究所 | 面向键值存储系统的索引树构建方法及系统 |
CN111459846A (zh) * | 2020-03-12 | 2020-07-28 | 华中科技大学 | 一种基于混合dram-nvm内存的动态哈希表操作方法 |
CN112395213A (zh) * | 2020-11-18 | 2021-02-23 | 之江实验室 | 一种基于内存面向热点数据的aceh索引结构及方法 |
Non-Patent Citations (2)
Title |
---|
廖名学;范植华;: "基于素数序列的Java哈希表性能优化", 计算机工程与应用, vol. 44, no. 03, pages 108 - 109 * |
金琪;王俊昌;付雄;: "基于智能放置策略的Cuckoo哈希表", 计算机科学, vol. 47, no. 08, pages 80 - 86 * |
Cited By (1)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
US12007911B2 (en) | 2022-03-10 | 2024-06-11 | Samsung Electronics Co., Ltd | System and method for efficiently obtaining information stored in an address space |
Also Published As
Publication number | Publication date |
---|---|
CN113505130B (zh) | 2023-07-21 |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
US11693830B2 (en) | Metadata management method, system and medium | |
US9672235B2 (en) | Method and system for dynamically partitioning very large database indices on write-once tables | |
US8868926B2 (en) | Cryptographic hash database | |
US9043334B2 (en) | Method and system for accessing files on a storage system | |
JP6764359B2 (ja) | 重複除去dramメモリモジュール及びそのメモリ重複除去方法 | |
CN108804031A (zh) | 最佳记录查找 | |
Hu et al. | Halo: A hybrid PMem-DRAM persistent hash index with fast recovery | |
Sarwat et al. | FAST: a generic framework for flash-aware spatial trees | |
US20240028560A1 (en) | Directory management method and system for file system based on cuckoo hash and storage medium | |
KR20210123236A (ko) | 키-값 장치들을 위한 키-값 저장소 아키텍처 | |
Zhang et al. | UniKV: Toward high-performance and scalable KV storage in mixed workloads via unified indexing | |
Zuo et al. | Level hashing: A high-performance and flexible-resizing persistent hashing index structure | |
Ahn et al. | μ*-Tree: An ordered index structure for NAND flash memory with adaptive page layout scheme | |
Tulkinbekov et al. | CaseDB: Lightweight key-value store for edge computing environment | |
Li et al. | Enabling efficient updates in KV storage via hashing: Design and performance evaluation | |
Huang et al. | Revisiting persistent hash table design for commercial non-volatile memory | |
CN113505130B (zh) | 一种哈希表的处理方法 | |
KR20090007926A (ko) | 플래시 메모리에 저장된 데이터의 인덱스 정보 관리 장치및 방법 | |
Wang et al. | The concurrent learned indexes for multicore data storage | |
Chen et al. | Design and implementation of skiplist-based key-value store on non-volatile memory | |
Hu et al. | Parallel multi-split extendible hashing for persistent memory | |
Li et al. | A new dynamic hash index for flash-based storage | |
Lu et al. | Revisiting lsm-tree-based key-value stores for ZNS ssds | |
Wu et al. | Rethinking key-value store for byte-addressable optane persistent memory | |
Zhao et al. | TurboHash: A Hash Table for Key-value Store on Persistent Memory |
Legal Events
Date | Code | Title | Description |
---|---|---|---|
PB01 | Publication | ||
PB01 | Publication | ||
SE01 | Entry into force of request for substantive examination | ||
SE01 | Entry into force of request for substantive examination | ||
GR01 | Patent grant | ||
GR01 | Patent grant |