数据存储系统和数据读写方法与流程

文档序号:11949878阅读:274来源:国知局
数据存储系统和数据读写方法与流程

本发明属于互联网技术领域,具体地说,涉及一种数据存储方法、数据存储系统和数据读写方法、用于数据读写的客户端及用于数据读写的系统。



背景技术:

近年来互联网公司需要备份、归档的数据呈爆发趋势。出于成本的考虑,磁带一直是备份和归档系统以及虚拟机主存储系统的主要存储介质。但是磁带的存放环境要求高而寿命又较短,一般每隔4-5年就需要转存到新的磁带上。当磁带的数量累计到几万甚至几十万后,转存工作将成为一场梦魇。

随着磁盘技术的发展,容量已经达到了6T甚至8T,其容量价格比逐渐与磁带接近,而且磁盘相对磁带的优势是支持随机访问,这使得重复数据删除技术的应用成为可能,通过结合磁盘技术和重复数据删除技术,可以大大节约备份归档的成本。

目前市场上已有的重复数据删除商用产品,比如EMC DD990、HP StoreOnce B6200设备、SEPATON DeltaStor软件等等,基本属于单机模式,可伸缩性非常有限,最大可用容量1.6PB,最大的吞吐量31TB/h(8.8G/s),无论从容量还是性能上,根本无法满足互联网公司的存储需求。

中国科学院计算技术研究所的《一种支持海量数据备份的可扩展分布式重复数据删除系统》,针对单机模式的不足,在去重系统的扩展性和去重效率这两个方面提出了分布式布隆过滤器(bloomfilter)用于分布式去重系统中去重节点的数据路由,并提出了基于取样机制的指纹查询用以提高指纹查询速度,实现了分布式重复数据删除系统3D-deduper。 以下简称为方案一。

EMC公司也在其单机(single-node)模式的基础上研发了集群化去重存储系统(cluster deduplication storage system)。其做法是增加几台备份服务器,负责对数据流进行切块、计算数据块的指纹,然后打包成一个超级块(super chunk)并根据一定的策略路由到某个去重节点进行处理。以下简称方案二。

以上两种方案从严格意义来讲,不能称为分布式系统,而是集群系统。集群系统的基本思路是在多个可靠的单节点之间进行任务的负载均衡。而分布式系统的基本思路是在多个不可靠的单节点之间进行数据分布(当数据分布均衡,则自然实现了任务的负载均衡),并且利用多副本或者校验码等手段来保障可靠性。

在上述两个方案中,集群系统的指纹库是分散管理的,虽然采用了一定的措施尽量将之前出现过的数据块及其指纹路由到之前负责处理的去重节点上,但是难以避免被路由到一个从未处理该数据块的去重节点上,从而被误判为新的数据块并被重复保存。方案一更是对指纹采用了基于采样的稀疏索引,进一步加重了数据块被误判的概率。哪怕只有2%的误判,对于100PB甚至更大数量级的系统来说,也是不可接受的。



技术实现要素:

有鉴于此,本申请提供一种数据存储方法、数据存储系统和数据读写方法、用于数据读写的客户端及用于数据读写的系统,解决了在大数量级的去重系统中由于指纹信息的分散管理而造成的误判概率较大的技术问题。

为了解决上述技术问题,本申请公开了一种数据存储方法,应用于包括中心节点和去重节点的数据存储系统;所述数据存储方法,包括:所述中心节点根据预设策略将每个桶(Bucket)分配到对应的去重节点;所述中心节点根据Bucket与去重节点的对应关系创建路由表,并同步所述路由表到每个去重节点;所述去重节点根据所述路由表,存储每个所述分配到的Bucket所对应的指纹信息和所述指纹信息代表的数据块。

所述去重节点根据所述路由表,存储每个所述分配到的Bucket所对应的指纹信息和所述指纹信息代表的数据块包括:所述去重节点为每个所述分配到的Bucket分别创建对应的容器(Container)文件;所述去重节点在每个所述分配到的Bucket中保存对应的指纹信息,在与每个所述分配到的Bucket对应的Container文件中保存所述指纹信息代表的数据块。

所述去重节点判断所述Container文件的大小是否大于预设阈值;当所述Container文件的大小大于预设阈值时,所述去重节点将所述Container文件归档至后台服务器。

所述中心节点根据预设策略将每个Bucket分配给对应的去重节点包括:所述中心节点将每个Bucket分配到多个对应的去重节点,在所述多个对应的去重节点中确定一个主节点和至少一个备用节点。

所述中心节点判断每个去重节点是否可用,或者是否增加了新的去重节点;当判断出某个去重节点不可用,或者增加了新的去重节点时,所述中心节点重新分配所述每个Bucket;所述中心节点更新所述路由表并同步到每个去重节点;所述去重节点根据所述更新后的路由表进行数据迁移。

所述去重节点根据所述更新后的路由表进行数据迁移包括:所述主节点根据所述更新后的路由表发起所述数据迁移。

所述当判断出某个去重节点不可用时,所述中心节点重新分配所述每个Bucket包括:当判断出所述主节点不可用时,所述中心节点从所述至少一个备用节点中重新确定出一个主节点;所述去重节点根据所述更新后的路由表进行数据迁移包括:所述重新确定的主节点根据所述更新后的路由表发起所述数据迁移。

每个所述去重节点包括一个指纹信息库,所述指纹信息库是存储于固态硬盘上的布谷鸟哈希映射表,包括所述去重节点的每个Bucket所对应的指纹信息和所述指纹信息代表的数据块的存储信息。

所述固态硬盘上同时运行M个布谷鸟哈希映射表,并同时使用N个布谷鸟哈希函数;其中,M×N=128。

