一种块级数据去重存储系统的制作方法

文档序号:17078224发布日期:2019-03-08 23:57阅读:161来源:国知局
一种块级数据去重存储系统的制作方法

本发明属于计算机存储备份技术领域,尤其涉及一种块级数据去重存储系统。



背景技术:

随着数据的爆炸性增长,数据容灾备份正面临前所未有的挑战。一方面,传统的数据保护技术如周期性备份、快照、连续数据保护和版本文件系统等产生了大量重复数据,加快了数据增长速度,迫使备份系统的存储容量不断扩张,使企业面临巨大的成本压力和数据管理难题。另一方面,由于应用对数据保护的要求越来越苛刻,备份窗口逐渐缩短,大量数据需要在线备份和故障即时恢复,对系统吞吐率和网络带宽提出了极高的要求。为了抑制数据过快增长,提高资源利用率,数据去重技术最近成为一个备受关注的研究课题。

数据去重是指消除冗余的文件、数据块、或字节以保证只有单一的数据实例存储在磁盘上的过程,它也被称为一种容量优化保护技术,用来降低数据保护的容量需求。数据去重主要使用delta压缩和分块压缩技术。

分块压缩的基本思想是对数据流(或文件)进行分块,然后消除重复数据块。简单的定长分块会产生比特偏移问题,目前常用基于内容的分块法如cdc(contentdefinedchucking)等来确定数据块边界而得到大小围绕某个期望值变化的变长数据块。使用加密哈希函数(如md5、sha-1等)计算每个数据块内容的哈希值作为该数据块的指纹,使用指纹对数据块进行索引并通过比较指纹来消除重复数据块(指纹相同的数据块为重复数据块)。相较于delta压缩,分块压缩实现简单但无法消除内容相似的数据块之间的冗余。另外,确定一个最佳的数据块期望大小比较困难。较小的数据块有利于提高数据压缩率,但单位时间内需要处理的数据块较多,系统的读写性能会降低,同时也增加了索引等元数据存储开销。目前主流的块级数据去重存储系统一般选择4kb或8kb的期望数据块大小,这导致粒度小于4kb或8kb的重复数据不能被删除。研究表明,文件系统中约50%的文件小于4kb,而超过80%的文件大小在64kb以下,对这些文件的修改会产生大量粒度小于4kb或8kb的重复数据。对于这类负载,使用分块压缩难以达到理想的数据压缩效果。

由于分块压缩具有实现简单、存储管理方便等优点,目前主流的数据去重存储系统采用单一的分块压缩算法,并使用布隆过滤器、稀疏索引技术来提高重复数据块的查询效率,取得了较高的读写性能。但是分块压缩仅仅删除数据块粒度的重复数据,未能取得最好的数据压缩效果。hydrastor和mad2通过数据块指纹的前缀把数据块分发到相应的存储节点,然后消除每个存储节点内的重复数据块。这种数据分布虽然也消除了节点间的重复数据块,但无法进行相似数据块聚类。ddgda把数据流分成超级块,从超级块内容中提取标识数据相似特征的相似签名,按照相似签名前缀把超级块分发到相应的存储节点,在存储节点内消除重复数据块。该技术能够把相似数据聚类到相同的节点,但无法消除节点间的重复数据块。



技术实现要素:

本发明的目的是提供一种块级数据去重存储系统,既能够消除存储节点内和存储节点间的重复数据块,又能够把内容相似的新数据块聚类到相同的存储节点。

为达到上述目的,本发明采用的技术方案是:一种块级数据去重存储系统,所述块级数据去重存储系统包括数据读写模块、指纹查询模块和容器读写模块三个模块,还设置有指纹路由表、容器路由表、输入缓冲区、文件缓冲区、指纹缓冲区和数据恢复缓冲区;所述数据读写模块包括数据备份方法和数据恢复方法;所述指纹查询模块包括指纹查询命令、指纹定位命令、数据块子索引更新命令和分布式指纹查询命令;所述容器读写模块包括写容器命令、读容器命令、读容器指纹命令和数据迁移命令;

所述块级数据去重存储系统用来设置在存储节点上,接收客户机发送过来的数据,每一个存储节点都可以接收客户机发送过来的数据并将数据备份到磁盘的容器存储池中,或从容器存储池中恢复指定的数据;所述容器存储池设置在磁盘设备上,磁盘设备上还安装有数据块子索引和容器索引;

所述块级数据去重存储系统采用分块压缩技术,消除存储节点集群中的重复数据块,并把内容相似的新数据块聚类到相同的存储节点;所述新数据块是指和存储节点集群中已有的所有数据块都不相同的数据块。

所述数据备份方法依次包括如下步骤:

21)、接收数据流:接收客户机发送过来的数据,将接收到的数据写入输入缓冲区;

22)、分块和计算指纹:使用通识的基于内容的分块算法将输入缓冲区中的数据分成数据块,使用通识的加密哈希函数计算每个数据块内容的哈希值作为该数据块的指纹;

23)、数据块相似签名:计算每一个数据块的相似签名,即从数据块的起始位置开始,以一个固定大小的窗口在数据块上滑动,每滑动一个字节前,就使用通识的罗宾指纹算法计算落入窗口内的数据小块的罗宾指纹,取所有数据小块中最小的罗宾指纹作为数据块的相似签名;

24)、创建文件索引:对输入缓冲区的数据中包含的文件建立文件索引,将文件索引发送给发起数据备份请求的客户机;文件索引由文件所包含的数据块的指纹组成,指纹在文件索引中出现的顺序和其对应的数据块在文件中出现的顺序一致;

25)、分段:采用基于内容的分段技术对输入缓冲区中的数据进行分段,即按顺序在输入缓冲区中查找相似签名后r位为0的数据块,以这些数据块为边界把输入缓冲区中的数据分成非定长数据段,每个数据段包含2r个数据块,其中,r为预先选择的正整数;

