一种基于哈希表与LSM树的键值存储方法
文献发布时间:2023-06-19 13:46:35
技术领域
本发明公开一种基于哈希表与LSM树的键值存储方法,涉及计算机存储技术领域。
背景技术
数据库作为一种信息技术的基础软件,在信息时代起到至关重要的作用,随着信息技术的快速发展,数据的存储与管理也面临越来越多样化的挑战,日新月异的需求场景对数据库的存储机制、并发访问、存储空间利用以及使用效率等方面都提出了新的要求。传统的单机数据库在海量数据时代受限于性能瓶颈正在被分布式数据库所取代,分布式数据库以良好的可扩展性和相对低廉的硬件投入在业务高速发展场景中动态地满足各项资源需求,为业务发展提供源源不断的动力。
分布式数据库是分布在物理空间离散的计算机网络上、具备分布式事务处理能力、可线性扩展、且在逻辑上统计的数据库,近些年陆续涌现出一些具有代表性的开源分布式数据库,如OceanBase\CockroachDB\TiDB等。分布式数据库水平扩展的能力得益于其底层采用的键值数据库,键值数据库将上层传入的从简单对象到复杂对象的任何内容均转化为键值对进行存储,键值数据库是高度可分区的,从而实现其他类型数据库无法实现的规模水平扩展能力。目前主流的键值存储系统如Facebook公司基于levelDB开发出嵌入式键值存储 RocksDB,RocksDB在levelDB架构基础上针对Flash/RAM存储进行优化,大大降低操作延迟,被广泛的使用到分布式键值存储系统中,如 CockroachDB\TiKV\ZnBase等均使用嵌入式键值存储RocksDB作为存储层。
最早Google公司在其推出的BigTable中首先使用LSM树存储键值数据,基于LSM树的键值存储系统能够将随机写操作转化为顺序写,使得系统可以将大块内存连续刷入磁盘,降低了磁盘寻址延迟,提供了良好的写入性能,尤其适合在基于混合硬盘(Hybrid HardDrive,简称HHD)的写负载高的业务场景下使用。后来Sanjay Ghemawa与Jeff Dean共同开发的持久化键值存储系统—LevelDB以及Facebook公司基于levelDB开源版本二次开发的嵌入式的键值存储系统—RocksDB均使用了LSM树存储键值数据。随着固态盘(Solid StateDisk,简称SSD)技术的成熟并得到广泛使用,基于LSM树的键值存储系统,在大量数据持续写入场景下会不断引发底层数据文件的合并,产生大量I/O操作并造成一定程度的空间放大和写放大,进而降低系统的写性能,无法发挥出SSD并行随机读的能力,反复写入会还会降低SSD使用寿命。
在《WiscKey:Separating Keys from Values in SSD-Conscious Storage》论文中作者提出了面向SSD的数据与索引分离存储的方法,即将数据直接写入磁盘,在LSM树中存储键与数据地址作为索引。数据合并过程减少数据读写量,有效降低空间放大和写放大,LSM树能够将更多索引存储在内存中,有效提升缓存命中并降低读放大。BadgerDB是基于数据与索引分离思想实现的高性能键值存储系统,其整体架构与LevelDB类似,BadgerDB中顺序查找会变成对磁盘的随机读取,会影响其读性能。同时,为了对数据文件中已删除数据条目进行清理,需要遍历数据条目并逐个查询LSM树,该过程需要消耗大量资源进而影响BadgerDB的整体性能。
故现发明一种基于哈希表与LSM树的键值存储方法,以解决上述问题。
发明内容
本发明针对现有技术的问题,提供一种基于哈希表与LSM树的键值存储方法,所采用的技术方案为:一种基于哈希表与LSM树的键值存储方法,所述的方法具体步骤如下:
S1利用键值将数据和索引分开存储;
S2利用哈希索引将键值数据进行封装;
S3在跳表合并中对有序索引中的数据进行合并;
S4利用哈希索引将键值数据进行查询,并将查询结果返回;
S5对数量或大小超过阈值的键值数据日志文件发起数据合并;
S6将数据合并的操作过程与结果进行存储。
所述S1利用键值将数据和索引分开存储的具体步骤如下:
S101上层应用调用键值存储系统的写操作接口;
S102利用哈希函数哈希函数计算出写入键的哈希值。
所述S2利用哈希索引将键值数据进行封装的具体步骤如下:
S201将键值数据封装进键值条目;
S202根据索引哈希值,在内存中的哈希表中插入对应的索引条目。
所述S201将键值数据封装进键值条目,该条目中包含索引键、值、索引哈希值以及元数据,把键值条目按逻辑块写入键值日志文件持久化存储。
所述S202根据索引哈希值,在内存中的哈希表中插入对应的索引条目,该索引条目中包括索引键、索引哈希值、键值数据在数据文件中地址信息以及元数据。
所述S3在跳表合并中对有序索引中的数据进行合并的具体步骤如下:
S301根据元数据中记录的状态判断是否需要保留;
S302需保留,则将有序索引中的数据写入合并后的跳表;
S312不保留,则将有序索引中的数据丢弃。
所述S4利用哈希索引将键值数据进行查询,并将查询结果返回的具体步骤如下:
S401上层应用调用键值存储系统的读操作接口,利用哈希函数计算查询键的哈希值;
S402根据查询键在有序索引中进行查询;
S403查询到,则在哈希索引中根据哈希值查找索引条目;
S402根据索引条目中记录的数据地址信息在键值存储模块中查询对应的键值条目,并将查询结果返回。
所述S5对数量或大小超过阈值的键值数据日志文件发起数据合并的具体步骤如下:
S501判断键值数据日志数量是否超过阈值;
S502在只读模式下的键值数据日志文件中选取待合并文件;
S503遍历键值数据日志文件中的键值条目并根据索引哈希值,
S504在哈希索引中查询对应条目元数据中的数据状态信息,判断该键值条目是否需要保留;
S505若需要保留则写入到新的键值数值日志文件中。
本发明的有益效果为:本发明专利采用数据与索引分离存储的思想,将数据文件写入磁盘完成持久化,分别利用哈希表与LSM树存储索引,哈希索引利用其特性能够实现极低延迟下的写入和随机查询,基于LSM树的顺序索引能够实现任意的范围查询。该发明方案能够实现高性能的键值数据操作,同时具有较低的空间放大和写放大,在任意的查询场景下又不会造成较高的读放大,相比目前流行的键值存储系统具有一定的优越性;有益效果包括:
显著降低键值存储系统读写操作延迟;
显著降低键值存储系统的空间放大、写放大以及读放大;
显著提升键值存储系统数据合并效率;
支持延迟垃圾回收,降低高峰期系统资源消耗;
显著提升键值存储系统的整体性能。
附图说明
为了更清楚地说明本发明实施例或现有技术中的技术方案,下面将对实施例或现有技术描述中所需要使用的附图作一简单地介绍,显而易见地,下面描述中的附图是本发明的一些实施例,对于本领域普通技术人员来讲,在不付出创造性劳动性的前提下,还可以根据这些附图获得其他的附图。
图1是本发明方法实施例的键值存储系统的写入流程;图2是本发明方法实施例的键值存储模块、哈希索引模块与有序索引模块的结构示意图;图3是本发明方法实施例键值存储系统的读取流程图;图4是本发明方法实施例的键值存储系统的数据合并流程图;图5是本发明方法的流程图。
具体实施方式
下面结合附图和具体实施例对本发明作进一步说明,以使本领域的技术人员可以更好地理解本发明并能予以实施,但所举实施例不作为对本发明的限定。
一种基于哈希表与LSM树的键值存储方法,所述的方法具体步骤如下:
S1利用键值将数据和索引分开存储;
S2利用哈希索引将键值数据进行封装;
S3在跳表合并中对有序索引中的数据进行合并;
S4利用哈希索引将键值数据进行查询,并将查询结果返回;
S5对数量或大小超过阈值的键值数据日志文件发起数据合并;
S6将数据合并的操作过程与结果进行存储;
进一步的,所述S1利用键值将数据和索引分开存储的具体步骤如下:
S101上层应用调用键值存储系统的写操作接口;
S102利用哈希函数哈希函数计算出写入键的哈希值;
进一步的,所述S2利用哈希索引将键值数据进行封装的具体步骤如下:
S201将键值数据封装进键值条目;
S202根据索引哈希值,在内存中的哈希表中插入对应的索引条目。
进一步的,所述S201将键值数据封装进键值条目,该条目中包含索引键、值、索引哈希值以及元数据,把键值条目按逻辑块写入键值日志文件持久化存储;
进一步的,所述S202根据索引哈希值,在内存中的哈希表中插入对应的索引条目,该索引条目中包括索引键、索引哈希值、键值数据在数据文件中地址信息以及元数据;
进一步的,所述S3在跳表合并中对有序索引中的数据进行合并的具体步骤如下:
S301根据元数据中记录的状态判断是否需要保留;
S302需保留,则将有序索引中的数据写入合并后的跳表;
S312不保留,则将有序索引中的数据丢弃;
进一步的,所述S4利用哈希索引将键值数据进行查询,并将查询结果返回的具体步骤如下:
S401上层应用调用键值存储系统的读操作接口,利用哈希函数计算查询键的哈希值;
S402根据查询键在有序索引中进行查询;
S403查询到,则在哈希索引中根据哈希值查找索引条目;
S402根据索引条目中记录的数据地址信息在键值存储模块中查询对应的键值条目,并将查询结果返回;
进一步的,所述S5对数量或大小超过阈值的键值数据日志文件发起数据合并的具体步骤如下:
S501判断键值数据日志数量是否超过阈值;
S502在只读模式下的键值数据日志文件中选取待合并文件;
S503遍历键值数据日志文件中的键值条目并根据索引哈希值,
S504在哈希索引中查询对应条目元数据中的数据状态信息,判断该键值条目是否需要保留;
S505若需要保留则写入到新的键值数值日志文件中;
键值存储系统的写入流程如图1所示;上层应用调用键值存储系统的写操作接口,利用哈希函数计算出写入键的哈希值,将键值数据封装进键值条目,该条目中包含索引键、值、索引哈希值以及元数据,把键值条目按逻辑块写入键值日志文件持久化存储;根据索引哈希值,在内存中的哈希表中插入对应的索引条目,该索引条目中包括索引键、索引哈希值、键值数据在数据文件中地址信息以及元数据;同时,在基于LSM树的有序索引结构的跳表中插入对应的索引条目,该条目包含索引键与元数据;如果是删除键值数据,在将键值条目写入键值存储模块后,在哈希索引与有序索引中查找该索引键,如果查到该索引键则在对应的数据结构中将该条目标记为删除状态;为了提升查询效率,哈希索引与有序索引均是存储在内存中,为了避免系统故障时发生数据丢失,需要定期将索引数据写入磁盘,并在元数据管理模块中更新各自索引数据的回放点,进而有效降低故障恢复时索引数据回放的时延;哈希索引中数据的合并是在索引条目持久化过程中进行的,根据元数据中记录的数据状态判断索引条目是否需要持久化;有序索引中数据的合并是在跳表合并的过程中进行的,同样是根据元数据中记录的状态判断是否需要保留,如需保留则写入合并后的跳表否则直接丢弃;每次哈希索引与有序索引的合并与落盘操作及结果都会由元数据管理模块进行记录;上述涉及的键值存储模块、哈希索引模块与有序索引模块的详细结构如图2所示;
键值存储系统的读取流程如图3所示;上层应用调用键值存储系统读操作接口时,利用哈希函数计算出查询键的哈希值,根据查询键在有序索引中进行查询,若在有序索引中查到该键,再根据哈希值在哈希索引中查找索引条目,根据索引条目中记录的数据地址信息在键值存储模块中查询对应的键值条目,并将查询结果返回;基于LSM树的顺序索引高效地实现了范围查询功能,哈希索引利用其特性能够实现极低延迟下随机查询;由于顺序索引与哈希索引中仅仅记录少量数据,业务数据在TB量级下也能将索引数据完全存储在内存中,大大提升键值存储系统的读取效率;
键值存储系统的数据合并流程如图4所示;数据合并流程由元数据管理模块发起,元数据管理模块中记录键值日志文件的数量与大小,当文件数量或大小超过阈值后便会发起数据合并;键值存储模块会从只读模式下的键值日志文件中选取待合并文件,遍历键值日志文件中的键值条目并根据索引哈希值到哈希索引中查询对应条目元数据中的数据状态信息进而判断该键值条目是否需要保留,若需要保留则写入到新的键值日志文件中,若不需要则直接跳过;键值日志文件序号是递增,并且不会被复用;键值日志文件合并完毕后将操作过程与结果记录到元数据管理模块,进行持久化存储。
最后应说明的是:以上实施例仅用以说明本发明的技术方案,而非对其限制;尽管参照前述实施例对本发明进行了详细的说明,本领域的普通技术人员应当理解:其依然可以对前述各实施例所记载的技术方案进行修改,或者对其中部分技术特征进行等同替换;而这些修改或者替换,并不使相应技术方案的本质脱离本发明各实施例技术方案的精神和范围。
- 一种基于哈希表与LSM树的键值存储方法
- 一种面向LSM树的键值存储方法和存储系统