所述固态硬盘上同时运行32个布谷鸟哈希映射表,并同时使用4路布 谷鸟哈希函数。

为了解决上述技术问题,本申请还公开了一种数据读写方法,包括:将数据切分为多个数据块并分别计算每个数据块的指纹信息;确定所述每个数据块的指纹信息所对应的Bucket;根据从中心节点获取的路由表,确定与所述Bucket对应的去重节点;发送指纹查询请求至与所述Bucket对应的去重节点,所述指纹查询请求包括数据块的指纹信息;接收到与所述Bucket对应的去重节点返回的未查询到的指纹信息;上传所述未查询到的指纹信息及其代表的数据块至与所述Bucket对应的去重节点。

所述确定所述每个数据块的指纹信息所对应的Bucket包括:将所述指纹信息与所述Bucket的总数量进行取模运算,根据所述取模运算的结果确定所述指纹信息所对应的Bucket。

所述方法还包括:当所述未查询到的指纹信息及其代表的数据块全部上传完毕时,上传所述数据的映射文件至去重节点,所述映射文件包括所述数据的每个数据块的指纹信息,所述每个数据块的指纹信息按照数据块的切分顺序排列。

所述上传所述数据的映射文件至去重节点,包括:将所述映射文件切分为多个数据块并分别计算映射文件的数据块的哈希值;确定所述映射文件的数据块的哈希值所对应的Bucket;根据所述路由表确定与所述映射文件的数据块的哈希值对应的Bucket所对应的去重节点;上传所述映射文件的数据块和相应的哈希值至与所述映射文件的数据块的哈希值对应的Bucket所对应的去重节点。

所述将所述映射文件切分为多个数据块包括:将所述映射文件的头信息切分为所述多个数据块中的第一个数据块;所述映射文件的头信息包括所述映射文件的总大小、所述多个数据块的总数量等信息。

所述方法还包括:从去重节点获取所述数据的映射文件;根据所述映射文件中所述数据的每个数据块的指纹信息从去重节点获取所述数据的每个数据块;按照所述每个数据块的指纹信息在所述映射文件中的顺序拼接出所述数据。

所述从去重节点获取所述数据的映射文件包括:根据所述映射文件的名 称和数据块序号从去重节点获取所述映射文件的每个数据块;将所述映射文件的每个数据块拼接为所述数据的映射文件。

所述根据从中心节点获取的路由表,确定与所述Bucket对应的去重节点包括:当首次存储数据时,从所述中心节点获取路由表;根据从中心节点获取的路由表,确定与所述Bucket对应的去重节点。

所述根据从中心节点获取的路由表,确定与所述Bucket对应的去重节点还包括:发送请求包至与所述Bucket对应的去重节点;接收与所述Bucket对应的去重节点返回的响应包,所述响应包包括路由表的版本信息;判断所述响应包中的路由表的版本信息与所述从中心节点获取的路由表的版本信息是否相同;当所述响应包中的路由表的版本信息与所述与从中心节点获取的路由表的版本信息相同时,根据所述从中心节点获取的路由表确定与所述Bucket对应的去重节点;当所述响应包中的路由表的版本信息与从中心节点获取的路由表的版本信息不相同时,从所述中心节点获取更新后的路由表;根据所述更新后的路由表重新确定与所述Bucket对应的去重节点。

为了解决上述技术问题,本申请还公开了一种数据读写方法,包括:

中心节点发送路由表至客户端,所述路由表包括Bucket与去重节点之间的对应关系;去重节点接收到所述客户端的指纹查询请求,所述指纹查询请求包括与所述去重节点分配到的Bucket对应的指纹信息;所述去重节点对所述指纹信息进行查询,将未查询到的指纹信息返回至所述客户端;所述去重节点接收到所述客户端上传的所述未查询到的指纹信息及其所代表的数据块。

所述方法还包括:所述去重节点在所述分配到的Bucket中保存所述未查询到的指纹信息,在与所述分配到的Bucket对应的Container文件中保存所述数据块,所述去重节点向所述客户端返回所述数据块保存成功的消息。

所述去重节点向所述客户端返回所述数据块保存成功的消息之前,所述方法还包括:所述去重节点将所述未查询到的指纹信息及其代表的数据块备份到备用节点。

所述方法还包括:所述去重节点保存所述客户端上传的映射文件的数据块和相应的哈希值。

所述保存所述客户端上传的映射文件的数据块和相应的哈希值包括:在所述对应的Bucket所对应的Container文件中,保存所述映射文件的数据块;在所述对应的Bucket中,保存所述映射文件的数据块的哈希值以及第一存储信息。

所述第一存储信息包括:保存所述映射文件的数据块的Container文件的名称,所述映射文件的数据块在所述Container文件中的偏移量和所述映射文件的数据块的大小。

所述方法还包括:所述去重节点接收到所述客户端获取所述映射文件的数据块的请求;所述去重节点发送所述映射文件的数据块至所述客户端;所述去重节点接收到所述客户端获取所述映射文件中的每个指纹信息所代表的数据块的请求;所述去重节点发送所述每个指纹信息所代表的数据块至所述客户端。

所述去重节点发送所述每个指纹信息所代表的数据块至所述客户端包括:所述去重节点根据所述指纹信息确定所述数据块的第二存储信息,所述第二存储信息包括保存所述数据块的Container文件的名称,所述数据块在所述Container文件中的偏移量和所述数据块的大小;所述去重节点根据所述Container文件的名称判断所述Container文件是否已归档至后台服务器;当所述Container文件已归档至后台服务器时,所述去重节点根据所述数据块在所述Container文件中的偏移量和所述数据块的大小从所述后台服务器获取所述数据块并发送至所述客户端;当所述Container文件仍保存在本地时,所述去重节点根据所述数据块在所述Container文件中的偏移量和所述数据块的大小从本地获取所述数据块并发送至所述客户端。