26)、数据段相似签名:选择数据段中包含的所有数据块相似签名中最小的相似签名作为数据段的相似签名;

27)、数据段指纹去重:对于每个数据段,将该数据段里包含的所有指纹发送给本存储节点上的指纹查询模块,并向指纹查询模块发送分布式指纹查询命令;

28)、容器封装步骤:根据指纹查询模块返回的结果,依次处理每个数据段:丢弃数据段里没有包含在返回结果中的指纹和其对应的数据块,如果数据段中尚余数据块,则这些数据块为新数据块,为该数据段分配一个容器以存储新数据块;取数据段的相似签名为容器的相似签名;把容器的相似签名和新数据块的指纹写入容器的元数据区,把新数据块写入容器的数据区;将处理过后的数据段从输入缓冲区中删除;所述容器由元数据区和数据区组成,所述元数据区用来存储容器的元数据,所述容器的元数据包括容器标识符、容器的相似签名、容器中所包含的数据块的指纹信息,所述数据区用来存储数据块;

29)、数据聚类:对于每个容器作如下处理:查询容器路由表,根据该容器的相似签名前缀找到容器路由表中对应的路由项,按照该路由项中标明的存储节点地址将容器发送给相应的存储节点的容器读写模块,并向该存储节点的容器读写模块发送写容器命令;所述容器路由表由路由项组成,用于建立容器标识符前缀或容器相似签名前缀和存储节点地址之间的映射,所述路由项为二元组<容器标识符前缀,存储节点地址>;所述容器标识符前缀等于同一容器的容器相似签名前缀;

291)、结束判断:如果没有收到客户机的备份结束请求,则转步骤(21);否则结束本次备份作业。

所述数据恢复方法依次包括如下步骤:

31)、初始化:在内存中生成一个空的数据恢复缓冲区和一个空的文件缓冲区,设置一个计数器counter用来记录处理的指纹数,将counter清零;

32)、接收文件索引:接收客户机发送过来的一个文件索引,设置一个读指针p指向文件索引中的第一个指纹;

33)、缓冲区查询:读取p所指向的指纹,记为fp,将counter的值加1,在数据恢复缓冲区的指纹索引表中查询指纹fp:如果查到,则从数据恢复缓冲区的容器链表中找到包含指纹fp的容器,将counter的值赋值给该容器所在链表结点的计数器字段,从该容器中读取指纹fp所对应的数据块,记为d,进入步骤38),否则,进入步骤34);所述数据恢复缓冲区由指纹索引表和容器链表组成;所述指纹索引表为内存哈希表;所述内存哈希表包含一个桶组;所述桶组里的每个桶对应一个编号,并使用哈希函数建立指纹和桶编号之间的映射,映射到桶里的指纹存放在索引结点链表的索引结点中;所述索引结点包括指纹字段、容器指针字段和链表指针字段;所述指纹字段存放一个指纹,所述容器指针字段存放该指纹所在的容器在容器链表中的地址,所述链表指针字段存放同一个索引结点链表中下一个索引结点的地址;所述容器链表为通识的内存链表,写入数据恢复缓冲区的容器被链接在该内存链表中;所述内存链表由一个头指针和多个链接在一起的链表结点组成,链表结点包括一个计数器字段和一个容器;

34)、指纹定位:查询指纹路由表,根据指纹fp的前缀找到指纹路由表中对应的路由项,按照该路由项中标明的存储节点地址将指纹fp发送给相应的存储节点的指纹查询模块,并向该存储节点的指纹查询模块发送指纹定位命令;所述指纹路由表由路由项组成,用于建立指纹前缀和存储节点地址之间的映射,所述路由项为二元组<指纹前缀,存储节点地址>;

35)、指纹定位结果判断:接收指纹fp的定位结果,如果定位结果是负数,则转步骤392);否则,从定位结果里得到一个容器标识符,记为cid,进入步骤36);

36)、读容器:查询容器路由表,根据cid的前缀找到容器路由表中对应的路由项,按照该路由项中标明的存储节点地址将cid发送给相应的存储节点的容器读写模块,并向该存储节点的容器读写模块发送读容器命令;所述容器标识符是一个m+n+s位的二进制数,前m位为容器标识符的满前缀,是该容器相似签名的前m位,中间n位为编号,是该容器所在存储节点的编号,最后s位为序号,是该容器在存储节点上的序号;所述容器标识符前缀是指该容器标识符的满前缀的m(m为大于或等于1小于或等于m的整数)位前缀;

37)、写缓冲区:接收读容器命令返回的容器,将该容器写入数据恢复缓冲区,从该容器中读取指纹fp所对应的数据块,记为d;

38)、恢复文件数据:将数据块d写入文件缓冲区;如果文件缓冲区满,则从其中移出一部分数据,并将移出的数据发送给客户机;

39)、文件索引判断:读指针p向前移动一步,指向文件索引的下一个指纹,如果p非空,则转步骤33);否则,将文件缓冲区中的剩余数据移出并发送给客户机,并向客户机发送文件数据恢复结束信号,进入步骤391);

391)、结束判断步骤:如果没有收到客户机的数据恢复结束请求,则进入步骤32);否则,进入步骤393);

392)、出错处理:向客户机发送文件索引出错信号,出错原因为:系统中查不到指纹fp;

393)、结束:删除数据恢复缓冲区、文件缓冲区、计数器counter等数据结构后退出。

所述指纹查询命令依次包括如下步骤:

41)、提取指纹:从指纹查询命令中提取要查询的指纹,记为fp;

42)、过滤器查询:在布隆过滤器中查询fp,如果没有查到,则向请求指纹查询的存储节点返回“fp是新指纹”的信息后结束;否则,转步骤43);所述布隆过滤器为通识的数据查询结构,用于在内存中表示本存储节点的数据块子索引中的所有指纹;

43)、数据块子索引查询:所述数据块子索引为通识的磁盘哈希表,所述磁盘哈希表使用哈希函数将指纹映射到相应的桶中,所述桶里存放二元组<fp,cid>;在数据块子索引中查询fp,如果查到,则得到指纹fp所在容器的容器标识符,记为cid,向请求指纹查询的存储节点返回“fp是旧指纹,包含在容器cid中”的信息后结束;否则,向请求指纹查询的存储节点返回“fp是新指纹”的信息后结束。

所述指纹定位命令的执行方法依次包括如下步骤:

51)、提取指纹:从指纹定位命令中提取要定位的指纹,记为fp;

52)、数据块子索引查询:在数据块子索引中查询fp,如果查到,则得到指纹fp所在容器的容器标识符,记为cid,向请求指纹定位的存储节点返回容器标识符“cid”后结束;否则,向请求指纹定位的存储节点返回负数“-1”后结束。

所述数据块子索引更新命令的执行方法为:

61)、提取二元组:从数据块子索引更新命令中提取二元组<fp,cid>其中,fp是指纹,cid是fp所在容器的容器标识符;

62)、把fp插入到布隆过滤器中;将二元组<fp,cid>插入数据块子索引中。

所述分布式指纹查询命令依次包括如下步骤:

71)、接收数据段指纹:接收本存储节点的数据读写模块发送过来的数据段指纹,记为指纹集,设置一个读指针p指向指纹集中的第一个指纹;

72)、缓冲区查询:读取p所指向的指纹,记为fp,在指纹缓冲区中查询fp,如果查到,则进入步骤77);否则,进入步骤73);所述指纹缓冲区为通识的内存哈希表,所述内存哈希表使用哈希函数将指纹映射到相应的桶中,所述桶里存放指纹;所述指纹缓冲区满时,采用通识的最近最少使用置换算法删除一些指纹;

73)、指纹查询:查询指纹路由表,根据指纹fp的前缀找到指纹路由表中对应的路由项,按照该路由项中标明的存储节点地址将指纹fp发送给相应的存储节点的指纹查询模块,并向该存储节点的指纹查询模块发送指纹查询命令;

74)、查询结果判断:接收指纹fp的查询结果,如果fp是新指纹,则将fp插入指纹缓冲区中,转第78)步,否则,fp是旧指纹,且得到指纹fp所在容器的容器标识符,记为cid,转下一步;

75)、读容器指纹:查询容器路由表,根据cid的前缀找到容器路由表中对应的路由项,按照该路由项中标明的存储节点地址将cid发送给相应的存储节点的容器读写模块,并向该存储节点的容器读写模块发送读容器指纹命令;

76)、缓冲区更新:接收到读容器指纹命令返回的指纹后,将这些指纹插入指纹缓冲区中;

77)、删除旧指纹:将指纹fp从指纹集中删除;

78)、结束判断:读指针p向前移动一步,指向指纹集中的下一个指纹,如果p非空,则转第72)步,否则,转下一步;

79)、结束:如果指纹集中尚余指纹,则将指纹集中的剩余指纹返回给本存储节点的数据读写模块后退出,否则,将0返回给本存储节点的数据读写模块后退出。

所述写容器命令的执行方法依次包括如下步骤:

81)、接收容器:从写容器命令中读取容器,记为container,将容器计数器的值加1;所述容器计数器由容器读写模块维护,用来记录该容器读写模块写入容器存储池的容器数量;

82)、生成容器标识符:

首先:读取container的相似签名,并取其前m位作为容器标识符的满前缀;

其次:读取本存储节点的编号,将该编号作为容器标识符的编号;

再次:读取容器计数器的当前值,将其作为容器标识符的序号;

最后:为container生成了一个m+n+s位的容器标识符,记为cid,将cid写入container的元数据区;

83)、写容器:将container写入本存储节点上的容器存储池,并将container在容器存储池中的位置信息写入容器索引;所述容器索引设置在磁盘设备上,用于记录容器存储池中容器的位置信息;

84)、数据块索引更新:所述数据块索引是通识的分布式哈希表,由分布在各个存储节点上的数据块子索引组成,这些数据块子索引里包含的指纹都互不相同,整个存储节点集群里没有重复的指纹;对于container中包含的每一个指纹fp,生成一个二元组<fp,cid>,查询指纹路由表,根据指纹fp的前缀找到指纹路由表中对应的路由项,按照该路由项中标明的存储节点地址将<fp,cid>发送给相应的存储节点的指纹查询模块,并向该存储节点的指纹查询模块发送数据块子索引更新命令。

所述读容器命令的执行方法为:

首先:提取读容器命令中的容器标识符,记为cid;

然后:从本存储节点的容器存储池中读取容器标识符为cid的容器,并将读取的容器返回给请求读容器的存储节点;

所述读容器指纹命令的执行方法为:

首先:提取读容器指纹命令中的容器标识符,记为cid;

然后:从本存储节点的容器存储池中读取容器标识符为cid的容器所包含的指纹,并将读取的指纹返回给请求读容器指纹的存储节点。

所述数据迁移命令的执行依次包括如下步骤:

111)、子索引迁移:读取本存储节点的数据块子索引中的所有二元组,对于读取的每个二元组<fp,cid>,如果指纹fp的第k+1位为0,则将<fp,cid>发送给地址为addr2的新存储节点的指纹查询模块,并向其发送数据块子索引更新命令;如果指纹fp的第k+1位为1,则将<fp,cid>发送给地址为addr3的新存储节点的指纹查询模块,并向其发送数据块子索引更新命令;