所述中心节点发送路由表至客户端包括:当所述客户端首次存储数据时,所述中心节点接收到所述客户端的路由表请求;所述中心节点发送路由表至所述客户端。

所述中心节点发送路由表至客户端还包括:所述去重节点接收到所述客户端的请求包:所述去重节点发送响应包至所述客户端,所述响应包包括所述去重节点保存的路由表的版本信息;当所述客户端保存的路由表的版本信息与所述所述去重节点保存的路由表的版本信息不一致时,所述中心节点接 收到所述客户端的路由表请求;所述中心节点发送更新后的路由表至所述客户端。

所述去重节点对所述指纹信息进行查询,将未查询到的指纹信息返回至所述客户端包括:所述去重节点通过布隆过滤器判断所述指纹信息是否存在;当通过布隆过滤器判断出所述指纹信息不存在时,确定所述指纹信息为未查询到的指纹信息;当通过布隆过滤器判断出所述指纹信息存在时,在指纹信息库中查询所述指纹信息是否存在;当在指纹信息库中查询到所述指纹信息时,确定所述指纹信息已存在;当在指纹信息库中未查询到所述指纹信息时,确定所述指纹信息为未查询到的指纹信息。

为了解决上述技术问题,本申请还公开了一种数据存储系统,包括:中心节点和一个或多个去重节点,其中,所述中心节点,用于根据预设策略将每个桶(Bucket)分配到对应的去重节点,并根据Bucket与去重节点的对应关系创建路由表,并同步所述路由表到每个去重节点;所述去重节点,用于根据所述路由表,存储每个所述分配到的Bucket所对应的指纹信息和所述指纹信息代表的数据块。

为了解决上述技术问题,本申请还公开了一种用于数据读写的客户端,包括:切分计算模块,用于将数据切分为多个数据块并分别计算每个数据块的指纹信息;桶确定模块,用于确定所述每个数据块的指纹信息所对应的Bucket;节点确定模块,用于根据从中心节点获取的路由表,确定与所述Bucket对应的去重节点;请求发送模块,用于发送指纹查询请求至与所述Bucket对应的去重节点,所述指纹查询请求包括数据块的指纹信息;信息接收模块,用于接收到与所述Bucket对应的去重节点返回的未查询到的指纹信息;数据上传模块,用于上传所述未查询到的指纹信息及其代表的数据块至与所述Bucket对应的去重节点。

为了解决上述技术问题,本申请还公开了一种用于数据读写的系统,包括:中心节点和去重节点,其中,所述中心节点,用于发送路由表至客户端,所述路由表包括Bucket与去重节点之间的对应关系;所述去重节点,用于接收到所述客户端的指纹查询请求,所述指纹查询请求包括与所述去重节点分配到的Bucket对应的指纹信息;对所述指纹信息进行查询,将未查询到的指 纹信息返回至所述客户端;接收到所述客户端上传的所述未查询到的指纹信息及其所代表的数据块。

与现有技术相比,本申请可以获得包括以下技术效果:实现了对100PB以上级别的原始数据以及100TB以上级别的指纹信息的全局去重存储管理,具有非常高的可扩展性,系统中加入新的去重节点后中心节点能够根据预设策略重新进行数据分布,去重节点自动完成数据迁移,使系统的性能和容量都能够便捷的进行扩展。

当然,实施本申请的任一产品必不一定需要同时达到以上所述的所有技术效果。

附图说明

此处所说明的附图用来提供对本申请的进一步理解,构成本申请的一部分,本申请的示意性实施例及其说明用于解释本申请,并不构成对本申请的不当限定。在附图中:

图1是本申请实施例的一种数据存储系统(用于数据读写的系统)的结构示意图;

图2是本申请实施例的路由表示意图;

图3是本申请实施例的一种数据读写方法的流程示意图;

图4是本申请实施例的一种数据读写方法的流程示意图;

图5是本申请实施例的一种用于数据读写的客户端的结构示意图。

具体实施方式

以下将配合附图及实施例来详细说明本发明的实施方式,藉此对本发明如何应用技术手段来解决技术问题并达成技术功效的实现过程能充分理解并据以实施。

图1是本申请实施例提供的数据存储系统(以下简称“系统”),包括中心节点10和去重节点11,中心节点10与去重节点11耦接。在系统中, 中心节点10负责对多个去重节点11的分布式管理和系统内的数据分布以及副本管理。去重节点11负责对数据块、以及数据块的指纹信息和存储信息进行管理和保存,并在中心节点10的分布式管理下完成数据的复制和迁移。去重节点11具备抽象的存储引擎层,可以很方便的添加新存储引擎。

系统对数据块的管理以桶(Bucket)为单位,Bucket是系统中的一个逻辑概念,为每个Bucket分配一个Bucket编号,该Bucket编号用于与各个数据块的指纹信息通过预设的哈希算法建立对应关系,从而将数据块按照Bucket编号分别存储并建立数据块与存储文件之间的对应关系。系统的中心节点通过Bucket对系统保存的数据块和数据块的指纹信息进行全局管理。

中心节点根据预设策略将每个Bucket分配到对应的去重节点,该预设策略可以是负载均衡策略。例如,中心节点获取各个去重节点的负载数据,通过负载数据的实时变化来确定每个去重节点的当前负载状况,将Bucket优先分配到当前负载较低的去重节点,通过数据分布均衡实现各个去重节点的负载均衡。该预设策略可以是位置安全策略,例如,中心节点根据数据的涉密性或者客户端的权限将不同的Bucket分配到不同的去重节点,使不同涉密级别或者不同权限的客户端数据保存在不同的去重节点中。