112)、重定向:将本存储节点接收到的指纹查询命令、指纹定位命令、数据块子索引更新命令重定向给新存储节点,即检测指纹的第k+1位,如果为0,则把相应的命令转发给地址为addr2的新存储节点执行;如果为1,则把相应的命令转发给地址为addr3的新存储节点执行;将本存储节点接收到的写容器命令重定向给新存储节点,即检测容器相似签名的第w+1位,如果为0,则把写容器命令转发给地址为addr2的新存储节点执行;如果为1,则把写容器命令转发给地址为addr3的新存储节点执行;对本存储节点接收到的读容器命令、读容器指纹命令进行重定向,即检测容器标识符的编号,如果编号为num1,则由本存储节点执行命令,如果编号为num2,则把相应的命令转发给地址为addr2的新存储节点执行;如果编号为num3,则把相应的命令转发给地址为addr3的新存储节点执行;

113)、容器迁移:从本存储节点的容器存储池中读取其存储的所有容器,对于读取的每个容器,检测容器相似签名的第w+1位,如果为0,则把该容器发送给地址为addr2的新存储节点,并向其发送写容器命令;如果为1,则把该容器发送给地址为addr3的新存储节点,并向其发送写容器命令;

114)、路由更新:

首先:将本存储节点的指纹路由表和容器路由表发送给新存储节点,作为新存储节点的指纹路由表和容器路由表;

然后:向存储节点集群中包含的所有存储节点包括新存储节点广播路由更新,将指纹路由表中的路由项<a1a2…ak,addr1>删除,并增加新路由项<a1a2…ak0,addr2>和<a1a2…ak1,addr3>;将容器路由表中的路由项<b1b2…bw,addr1>删除,并增加新路由项<b1b2…bw0,addr2>和<b1b2…bw1,addr3>;

结束:本存储节点停止接收客户机的数据备份和恢复请求,本存储节点已有的读容器命令、读容器指纹命令,数据备份和数据恢复作业执行完毕后退出。

本发明提出了一种块级数据去重存储系统,具有以下优点:

1、采用基于内容的分块和分段技术,减少了因数据的局部修改而产生的边界偏移现象,保护了数据的冗余局部性,有利于提高重复数据删除比率;使用容器按逻辑顺序存储新数据块也有效保护了数据的冗余局部性,有利于提高数据处理和恢复性能;

2、分布式指纹查询命令采用指纹缓冲区、布隆过滤器和数据块索引三级指纹查询机构,既减少了指纹查询的磁盘i/o开销,又支持分布式并行查询,从而能有效提高指纹查询效率和数据去重性能;

3、数据恢复缓冲区的设计能有效减少数据恢复过程中的磁盘i/o开销,提高数据恢复性能;

4、把相似数据聚类到相同的存储节点上并以容器为单位进行处理,有利于缩小相似数据的查找范围,提高相似数据的查找效率,因为同一容器中数据块的相似数据块极可能也在同一容器中;

5、支持在线数据迁移,从而允许系统在运行的过程中根据需要增加更多的存储节点,使得系统的性能和容量具有良好的可扩展性。

附图说明

图1为本发明结构示意图;

图2为数据备份方法流程图;

图3为数据恢复方法流程图;

图4为分布式指纹查询命令流程图;

图5为数据迁移命令流程图;

图6为指纹索引表结构示意图;

图7为指纹索引表索引结点结构图;

图8为容器链表结构示意图。

具体实施方式

本发明公开了一种块级数据去重存储系统,如图1所示,所述块级数据去重存储系统包括数据读写模块、指纹查询模块和容器读写模块三个模块,还设置有指纹路由表、容器路由表、输入缓冲区、文件缓冲区、指纹缓冲区和数据恢复缓冲区;所述数据读写模块包括数据备份方法和数据恢复方法;数据读写模块监听网络上客户机发送过来的数据备份或恢复请求,执行数据备份方法或数据恢复方法响应客户机发送过来的数据备份或恢复请求。

所述指纹查询模块包括指纹查询命令、指纹定位命令、数据块子索引更新命令和分布式指纹查询命令;

所述容器读写模块包括写容器命令、读容器命令、读容器指纹命令和数据迁移命令;

所述块级数据去重存储系统用来设置在存储节点上,接收客户机发送过来的数据,每一个存储节点都可以接收客户机发送过来的数据并将数据备份到容器存储池中,或从容器存储池中恢复指定的数据;所述容器存储池设置在磁盘设备上,磁盘设备上还安装有数据块子索引和容器索引;

所述块级数据去重存储系统采用分块压缩技术,消除存储节点集群中的重复数据块,并把内容相似的新数据块聚类到相同的存储节点;所述新数据块是指和集群中已有的所有数据块都不相同的数据块。

如图2所示,所述数据备份方法依次包括如下步骤:

21)、接收数据流:接收客户机发送过来的数据,将接收到的数据写入输入缓冲区;所述输入缓冲区采用队列结构,所述队列结构为成熟的现有技术。

22)、分块和计算指纹:使用通识的基于内容的分块方法将输入缓冲区中的数据分成数据块,使用通识的加密哈希函数计算每个数据块内容的哈希值作为该数据块的指纹;

本实施例中,可以采用通识的cdc算法,将数据分成期望大小为8kb的变长数据块,使用sha-1哈希函数计算数据块指纹,指纹长度为20字节。

23)、数据块相似签名:计算每一个数据块的相似签名,即从数据块的起始位置开始,以一个固定大小的窗口在数据块上滑动,每滑动一个字节前,就使用通识的罗宾指纹算法计算落入窗口内的数据小块的罗宾指纹,取所有数据小块中最小的罗宾指纹作为数据块的相似签名;本实施例中,所述窗口的大小是预先确定的一个常数,可取512字节,所述罗宾指纹的长度可取4字节。

24)、创建文件索引:对输入缓冲区的数据中包含的文件建立文件索引,将文件索引发送给发起数据备份请求的客户机;文件索引由文件所包含的数据块的指纹组成,指纹在文件索引中出现的顺序和其对应的数据块在文件中出现的顺序一致;

25)、分段:采用基于内容的分段技术对输入缓冲区中的数据进行分段,即按顺序在输入缓冲区中查找相似签名后r位为0的数据块,以这些数据块为边界把输入缓冲区中的数据分成非定长数据段,每个数据段包含2r个数据块,其中,r为预先选择的正整数;

本实施例中,r是个重要的参数,r设置过小和过大都不利于数据去重效率和处理性能,在实施中,r取12或13为宜,这样一个数据段平均包含212或213个数据块。本实施例中,运用了基于内容的分段技术对数据进行分段,这样应用程序对数据段的修改便难以影响到数据段外部的数据,有利于保护数据的冗余局部性。

26)、数据段相似签名:选择数据段中包含的所有数据块相似签名中最小的相似签名作为数据段的相似签名;

27)、数据段指纹去重:对于每个数据段,将该数据段里包含的所有指纹发送给本存储节点上的指纹查询模块,并向指纹查询模块发送分布式指纹查询命令;

28)、容器封装步骤:根据指纹查询模块返回的结果,依次处理每个数据段:丢弃数据段里没有包含在返回结果中的指纹和其对应的数据块,如果数据段中尚余数据块,则这些数据块为新数据块,为该数据段分配一个容器以存储新数据块;取数据段的相似签名为容器的相似签名;把容器的相似签名和新数据块的指纹写入容器的元数据区,把新数据块写入容器的数据区;将处理过后的数据段从输入缓冲区中删除;所述容器由元数据区和数据区组成,所述元数据区用来存储容器的元数据,所述容器的元数据包括容器标识符、容器的相似签名、容器中所包含的数据块的指纹信息,所述数据区用来存储数据块;

本实施例中,按照数据段为单位进行处理,除了使用容器封装数据段里的新数据块外,还将数据段的相似签名作为容器的相似签名存储到容器中,而数据段的相似签名是从对数据段里包含的所有数据块包括旧数据块的相似签名进行处理而获得的,这使得容器在保护数据段的冗余局部性的同时不用存储数据段里的旧数据块,从而既避免了重复数据块存储又有利于相似数据块聚类;所述旧数据块是指和存储节点集群中已有数据块相同的数据块。

29)、数据聚类:对于每个容器作如下处理:查询容器路由表,根据该容器的相似签名前缀找到容器路由表中对应的路由项,按照该路由项中标明的存储节点地址将容器发送给相应的存储节点的容器读写模块,并向该存储节点的容器读写模块发送写容器命令;所述容器路由表由路由项组成,用于建立容器标识符前缀或容器相似签名前缀和存储节点地址之间的映射,所述路由项为二元组<容器标识符前缀,存储节点地址>;所述容器标识符前缀等于同一容器的容器相似签名前缀;

本实施例中,具有相同相似签名的容器被聚类到相同的存储节点上,这有利于相似数据块聚类,因为具有相同相似签名的容器其对应的数据段内容彼此相似的概率很高,反之,内容彼此相似的两个数据段其对应的容器具有相同相似签名的概率也很高。由于数据段保护了数据的冗余局部性,使得同一容器中数据块的相似数据块极有可能也在同一容器中。

291)、结束判断:如果没有收到客户机的备份结束请求,则转步骤(21);否则结束本次备份作业。

如图3所示,所述数据恢复方法依次包括如下步骤:

31)、初始化:在内存中生成一个空的数据恢复缓冲区和一个空的文件缓冲区,设置一个计数器counter用来记录处理的指纹数,将counter清零;所述文件缓冲区采用队列结构,所述队列结构为成熟的现有技术。

32)、接收文件索引:接收客户机发送过来的一个文件索引,设置一个读指针p指向文件索引中的第一个指纹;

33)、缓冲区查询:读取p所指向的指纹,记为fp,将counter的值加1,在数据恢复缓冲区的指纹索引表中查询指纹fp:如果查到,则从数据恢复缓冲区的容器链表中找到包含指纹fp的容器,将counter的值赋值给该容器所在链表结点的计数器字段,从该容器中读取指纹fp所对应的数据块,记为d,进入步骤38),否则,进入步骤34);所述数据恢复缓冲区由指纹索引表和容器链表组成;如图6所示,所述指纹索引表为内存哈希表;所述内存哈希表包含一个桶组;所述桶组里的每个桶对应一个编号,并使用哈希函数建立指纹和桶编号之间的映射,映射到桶里的指纹存放在索引结点链表的索引结点中;如图7所示,所述索引结点包括指纹字段、容器指针字段和链表指针字段;所述指纹字段存放一个指纹,所述容器指针字段存放该指纹所在的容器在容器链表中的地址,所述链表指针字段存放同一个索引结点链表中下一个索引结点的地址;所述容器链表为通识的内存链表,写入数据恢复缓冲区的容器被链接在该内存链表中;如图8所示,所述内存链表由一个头指针和多个链接在一起的链表结点组成,链表结点包括一个计数器字段和一个容器。

34)、指纹定位:查询指纹路由表,根据指纹fp的前缀找到指纹路由表中对应的路由项,按照该路由项中标明的存储节点地址将指纹fp发送给相应的存储节点的指纹查询模块,并向该存储节点的指纹查询模块发送指纹定位命令;所述指纹路由表由路由项组成,用于建立指纹前缀和存储节点地址之间的映射,所述路由项为二元组<指纹前缀,存储节点地址>;

35)、指纹定位结果判断:接收指纹fp的定位结果,如果定位结果是负数,则转步骤392);否则,从定位结果里得到一个容器标识符,记为cid,进入步骤36);