中心节点将各个Bucket分配到对应的去重节点,通过Bucket编号以及去重节点的标识来建立Bucket与去重节点的对应关系,并根据该对应关系创建路由表。该路由表可看作一个映射表,记录了Bucket与去重节点之间的映射关系,图2是本申请实施例中路由表的示例图,其中,横向表头的数字代表Bucket编号,纵向表头的数字代表Bucket的拷贝标识,表格中的字母分别代表不同的去重节点。如图2所示,其中编号为0的Bucket,0号拷贝被分配到去重节点D,1号拷贝被分配到去重节点A;编号为1的Bucket,0号拷贝被分配到去重节点A,1号拷贝被分配到去重节点B。图2用于对本申请实施例中的路由表进行示例性说明,并不构成对本申请保护范围的限制,系统中可设置任意多个去重节点,每个去重节点可以被分配到多个Bucket,每个Bucket也可以有一个或多个备份并备份在不同的去重节点。

中心节点创建路由表之后,将该路由表同步到每个去重节点。系统中的各个去重节点根据路由表确定被分配到本地的Bucket,存储与被分配到本地 的Bucket对应的指纹信息和指纹信息代表的数据块。去重节点保存每个Bucket对应的指纹信息和指纹信息代表的数据块时,为每个分配到的Bucket创建对应的容器(Container)文件,在每个Bucket中保存对应的指纹信息,在与Bucket对应的Container文件中保存指纹信息代表的数据块。而指纹信息与Bucket之间的对应关系,是通过指纹信息对系统内部的Bucket总数进行取模运算,根据运算结果确定指纹信息对应的Bucket编号,这一运算过程通常由向系统存储数据的客户端来完成。当与Bucket对应的指纹信息越来越多时,相应的Container文件中保存的数据块随之增多,Container文件占用的存储空间也随之增大,为了确保每个去重节点能够存储多个Bucket的拷贝并且控制去重节点的负载,当一个Bucket对应的Container文件的大小超过预设阈值时,去重节点将该Container文件归档到后台服务器12,如图1中所示,每个去重节点都与后台服务器12耦接,去重节点再接收到相应的数据块时,存储到位于后台服务器12的Container文件中。

中心节点根据预设策略将每个Bucket分配给对应的去重节点时,可以将每个Bucket分配到多个对应的去重节点,使每个Bucket在系统中存在多个拷贝,并且为每个拷贝分配不同的拷贝标识。例如图2所示的路由表中,中心节点为每个Bucket分配到两个去重节点,每个Bucket在不同的去重节点的拷贝分别具有的拷贝标识0和1。

中心节点将每个Bucket分配到多个去重节点时,在该多个去重节点中确定一个主节点和至少一个备用节点。中心节点可根据拷贝标识确定主节点和备用节点,在每个Bucket的多个拷贝标识中确定一个主拷贝标识,其他拷贝标识均为备用拷贝标识,例如,将拷贝标识为0的拷贝做为每个Bucket的主拷贝,其他拷贝标识的拷贝均为备用拷贝。而在所有去重节点中,将某个Bucket的拷贝标识为0的拷贝所在的去重节点确定为该Bucket的主节点,该Bucket的其他拷贝所在的去重节点均为该Bucket的备用节点。以防止某个去重节点不可用时,该去重节点上的Bucket的数据存储和读写都将无法进行。Bucket的每一个拷贝包括该Bucket对应的指纹信息和保存该指纹信息代表的数据块的Container文件。

中心节点会判断每个去重节点是否可用,或者判断系统内部是否增加了 新的去重节点。中心节点通过与去重节点之间的心跳信息来判断每个去重节点是否可用或者是否增加了新的去重节点。中心节点判断出某个去重节点不可用或者系统内增加了新的去重节点时,中心节点重新分配每个Bucket,系统内部Bucket与去重节点的映射关系将发生变化。当某个去重节点不可用时,中心节点根据预设策略将与该去重节点对应的Bucket重新分配到其他去重节点中;当系统内增加了新的去重节点时,中心节点根据预设策略将系统内的Bucket进行重新分配。上述两种情形都会使系统内部Bucket与去重节点的映射关系发生变化,中心节点根据变化后的Bucket与去重节点的映射关系更新路由表,并将更新后的路由表同步到每个去重节点。由于Bucket分配到的去重节点发生了变化,系统内的去重节点将根据更新后的路由表进行数据迁移。

由被分配到的去重节点发生变化的Bucket的主节点发起该数据迁移。例如,在路由表中,编号为1的Bucket的0号拷贝(主拷贝)由去重节点A变为去重节点B,则由该去重节点A发起编号为1的Bucket的0号拷贝向去重节点B的数据迁移,去重节点B再根据路由表判断该编号为1的Bucket的其他备用节点是否发生了变化,如果发生了变化,例如从去重节点D变为去重节点E,则再将编号为1的Bucket中的数据备份到去重节点E,去重节点E的编号为1的Bucket的拷贝标识为备用拷贝标识。数据迁移完成后每个去重节点会根据更新后的路由表删除与本地不存在映射关系的Bucket的数据。当做为某个Bucket的主节点的去重节点不可用时,中心节点在该Bucket的备用节点中重新确定一个主节点,由重新确定的主节点根据更新后的路由表发起有关该Bucket的数据迁移。例如,编号为1的Bucket的主节点——去重节点A不可用时,中心节点从编号为1的Bucket的备用节点——去重节点B和去重节点C中,确定去重节点B为编号为1的Bucket的主节点,则去重节点B中编号为1的Bucket的拷贝的拷贝标识变为主拷贝标识(例如0),更新后的路由表中编号为1的Bucket的备用节点为去重节点C和去重节点D,则由去重节点B将编号为1的Bucket的数据备份到去重节点D。