36)、读容器:查询容器路由表,根据cid的前缀找到容器路由表中对应的路由项,按照该路由项中标明的存储节点地址将cid发送给相应的存储节点的容器读写模块,并向该存储节点的容器读写模块发送读容器命令;所述容器标识符是一个m+n+s位的二进制数,前m位为容器标识符的满前缀,是该容器相似签名的前m位,中间n位为编号,是该容器所在存储节点的编号,最后s位为序号,是该容器在存储节点上的序号;所述容器标识符前缀是指该容器标识符的满前缀的m(m为大于或等于1小于或等于m的整数)位前缀;

本实施例中,所述m决定了系统的最大规模,也就是存储节点集群中允许包含的存储节点个数不超过2m;所述n为存储节点集群中存储节点编号的位数,所述存储节点集群中每个存储节点都有一个唯一的编号,该编号是一个n位二进制数;在实施中,应保证m大于n,m可取12,n可取10,这样,存储节点集群最多可有210个存储节点,能满足大规模集群备份的需要;所述s决定了单个存储节点的最大存储容量,也就是单个存储节点上允许存储的容器个数不超过2s,在实施中,可选择相对较大的s值,给系统扩容留有足够的余地;比如s取值26,单个存储节点最多可存储226个容器,每个容器存储一个数据段的逻辑数据,按每个数据段平均213个数据块,平均每个数据块8kb来计算,存储节点集群的最大逻辑存储容量可达到210×226×213×8kb=4eb,如果考虑到很多数据段可能不含新数据块从而不用消耗容器的情况,实际的逻辑存储容量还要大于4eb,但是,4eb的逻辑数据经过去重后实际需要的物理存储空间会远远小于4eb。

37)、写缓冲区:接收读容器命令返回的容器,将该容器写入数据恢复缓冲区,从该容器中读取指纹fp所对应的数据块,记为d;

“将该容器写入数据恢复缓冲区”的具体过程为:

首先:判断数据恢复缓冲区是否已满,如果数据恢复缓冲区已满,则将容器链表中计数器字段的值最小的链表结点删除,并将该链表结点的容器中包含的所有指纹从指纹索引表中删除;所述判断数据恢复缓冲区是否已满的方法为成熟的现有技术;

其次:将该容器链接到容器链表中,并将计数器counter的值赋值给该容器所在链表结点的计数器字段;

最后:将该容器包含的所有指纹都插入到指纹索引表中,并将该容器在容器链表中的地址写入这些指纹所在索引结点的容器指针字段。

在实施中,所述数据恢复缓冲区能有效提高数据恢复性能,其原因为:读取一个指纹对应的数据块时,首先在数据恢复缓冲区中查询此指纹,如果命中,可直接在数据恢复缓冲区中读取该指纹对应的数据块,只有未命中时,才需要查询磁盘上的数据块索引、找到相应的容器标识符、根据容器标识符从相应的存储节点中把容器读入到数据恢复缓冲区中,一次磁盘i/o可以读入整个容器到内存中,而同一个容器中的数据块极有可能再次被访问,从而维持了较高的数据恢复缓冲区命中率,降低了数据恢复所需的磁盘i/o开销。

38)、恢复文件数据:将数据块d写入文件缓冲区;如果文件缓冲区满,则从其中移出一部分数据,并将移出的数据发送给客户机;

39)、文件索引判断:读指针p向前移动一步,指向文件索引的下一个指纹,如果p非空,则转步骤33);否则,将文件缓冲区中的剩余数据移出并发送给客户机,并向客户机发送文件数据恢复结束信号,进入步骤391);

391)、结束判断步骤:如果没有收到客户机的数据恢复结束请求,则进入步骤32);否则,进入步骤393);

392)、出错处理:向客户机发送文件索引出错信号,出错原因为:系统中查不到指纹fp;

393)、结束:删除数据恢复缓冲区、文件缓冲区、计数器counter等数据结构后退出。

所述指纹查询模块监听并执行存储节点集群中其它存储节点或本存储节点发送过来的指纹查询命令、指纹定位命令或数据块子索引更新命令;所述指纹查询模块还监听并执行本存储节点的数据读写模块发送过来的分布式指纹查询命令。

所述指纹查询命令依次包括如下步骤:

41)、提取指纹:从指纹查询命令中提取要查询的指纹,记为fp;

42)、过滤器查询:在布隆过滤器中查询fp,如果没有查到,则向请求指纹查询的存储节点返回“fp是新指纹”的信息后结束;否则,转步骤43);所述布隆过滤器为通识的数据查询结构,用于在内存中表示本存储节点的数据块子索引中的所有指纹;

43)、数据块子索引查询:所述数据块子索引为通识的磁盘哈希表,所述磁盘哈希表使用哈希函数将指纹映射到相应的桶中,所述桶里存放二元组<fp,cid>;在数据块子索引中查询fp,如果查到,则得到指纹fp所在容器的容器标识符,记为cid,向请求指纹查询的存储节点返回“fp是旧指纹,包含在容器cid中”的信息后结束;否则,向请求指纹查询的存储节点返回“fp是新指纹”的信息后结束。

本实施例中,所述指纹查询命令使用了布隆过滤器和数据块子索引二级指纹查询机构,所述布隆过滤器留驻在内存中,所述数据块子索引留驻在磁盘上;查询一个指纹时,首先在布隆过滤器中查询,如果没有查到,则可以肯定该指纹是新指纹,如果查到,则因为布隆过滤器存在误警率,不能肯定该指纹是旧指纹,需要在数据块子索引中继续查询;所述新指纹是指和存储节点集群中已有的所有指纹都不相同的指纹,所述旧指纹是指存储节点集群中已有的指纹;根据系统平均规模设置适当大小的布隆过滤器,可以使布隆过滤器的误警率足够小,从而使大部分的新指纹都能够通过布隆过滤器查询而识别,降低指纹查询的磁盘i/o开销。

在实施中,布隆过滤器大小可以根据系统平均规模,也就是存储节点集群中平均每个存储节点的物理存储容量来设定,假设系统平均规模为vkb,x为布隆过滤器的位数,y为布隆过滤器中存储的指纹个数,b为数据块大小,r为底层的平均delta压缩率,则有y=vr/b,要保证布隆过滤器的误警率小于或等于2%,只须保证x/y大于或等于8,在典型应用下,b一般为8kb,则可设定x=8y=8vr/b=vr,布隆过滤器的大小为vr*2-3*2-30gb=vr*2-33gb,如果底层对容器进行了delta压缩,则在典型应用下r可取值4,每1gb的布隆过滤器支持的物理存储容量为2tb,如果底层没有对容器进行delta压缩,则r为1,每1gb的布隆过滤器支持的物理存储容量为8tb;如果保证布隆过滤器的误警率小于或等于2%,则超过98%的新指纹都能够通过布隆过滤器查询而识别。

所述指纹定位命令的执行方法依次包括如下步骤:

51)、提取指纹:从指纹定位命令中提取要定位的指纹,记为fp;

52)、数据块子索引查询:在数据块子索引中查询fp,如果查到,则得到指纹fp所在容器的容器标识符,记为cid,向请求指纹定位的存储节点返回容器标识符“cid”后结束;否则,向请求指纹定位的存储节点返回负数“-1”后结束。

所述数据块子索引更新命令的执行方法为:

61)、提取二元组:从数据块子索引更新命令中提取二元组<fp,cid>其中,fp是指纹,cid是fp所在容器的容器标识符;

62)、把fp插入到布隆过滤器中;将二元组<fp,cid>插入数据块子索引中。

如图4所示,所述分布式指纹查询命令依次包括如下步骤:

71)、接收数据段指纹:接收本存储节点的数据读写模块发送过来的数据段指纹,记为指纹集,设置一个读指针p指向指纹集中的第一个指纹;

72)、缓冲区查询:读取p所指向的指纹,记为fp,在指纹缓冲区中查询fp,如果查到,则进入步骤77);否则,进入步骤73);所述指纹缓冲区为通识的内存哈希表,所述内存哈希表使用哈希函数将指纹映射到相应的桶中,所述桶里存放指纹;所述指纹缓冲区满时,采用通识的最近最少使用置换算法删除一些指纹;

73)、指纹查询:查询指纹路由表,根据指纹fp的前缀找到指纹路由表中对应的路由项,按照该路由项中标明的存储节点地址将指纹fp发送给相应的存储节点的指纹查询模块,并向该存储节点的指纹查询模块发送指纹查询命令;

74)、查询结果判断:接收指纹fp的查询结果,如果fp是新指纹,则将fp插入指纹缓冲区中,转第78)步,否则,fp是旧指纹,且得到指纹fp所在容器的容器标识符,记为cid,转下一步;

75)、读容器指纹:查询容器路由表,根据cid的前缀找到容器路由表中对应的路由项,按照该路由项中标明的存储节点地址将cid发送给相应的存储节点的容器读写模块,并向该存储节点的容器读写模块发送读容器指纹命令;

76)、缓冲区更新:接收到读容器指纹命令返回的指纹后,将这些指纹插入指纹缓冲区中;

77)、删除旧指纹:将指纹fp从指纹集中删除;

78)、结束判断:读指针p向前移动一步,指向指纹集中的下一个指纹,如果p非空,则转第72)步,否则,转下一步;

79)、结束:如果指纹集中尚余指纹,则将指纹集中的剩余指纹返回给本存储节点的数据读写模块后退出,否则,将0返回给本存储节点的数据读写模块后退出。

在本实施例中,所述分布式指纹查询命令使用了三级指纹查询机构:指纹缓冲区,布隆过滤器和数据块子索引,其中,指纹缓冲区和布隆过滤器留驻在内存中,数据块子索引留驻在磁盘上;查询一个指纹时,首先在本存储节点的指纹缓冲区中查询,如果命中,则可确定该指纹为旧指纹,如果没命中,则通过指纹查询命令在相应的存储节点上进一步查询;所述指纹查询命令使用了布隆过滤器和数据块子索引二级查询机构进一步识别指纹;如果最终通过查询数据块子索引而确认所查询的指纹是旧指纹,则通过所述步骤75)和步骤76)将包含该指纹的容器里的所有指纹读入指纹缓冲区,因为容器保护了数据的冗余局部性,同一容器里的指纹极有可能再次被访问,这样,一次磁盘i/o就可以创造成百上千的缓冲区命中机会,从而使得指纹缓冲区能够维持较高的命中率;所述三级查询机构中,所述布隆过滤器能识别超过98%的新指纹,所述指纹缓冲区具有较高的命中率从而能够识别大部分的旧指纹,极大地降低了指纹查询的磁盘i/o开销。

所述容器读写模块监听并执行其它存储节点或本存储节点发送过来的写容器命令、读容器命令或读容器指纹命令;当存储节点集群中添加新的存储节点时,所述容器读写模块还可执行数据迁移命令将本存储节点上的数据迁移到两个新的存储节点上,所述数据迁移命令可在线执行,不影响存储节点集群的正常工作;

所述容器读写模块维护一个容器计数器,用来记录该容器读写模块写入容器存储池的容器数量,所述容器计数器是一个s位的二进制计数器,其中s是容器标识符序号的位数。

所述写容器命令的执行方法依次包括如下步骤:

81)、接收容器:从写容器命令中读取容器,记为container,将容器计数器的值加1;

82)、生成容器标识符:

首先:读取container的相似签名,并取其前m位作为容器标识符的满前缀;

其次:读取本存储节点的编号,将该编号作为容器标识符的编号;

再次:读取容器计数器的当前值,将其作为容器标识符的序号;