每个去重节点内部构建有一个指纹信息库。该指纹信息库包括去重节点的每个Bucket所对应的指纹信息和指纹信息代表的数据块的存储信息。该指 纹信息库可以采用Key-Value Store的形式,以指纹信息为Key,该指纹信息代表的数据块的存储信息为Value。在系统的数据读写过程中,涉及到大量的指纹信息查询和比对处理,在每个去重节点中采用布隆过滤器来承担部分查询请求,由于布隆过滤器的存在漏查的可能,还有大量请求进一步需要由指纹信息库来完成。因此对指纹信息库(Key-Value Store)的读取性能要求非常高。通常对于小型的Key-Value Store来说,可以把Key-Value对(Key-Value Pair)以预设形式,比如log-structure,存放在普通硬盘上,然后在内存中建立索引,以快速地访问硬盘上的Key-Value Pair。但由于本系统应用于100PB级别以上的数据存储,指纹信息和存储信息量非常大(100PB的原始数据,对应大约50TB的指纹信息和存储信息),因此此时无法在设备内存中建立索引。因此本申请的发明人发现,完全可以在固态硬盘(Solid State Drives,SSD)上实现一个哈希表来存放指纹信息库的全部Key-Value Pair。这个存储于固态硬盘上的哈希表是布谷鸟哈希映射表,由于去重节点的首先通过布隆过滤器进行指纹信息的查询比对,存在由于哈希冲突而漏查的情形,布谷鸟哈希映射表是一种能够处理哈希冲突的方式,它的基本思路是使用两个不同的哈希函数来计算Key存放的位置,(1)如果两个位置都空闲,则选择一个位置插入;(2)如果只有一个位置空闲,则插入到这个空闲位置;(3)如果两个位置都不空闲,随机选择两者之一的位置并将该位置上的Key踢出,然后计算被踢出的Key的另一个哈希值对应的位置进行插入,如果这个位置为空则插入,如果不为空则再踢出这个位置上的Key,如此继续一直找到空闲位置。显然这种方式有可能产生无限循环,因此通常设定一个最大的查找次数,当达到这个最大值时,认为该哈希表已满。发明人选择布谷鸟哈希,是因为系统在查询Key时的输入输出次数通常设置为常量。

普通布谷鸟哈希映射表只有49%的利用率,所以通常采用布谷鸟哈希的两种主要的变形:1)增加hash函数的个数;2)增加每个位置可以存放Key的个数。这两种变形都可以用来提高布谷鸟哈希映射表的利用率。本申请的发明人选择了murmur2哈希函数作为基本的哈希函数,并通过设置不同的种子,相同的Key值可以产生不同的哈希值。

由于基于NVMe(NonVolatile Memory express,高速非易失存储器)协议的固态硬盘(SSD)底层都是以4K的页(Page)为基本单位,因此指纹信息库进行操作的时都是以4K为大小进行读写操作。指纹信息库中的Key-Value Pair大小是256Byte,则一个4K的Page可以存储16个指纹信息。那么该布谷鸟哈希映射表,每个位置存放16个Key-Value Pair,每个Key-Value Pair在Page内是按插入顺序写入,并不按Key来排序,这种无序的方式可以避免在固态硬盘上排序带来的开销。根据本申请的发明人的实际测试,采用128并发(队列深度×job数=128)的异步模式,可以充分挖掘NVMe的IOPS(Input/Output Operations Per Second,每秒进行读写(I/O)操作的次数)的能力(450K),为了产生这么大的并发,本申请的发明人在两个方面进行了优化:1、在一块NVMe硬盘上运行多个布谷鸟哈希映射表形式的Key-Value Store;2、在一块NVMe硬盘上采用多个布谷鸟哈希函数,并且采用异步读取方式;并且需要同时满足:每块固态硬盘上运行的布谷鸟哈希映射表的个数乘以布谷鸟哈希函数的个数等于128。本申请的发明人发现,当布谷鸟哈希函数变多时,单个布谷鸟哈希映射表的QPS(每秒查询率,Query Per Second)下降十分明显,从4路布谷鸟哈希函数变为8路布谷鸟哈希函数时,QPS下降了一半,而当布谷鸟哈希函数太少时,布谷鸟哈希映射表空间利用率则下降明显。综合权衡考虑性能和空间利用率,本申请的发明人选择4路布谷鸟哈希函数,其空间利用率能够达到98.66%。由此,需要在一块NVMe硬盘上运行32个布谷鸟哈希映射表。而分成多个哈希映射表的另外一个好处是能够降低该指纹信息库的锁定粒度。

下面对客户端与上述数据存储系统进行数据读写操作的过程做进一步说明。客户端向系统写入数据时,如图3所示,该过程包括以下步骤。

在步骤S201中,客户端将数据切分为多个数据块并分别计算每个数据块的指纹信息。

采用冲突率较低的哈希算法计算出每个数据块的哈希值做为指纹信息,例如SHA-1,MD5等哈希算法。

在步骤S202中,客户端确定每个数据块的指纹信息所对应的Bucket。

客户端将数据块的指纹信息与系统内的Bucket总数进行取模运算,根据 取模运算的结果与Bucket编号进行匹配,从而确定该指纹信息对应的Bucket。例如,数据块的哈希值为a,系统内的Bucket总数为p,进行取模运算a%P,取模运算结果为2,则该数据块的指纹信息对应编号为2的Bucket。