最后:为container生成了一个m+n+s位的容器标识符,记为cid,将cid写入container的元数据区;

83)、写容器:将container写入本存储节点上的容器存储池,并将container在容器存储池中的位置信息写入容器索引;所述容器索引设置在磁盘设备上,用于记录容器存储池中容器的位置信息;

84)、数据块索引更新:所述数据块索引是通识的分布式哈希表,由分布在各个存储节点上的数据块子索引组成,这些数据块子索引里包含的指纹都互不相同,整个存储节点集群里没有重复的指纹;对于container中包含的每一个指纹fp,生成一个二元组<fp,cid>,查询指纹路由表,根据指纹fp的前缀找到指纹路由表中对应的路由项,按照该路由项中标明的存储节点地址将<fp,cid>发送给相应的存储节点的指纹查询模块,并向该存储节点的指纹查询模块发送数据块子索引更新命令。

所述读容器命令的执行方法为:

首先:提取读容器命令中的容器标识符,记为cid;

然后:从容器存储池中读取容器标识符为cid的容器并将读取的容器返回给请求读容器的存储节点。

所述读容器指纹命令的执行方法为:

首先:提取读容器指纹命令中的容器标识符,记为cid;

然后:从容器存储池中读取容器标识符为cid的容器所包含的指纹,并将读取的指纹返回给请求读容器指纹的存储节点。

所述数据迁移命令能够将本存储节点上的数据迁移到两个新存储节点上;本存储节点的地址记为addr1,两个新存储节点的地址分别记为addr2和addr3;本存储节点的编号记为num1,两个新存储节点的编号分别记为num2和num3;指纹路由表中本存储节点的路由项记为<a1a2…ak,addr1>,其中,ai(i=1,2,…,k)为0或1,容器路由表中本存储节点的路由项记为<b1b2…bw,addr1>,其中,bi(i=1,2,…,w)为0或1,k和w是大于或等于1的整数;进行数据迁移前,所述新存储节点的数据块子索引为空,容器计数器为空;如图5所示,所述数据迁移命令的执行依次包括如下步骤:

111)、子索引迁移:读取本存储节点的数据块子索引中的所有二元组,对于读取的每个二元组<fp,cid>,如果指纹fp的第k+1位为0,则将<fp,cid>发送给地址为addr2的新存储节点的指纹查询模块,并向其发送数据块子索引更新命令;如果指纹fp的第k+1位为1,则将<fp,cid>发送给地址为addr3的新存储节点的指纹查询模块,并向其发送数据块子索引更新命令;

112)、重定向:将本存储节点接收到的指纹查询命令、指纹定位命令、数据块子索引更新命令重定向给新存储节点,即检测指纹的第k+1位,如果为0,则把相应的命令转发给地址为addr2的新存储节点执行;如果为1,则把相应的命令转发给地址为addr3的新存储节点执行;将本存储节点接收到的写容器命令重定向给新存储节点,即检测容器相似签名的第w+1位,如果为0,则把写容器命令转发给地址为addr2的新存储节点执行;如果为1,则把写容器命令转发给地址为addr3的新存储节点执行;对本存储节点接收到的读容器命令、读容器指纹命令进行重定向,即检测容器标识符的编号,如果编号为num1,则由本存储节点执行命令,如果编号为num2,则把相应的命令转发给地址为addr2的新存储节点执行;如果编号为num3,则把相应的命令转发给地址为addr3的新存储节点执行;

113)、容器迁移:从本存储节点的容器存储池中读取其存储的所有容器,对于读取的每个容器,检测容器相似签名的第w+1位,如果为0,则把该容器发送给地址为addr2的新存储节点,并向其发送写容器命令;如果为1,则把该容器发送给地址为addr3的新存储节点,并向其发送写容器命令;

114)、路由更新:

首先:将本存储节点的指纹路由表和容器路由表发送给新存储节点,作为新存储节点的指纹路由表和容器路由表;

然后:向存储节点集群中包含的所有存储节点包括新存储节点广播路由更新,将指纹路由表中的路由项<a1a2…ak,addr1>删除,并增加新路由项<a1a2…ak0,addr2>和<a1a2…ak1,addr3>;将容器路由表中的路由项<b1b2…bw,addr1>删除,并增加新路由项<b1b2…bw0,addr2>和<b1b2…bw1,addr3>;

结束:本存储节点停止接收客户机的数据备份和恢复请求,本存储节点已有的读容器命令、读容器指纹命令,数据备份和数据恢复作业执行完毕后退出。

所述数据迁移命令执行完毕后,本存储节点便退出了存储节点集群,同时两个新存储节点加入了存储节点集群,存储节点集群的存储容量和并行性能都得到了扩张;所述数据迁移过程对存储节点集群的其他存储节点透明,不影响存储节点集群正常工作。

本实施例中,使用数据迁移算法来增加存储节点,使得存储节点集群可以根据需要不断扩张,在存储节点集群扩张的过程中,指纹路由表和容器路由表也会自动更新;在配置中,既可以将指纹路由表和容器路由表配置成一样,这样每个存储节点只需要一张路由表,也可以将指纹路由表和容器路由表配置成不一样,这样可以将指纹查询和容器存储的负载灵活地分配给不同的存储节点;

假设将指纹路由表和容器路由表配置成一样,并且在初期存储节点集群配置有两个存储节点n1和n2,则路由表可设为{<0,n1>,<1,n2>},如果将n1扩张成两个存储节点n3和n4,则路由表自动更新为{<00,n3>,<01,n4>,<1,n2>},进一步将n2扩张成两个存储节点n5和n6,则路由表又自动更新为{<00,n3>,<01,n4>,<10,n5>,<11,n6>},通过数据迁移算法,存储节点集群可灵活扩张,保证系统具有较强的可扩展性。

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