在步骤S203中,客户端根据从中心节点获取的路由表,确定与Bucket对应的去重节点。

客户端根据保存的路由表确定指纹信息对应的Bucket所在的去重节点,当客户端首次向系统写入数据时,会先向中心节点请求路由表。例如,数据块的指纹信息对应编号为2的Bucket,在路由表中,编号为2的Bucket被分配到去重节点A和去重节点B,其中去重节点A为编号为2的Bucket的主节点,去重节点B为编号为2的Bucket的备用节点,因此需要将该数据块的指纹信息发送到去重节点A进行指纹查询。

在步骤S204中,客户端发送指纹查询请求至与Bucket对应的去重节点,该指纹查询请求包括数据块的指纹信息。

客户端包括读取线程、发送线程和逻辑处理线程。多个读取线程分别负责该数据的不同部分进行切块并计算数据块的指纹信息,然后将指纹信息暂存到查询请求队列中,每个读取线程包括多个查询请求队列,每个查询请求队列对应着一个Bucket编号。客户端会将对应同一个Bucket的指纹信息暂存到同一个查询请求队列中。当查询请求队列中的数据超过一定量或者是该查询请求队列的延迟到期后,读取线程将查询请求放置到发送线程的缓冲区。

发送线程根据每个查询请求队列对应的Bucket,发送请求包到该Bucket所在的去重节点(该Bucket的主节点)。在一个实施例中,该发送线程包括四个缓冲区,其中两个缓冲区存储正在向系统传输的请求,分别对应指纹查询请求和数据块上传请求,另外两个缓冲区接收客户端内部其他线程发送的新请求,分别对应指纹查询请求和数据块上传请求。设置两种不同的缓冲区,将正在向系统传输的请求和其他线程发送的新请求分离,能够避免其他线程在写入新请求过程中出现长时间的阻塞。

当发送线程接收到去重节点发回的响应包时,会将响应包发送给逻辑处理线程进行相应的处理。逻辑处理线程根据相应的去重节点返回的指纹查询 结果将未查询到指纹信息和其代表的数据块的上传请求传递给发送线程,由发送线程将未查询到的指纹信息和其代表的数据块发送至对应的去重节点。这样的线程并发模式可以保证请求的发送是连续的、平稳的。

其中发送线程接收到的响应包中包括该去重节点当前存储的路由表的版本信息,判断该响应包中的路由表的版本信息与从中心节点获取的路由表的版本信息是否相同,当响应包中的路由表的版本信息与从中心节点获取的路由表的版本信息不相同时,代表该中心节点已经更新了路由表并同步到系统内的去重节点,此时客户端通过发送线程向从中心节点获取更新后的路由表,并根据该更新后的路由表重新确定Bucket对应的去重节点,从而重新确定未查询到的指纹信息和其代表的数据块所应上传到的去重节点。当响应包中的路由表的版本信息与从中心节点获取的路由表的版本信息相同时,仍根据从中心节点获取的路由表确定与Bucket对应的去重节点,未查询到的指纹信息和其代表的数据块所应上传的去重节点不变。

在步骤S205中,去重节点对指纹信息进行查询,将未查询到的指纹信息返回至客户端。

去重节点内部包括一个布隆过滤器和一个指纹信息库。该布隆过滤器建立了该去重节点当前存储的所有指纹信息的哈希索引;该指纹信息库中以Key-Value Pair的形式保存着所有指纹信息以及指纹信息代表的数据块的存储信息。去重节点将指纹查询请求中的所有指纹信息依次访问布隆过滤器和指纹信息库。通过布隆过滤器计算每个指纹信息的哈希索引并判断是否与布隆过滤器中的哈希索引相同。当与布隆过滤器中的哈希索引都不相同时,则确定该去重节点中没有相同的指纹信息及其代表的数据块,当与布隆过滤器中的某个哈希索引相同时,由于布隆过滤器存在哈希冲突的漏洞,能确定该指纹信息有可能已存在,需要进一步通过指纹信息库查询是否包含该指纹信息,当指纹信息库中存在该指纹信息时,确定该指纹信息已存在,当指纹信息库中不存在该指纹信息时,确定该指纹信息不存在。首先通过具有指纹信息哈希索引的布隆过滤器进行查询能够提高去重节点指纹查询的效率,再通过指纹信息库来弥补布隆过滤器由于哈希冲突而可能出现的漏查情况,提高了去重节点指纹查询的准确度。去重节点将该指纹查询请求中所有未查询到 的指纹信息放入响应包并返回至客户端。该响应包还包括该去重节点当前存储的路由表的版本信息,以用于客户端判断是否需要更新路由表。

在步骤S206中,客户端上传未查询到的指纹信息及其代表的数据块至与Bucket对应的去重节点。

客户端将响应包中的未查询到的指纹信息及其代表的数据块上传至与未查询到的指纹信息对应的Bucket所在的去重节点。如果路由表的版本信息没有变化,则该与未查询到的指纹信息对应的Bucket所在的去重节点就是步骤S205中进行指纹查询的去重节点。指纹查询请求中的其他指纹信息由于在去重节点中已经存在,则不需要再次上传,避免系统重复存储相同的数据块。

在步骤S207中,去重节点在分配到的Bucket中保存所述未查询到的指纹信息,在与分配到的Bucket对应的Container文件中保存所述数据块。

去重节点接收到未查询到的指纹信息及其代表的数据块,在与指纹信息对应的Bucket中保存未查询到的指纹信息,在与指纹信息对应的Bucket所对应的Container文件中保存该指纹信息代表的数据块。Container文件的名称是由Container文件所对应的Bucket的编号+系统内部通用唯一识别码(UUID)+日期(Date)组成,例如2_abcd234_010515。为了保证数据块写入磁盘,通过设置O_SYNC标志位的方式将数据块写入相应的Container文件,使每次写入完成后才返回,当pwrite返回后再将该数据块的指纹信息写入指纹信息库,写入指纹信息库时,将该数据块的指纹信息作为Key,将该数据块的第二存储信息做为Value,形成一个Key-Value Pair保存在指纹信息库中。该第二存储信息包括保存该数据块的Container文件的名称,该数据块在该Container文件中的偏移量(Offset)和该数据块的大小(Chunksize)。在布隆过滤器中更新该新保存的Key-Value Pair的哈希索引,以用于后续的数据去重查询。

在步骤S208中,去重节点向客户端返回数据块保存成功的消息。

在未查询到的指纹信息及其代表的数据块保存完毕后,去重节点向客户端返回数据块保存成功的消息,或者在一个实施例中,当未查询到的指纹信息对应的Bucket在系统中存在备用节点时,主节点将客户端上传的未查询到 的指纹信息及其代表的数据块保存完毕后,再备份到相应的Bucket的备用节点,当备份完毕后向客户端返回数据块保存成功的消息。

在步骤S209中,当未查询到的指纹信息及其代表的数据块全部上传完毕时,客户端上传数据的映射文件至去重节点。

映射文件包括该数据的每个数据块的指纹信息,并且每个数据块的指纹信息按照客户端将该数据切分为多个数据块时的切分顺序排列,以保证对该数据的正确映射。

客户端在上传映射文件时,也同样将映射文件分块上传。客户端将映射文件切分为多个数据块并分别计算映射文件的数据块的哈希值。例如,客户端通过murmur2哈希函数分别计算映射文件的每个数据块的哈希值。客户端确定映射文件的数据块的哈希值所对应的Bucket,根据路由表确定与映射文件的数据块的哈希值对应的Bucket所对应的去重节点,上传映射文件的数据块和相应的哈希值至对应的Bucket所对应的去重节点。客户端上传该映射文件的数据块时,也同样根据各个映射文件的数据块的哈希值进行指纹查询,只上传未查询到的哈希值所对应的映射文件的数据块,避免上传重复的映射文件数据块。客户端将映射文件切分为多个数据块时,将映射文件的头信息切分为多个数据块中的第一个数据块,该映射文件的头信息包括映射文件的总大小以及该多个数据块的总数量等信息。

在步骤S210中,去重节点保存客户端上传的映射文件的数据块和相应的哈希值。

在与映射文件的数据块的哈希值对应的Bucket中,保存映射文件的数据块的哈希值以及第一存储信息,在该对应的Bucket所对应的Container文件中保存映射文件的数据块。该第一存储信息包括保存映射文件的数据块的Container文件的名称,映射文件的数据块在Container文件中的偏移量和映射文件的数据块的大小。再以映射文件的名称+数据块序号为Key,以映射文件的数据块的第一存储信息为Value,做为Key-Value Pair更新指纹信息库。至此客户端向系统写入数据的过程全部结束。

如图4所示,本申请实施例中客户端从系统读取数据的过程,该过程包括以下步骤。

在步骤S301中,客户端根据数据的映射文件名称和数据块序号向去重节点请求映射文件。

客户端首先向去重节点请求映射文件的第一个数据块,映射文件的第一个数据块包括该映射文件的头信息。该映射文件的头信息包括映射文件的大小以及该映射文件的数据块的总数量。客户端根据映射文件的头信息向去重节点发出获取映射文件的其他数据块的请求。

在步骤S302中,去重节点发送映射文件的数据块至客户端。

去重节点根据客户端发送的映射文件名称和数据块序号与指纹信息库中的Key进行匹配,从而查询到该映射文件的数据块在指纹信息库中的Key-Value Pair,确定与映射文件的数据块的Key对应的第一存储信息。根据第一存储信息中的Container文件名称确定该映射文件的数据块存储在哪个Container文件中,进一步根据该映射文件的数据块在Container文件中的偏移量和该映射文件数据块的大小从Container文件中获取到该映射文件的数据块。

在步骤S303中,客户端根据映射文件的数据块拼接出映射文件,并根据映射文件中每个数据块的指纹信息向去重节点请求数据块。

客户端根据映射文件数据块的块序号拼接出完整的映射文件。映射文件包括全部数据块的指纹信息并且按照数据块的切分顺序排列。客户端确定与指纹信息对应的Bucket,在通过路由表确定与指纹信息对应的Bucket所在的去重节点,向该去重节点发送获取相应的数据块的请求。

在步骤S304中,去重节点发送映射文件的指纹信息代表的数据块至客户端。

去重节点根据获取数据块的请求中的指纹信息来查询指纹信息库,查询到与该指纹信息对应的第二存储信息。根据第二存储信息中的Container文件名称确定该指纹信息代表的数据块保存在哪个Container文件中,并根据该数据块在Container文件中的偏移量和该数据块的大小从Container文件获取到该数据块。在一个实施例中,根据第二存储信息中的Container文件名称确定该指纹信息代表的数据块保存在哪个Container文件后,判断该Container文件是否已经归档到后台服务器,如果该Container文件已归档到 后台服务器,去重节点从存储于后台服务器的该Container文件中获取到数据块并将数据块发送至客户端。

在步骤S305中,客户端按照每个数据块的指纹信息在映射文件中的顺序拼接出所述数据。

如图5所示,本申请实施例中用于数据读写的客户端,包括:

切分计算模块501,用于将数据切分为多个数据块并分别计算每个数据块的指纹信息;

桶确定模块502,用于确定所述每个数据块的指纹信息所对应的Bucket;

节点确定模块503,用于根据从中心节点获取的路由表,确定与所述Bucket对应的去重节点;

请求发送模块504,用于发送指纹查询请求至与所述Bucket对应的去重节点,所述指纹查询请求包括数据块的指纹信息;

信息接收模块505,用于接收到与所述Bucket对应的去重节点返回的未查询到的指纹信息;

数据上传模块506,用于上传所述未查询到的指纹信息及其代表的数据块至与所述Bucket对应的去重节点;当所述未查询到的指纹信息及其代表的数据块全部上传完毕时,还用于上传所述数据的映射文件至去重节点,所述映射文件包括所述数据的每个数据块的指纹信息,所述每个数据块的指纹信息按照数据块的切分顺序排列。

另外,还公开了一种本申请实施例中用于数据读写的系统,可以参考图1所示,包括:中心节点10和一个或多个去重节点11,其中,

所述中心节点10,用于发送路由表至客户端,所述路由表包括Bucket与去重节点之间的对应关系;

所述去重节点11,用于接收到所述客户端的指纹查询请求,所述指纹查询请求包括与所述去重节点分配到的Bucket对应的指纹信息;对所述指纹信息进行查询,将未查询到的指纹信息返回至所述客户端;接收到所述客户端上传的所述未查询到的指纹信息及其所代表的数据块。

需要说明的是,图1所示出的用于数据读写的系统与图3、4所示出的 实施例的特征相互对应,图5所示出的用于数据读写的客户端也与图3、4所示出的实施例的特征相互对应,因此图1、5的实施例中的不足之处可参见图3、4所示出的实施例的描述,不再赘述。

本申请实施例提供的数据存储方法、数据存储系统和数据读写方法、用于数据读写的客户端及用于数据读写的系统,实现了对100PB以上级别的原始数据以及100TB以上级别的指纹信息的全局去重存储管理,具有非常高的可扩展性,系统加入新的去重节点后,中心节点能够根据预设策略重新进行数据分布,去重节点自动完成数据迁移,使系统的性能和容量都能够便捷的进行扩展。在每个去重节点实现了一个基于固态硬盘的高性能指纹信息库,在固态硬盘中建立大容量的布谷鸟哈希映射表,克服了当指纹信息的数据量很大时无法在内存中建立索引,进而无法进行去重查询的技术困难,同时保证了指纹信息查询的效率和并提高了指纹信息查询的准确度。

在一个典型的配置中,计算设备包括一个或多个处理器(CPU)、输入/输出接口、网络接口和内存。

内存可能包括计算机可读介质中的非永久性存储器,随机存取存储器(RAM)和/或非易失性内存等形式,如只读存储器(ROM)或闪存(flash RAM)。内存是计算机可读介质的示例。

计算机可读介质包括永久性和非永久性、可移动和非可移动媒体可以由任何方法或技术来实现信息存储。信息可以是计算机可读指令、数据结构、程序的模块或其他数据。计算机的存储介质的例子包括,但不限于相变内存(PRAM)、静态随机存取存储器(SRAM)、动态随机存取存储器(DRAM)、其他类型的随机存取存储器(RAM)、只读存储器(ROM)、电可擦除可编程只读存储器(EEPROM)、快闪记忆体或其他内存技术、只读光盘只读存储器(CD-ROM)、数字多功能光盘(DVD)或其他光学存储、磁盒式磁带,磁带磁磁盘存储或其他磁性存储设备或任何其他非传输介质,可用于存储可以被计算设备访问的信息。按照本文中的界定,计算机可读介质不包括非暂存电脑可读媒体(transitory media),如调制的数据信号和载波。

如在说明书及权利要求当中使用了某些词汇来指称特定组件。本领域技术人员应可理解,硬件制造商可能会用不同名词来称呼同一个组件。本说明 书及权利要求并不以名称的差异来作为区分组件的方式,而是以组件在功能上的差异来作为区分的准则。如在通篇说明书及权利要求当中所提及的“包含”为一开放式用语,故应解释成“包含但不限定于”。“大致”是指在可接收的误差范围内,本领域技术人员能够在一定误差范围内解决所述技术问题,基本达到所述技术效果。此外,“耦接”一词在此包含任何直接及间接的电性耦接手段。因此,若文中描述一第一装置耦接于一第二装置,则代表所述第一装置可直接电性耦接于所述第二装置,或通过其他装置或耦接手段间接地电性耦接至所述第二装置。说明书后续描述为实施本发明的较佳实施方式,然所述描述乃以说明本发明的一般原则为目的,并非用以限定本发明的范围。本发明的保护范围当视所附权利要求所界定者为准。

还需要说明的是,术语“包括”、“包含”或者其任何其他变体意在涵盖非排他性的包含,从而使得包括一系列要素的商品或者系统不仅包括那些要素,而且还包括没有明确列出的其他要素,或者是还包括为这种商品或者系统所固有的要素。在没有更多限制的情况下,由语句“包括一个……”限定的要素,并不排除在包括所述要素的商品或者系统中还存在另外的相同要素。

上述说明示出并描述了本发明的若干优选实施例,但如前所述,应当理解本发明并非局限于本文所披露的形式,不应看作是对其他实施例的排除,而可用于各种其他组合、修改和环境,并能够在本文所述发明构想范围内,通过上述教导或相关领域的技术或知识进行改动。而本领域人员所进行的改动和变化不脱离本发明的精神和范围,则都应在本发明所附权利要求的保护范围内。

当前第1页1 2 3 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1