发明内容
有鉴于此,本发明提供一种基于HBase的Lob数据的存储方法及装置,在保证实用性的前提下实现大对象数据存储的问题。
本发明提供了一种基于HBase的Lob数据的存储方法,根据HTable对象扩展LobTable对象;设置用于识别Lob数据的Qualifier;设置HBase所对应的服务器向HDFS转存数据的转存进制,还包括:
客户端在向LobTable对象发送存储请求时,LobTable在确定所述存储请求中包括Qualifier时,确定所述存储请求携带Lob数据,则创建LobPut对象;
客户端将所述存储请求中携带的Lob数据写入LobPut对象提供的Lob输出流中;
LobPut对象接收写入了Lob数据的Lob输出流,并在每次接收到的满足第一阈值的数据块时,将满足该第一阈值的数据块生成相应的Put对象,其中,Put对象包括相应数据块在Lob数据中的块号;
将生成的Put对象提交至服务器端,以使服务器端根据提交的Put对象中所包括的块号的顺序,利用设置的转存机制,将各个Put对象对应的数据块依次转存至HDFS的Lob文件中。
优选地,
进一步包括:客户端调用LobTable对象向服务器端提交scan请求,其中,所述查询请求用于查询服务器端的Lob数据,并接收服务器端针对所述查询请求返回的Result,所述Result包括所述查询请求所查询的Lob数据的Row Key;LobTable对象将所述Result封装为LobResult对象,LobResult对象根据所查询的Lob数据的Row Key生成LobGet对象,以使LobGet对象根据所查询的Lob数据所对应的每一块数据块在Lob数据中的起始地址向服务器端分块读取Lob数据。
本发明还提供了一种基于HBase的大对象数据的存储方法,创建LobCorprocessor,设置HBase所对应的服务器向HDFS转存数据的转存进制,还包括:
服务器端利用Lob Corprocessor分块接收客户端分块提交的各个Put对象,其中,每个Put对象包括相应数据块在其对应Lob数据中的块号;
根据首次接收到的Put对象所对应数据块,确定HDFS***的Lob文件中当前是否包括与该数据块相关的数据,若是,利用设置的转存机制将首次接收到的Put对象所对应的数据块,对与其相关的数据进行更新;若否,利用设置的转存机制,将首次接收到的Put对象所对应的数据块,创建至Lob文件中;
并根据提交的Put对象中所包括的块号的顺序,利用设置的转存机制,将后续接收到的Put对象分别对应的数据块转存入Lob文件中,并根据每个数据块的块号将各个数据块组合为Lob数据。
优选地,进一步包括:通过调用PrePut对象抛出一个特定的Do Not RetryIO Exception的子类异常,以阻止Lob Corprocessor将各个Put对象所对应的数据块写入到HBase的操作。
优选地,
进一步包括:创建读取数据的LobScanner对象;
进一步包括:接收客户端通过LobGet提交的Get对象,所述Get对象中包括所查询的Lob数据的Row Key;Lob Corprocessor打开LobScanner对象;LobScanner对象根据所述Get对象中的Row Key确定所查询的Lob数据的存储位置,并在确定的存储位置中分块读取Lob数据的各个数据块,并将各个数据块转换为KeyValue形式,使得服务器端将该KeyValue形式的各个数据块返回给客户端;
或,
进一步包括:LobStore进一步以HFile文件的形式和MemStore形式存储Lob数据;
进一步包括:遍历HDFS中的Lob文件,并将遍历到的小于第二阈值的多个Lob数据合并到HFile文件中;
进一步包括:将合并为HFile文件的多个Lob数据的删除信息存储至MemStore中。
本发明还提供了一种客户端,包括:
扩展单元,用于根据HTable对象扩展LobTable对象;设置用于识别Lob数据的Qualifier;
处理单元,用于在向LobTable对象发送存储请求时,LobTable在确定所述存储请求中包括Qualifier时,确定所述存储请求携带Lob数据,则创建LobPut对象;
写入单元,用于将所述存储请求中携带的Lob数据写入LobPut对象提供的Lob输出流中;
接收单元,用于利用LobPut对象接收写入了Lob数据的Lob输出流,并在每次接收到的满足第一阈值的数据块时,将满足该第一阈值的数据块生成相应的Put对象,其中,Put对象包括相应数据块在Lob数据中的块号;
提交单元,用于将生成的Put对象提交至服务器端,以使服务器端根据预先设置的HBase所对应的服务器向HDFS转存数据的转存进制,以及根据提交的Put对象中所包括的块号的顺序,将各个Put对象对应的数据块依次转存至HDFS的Lob文件中。
优选地,
进一步包括:数据查询单元,用于调用LobTable对象向服务器端提交查询请求,其中,所述查询请求用于查询服务器端的Lob数据,并接收服务器端针对所述查询请求返回的Result,所述Result包括所述查询请求所查询的Lob数据的Row Key;LobTable对象将所述Result封装为LobResult对象,LobResult对象根据所查询的Lob数据的Row Key生成LobGet对象,以使LobGet对象根据所查询的Lob数据所对应的每一块数据块在Lob数据中的起始地址向服务器端分块读取Lob数据。
本发明还提供了一种服务器,包括:
存储单元,用于创建Lob Corprocessor,设置HBase所对应的服务器向HDFS转存数据的转存进制;
接收单元,用于利用Lob Corprocessor分块接收客户端分块提交的各个Put对象,其中,每个Put对象包括相应数据块在其对应Lob数据中的块号;
处理单元,用于根据首次接收到的Put对象所对应数据块,确定HDFS***的Lob文件中当前是否包括与该数据块相关的数据,若是,利用设置的转存机制将首次接收到的Put对象所对应的数据块,对与其相关的数据进行更新;若否,利用设置的转存机制,将首次接收到的Put对象所对应的数据块,创建至Lob文件中;
转存单元,用于根据提交的Put对象中所包括的块号的顺序,利用设置的转存机制,将后续接收到的Put对象分别对应的数据块转存入Lob文件中,并根据每个数据块的块号将各个数据块组合为Lob数据。
优选地,
进一步包括:阻止单元,用于通过调用PrePut对象抛出一个特定的DoNot Retry IO Exception的子类异常,以阻止Lob Corprocessor将各个Put对象所对应的数据块写入到HBase的操作。
优选地,
所述存储单元,用于创建读取数据的LobScanner对象;
进一步包括:查询单元,用于接收客户端通过LobGet提交的Get对象,所述Get对象中包括所查询的Lob数据的Row Key;Lob Corprocessor打开LobScanner对象;LobScanner对象根据所述Get对象中的Row Key确定所查询的Lob数据的存储位置,并在确定的存储位置中分块读取Lob数据的各个数据块,并将各个数据块转换为KeyValue形式,使得服务器端将该KeyValue形式的各个数据块返回给客户端;
或,
进一步包括:LobStore进一步以HFile文件的形式和MemStore形式存储Lob数据;
进一步包括:遍历单元,用于遍历HDFS中的Lob文件,并将遍历到的小于第二阈值的多个Lob数据合并到HFile文件中;
进一步包括:合并单元,用于将合并为HFile文件的多个Lob数据的删除信息存储至MemStore中。
本发明实施例提供了一种基于HBase的Lob数据的存储方法及装置,在将Lob数据存储到服务器端时,由客户端根据预设值,分块上传Lob数据至HBase的服务器端,由服务器端根据分块上传的数据块进行存储,从而避免了服务器端内存溢出的问题。另外,为了避免客户端学习两种存储技术,客户端可以将Lob数据随其他结构化数据均上传至服务器端,由服务器端将Lob数据转存至HDFS中的Lob文件中,客户端只需对数据存储至HBase的存储方式进行编程,从而降低了客户端的工作量,提高了针对数据存储至HBase的存储方式的实用性。
具体实施方式
下面将结合本发明实施例中的附图,对本发明实施例中的技术方案进行清楚、完整地描述。显然,所描述的实施例仅是本发明一部分实施例,而不是全部的实施例。基于本发明中的实施例,本领域普通技术人员在没有做出创造性劳动前提下所获得的所有其他实施例,都属于本发明保护的范围。
如图1所示,本发明实施例提供了一种基于HBase的Lob数据的存储方法,根据HTable对象扩展LobTable对象;设置用于识别Lob数据的Qualifier;设置HBase所对应的服务器向HDFS转存数据的转存进制,该方法可以包括以下步骤:
步骤101:客户端在向LobTable对象发送存储请求时,LobTable在确定存储请求中包括Qualifier时,确定存储请求携带Lob数据,则创建LobPut对象。
步骤102:客户端将存储请求中携带的Lob数据写入LobPut对象提供的Lob输出流中。
步骤103:LobPut对象接收写入了Lob数据的Lob输出流,并在每次接收到的满足第一阈值的数据块时,将满足该第一阈值的数据块生成相应的Put对象,其中,Put对象包括相应数据块在Lob数据中的块号。
步骤104:将生成的Put对象提交至服务器端,以使服务器端根据提交的Put对象中所包括的块号的顺序,利用设置的转存机制,将各个Put对象对应的数据块依次转存至HDFS的Lob文件中。
根据上述方案,在将Lob数据存储到服务器端时,由客户端根据预设值,分块上传Lob数据至HBase的服务器端,由服务器端根据分块上传的数据块进行存储,从而避免了服务器端内存溢出的问题。另外,为了避免客户端学习两种存储技术,客户端可以将Lob数据随其他结构化数据均上传至服务器端,由服务器端将Lob数据转存至HDFS中的Lob文件中,客户端只需对数据存储至HBase的存储方式进行编程,从而降低了客户端的工作量,提高了针对数据存储至HBase的存储方式的实用性。
如图2所示,本发明实施例提供了一种基于HBase的大对象数据的存储方法,创建Lob Corprocessor,设置HBase所对应的服务器向HDFS转存数据的转存进制,该方法可以包括以下步骤:
步骤201:服务器端利用Lob Corprocessor分块接收客户端分块提交的各个Put对象,其中,每个Put对象包括相应数据块在其对应Lob数据中的块号。
步骤202:根据首次接收到的Put对象所对应数据块,确定HDFS***的Lob文件中当前是否包括与该数据块相关的数据,若是,利用设置的转存机制将首次接收到的Put对象所对应的数据块,对与其相关的数据进行更新;若否,利用设置的转存机制,将首次接收到的Put对象所对应的数据块,创建至Lob文件中。
步骤203:并根据提交的Put对象中所包括的块号的顺序,利用设置的转存机制,将后续接收到的Put对象分别对应的数据块转存入Lob文件中,并根据每个数据块的块号将各个数据块组合为Lob数据。
根据上述方案,服务器端根据分块上传的数据块进行分块存储,从而避免了服务器端内存溢出的问题。另外,为了避免客户端学习两种存储技术,客户端可以将Lob数据随其他结构化数据均上传至服务器端,由服务器端将Lob数据转存至HDFS中的Lob文件中,客户端只需对数据存储至HBase的存储方式进行编程,从而降低了客户端的工作量,提高了针对数据存储至HBase的存储方式的实用性。
为使本发明的目的、技术方案和优点更加清楚,下面结合附图及具体实施例对本发明作进一步地详细描述。
如图3所示,本发明实施例提供了一种基于HBase的大对象数据的存储方法,该方法可以包括以下步骤:
步骤301:构建存储模型,服务器端为每个Region关联一个对应的LobStore,并设置HBase的服务器端向HDFS转存数据的转存机制。
如图4所示,在本实施例中,LobStore在存储对象时可以使用下述三种形式进行存储:
Lob文件:Lob文件存储于HDFS中,当客户端在向服务器端存储Lob对象时,由服务器端将Lob对象转存入HDFS中的Lob文件中,其中,Lob对象的原始值(视频文件的二进制值)直接存储在HDFS,每次Put值都是直接写lob文件。其中,存储为Lob文件的文件名可以包括:row+列族+列名;其目录为:table目录/region/Lob。
HFile:用于将小Lob对象组合成HFile,避免在HDFS上产生大量小对象文件。此类文件是在表压缩时产生的。其中,存储为HFile的key值可以包括:业务表row+f+q,Value值可以包括:小Lob值或DEL。
MemStore:记录Lob对象的Deleted,其作用是在表压缩时用来清除已经删除的小Lob对象。
在本实施例中,可以对Lob列进行如下定义:在HBase Table的[Family+Qualifier]级别定义,声明某个表的Qualifier是否Lob列。当接收到存储请求或查询请求时,可以根据该Qualifier确定所存储或所查询的数据是否为Lob对象。
进一步地,可以定义“大Lob数据”和“小Lob数据”的阈值,例如,该阈值为10M,小于该阈值的Lob数据称之为“小Lob数据”,该小Lob数据使用HFile格式进行存储,大于该阈值的Lob数据称之为“大Lob数据”,该大Lob数据存储为HDFS中单对单的Lob文件。
步骤302:客户端向HBase的服务器端实现数据存储。
如图4所示,在本实施例中,客户端可以通过如下方式向HBase的服务器端实现数据存储或更新(put):
1、客户端向LobTable对象发送存储put请求。
2、LobTable在确定put请求中携带结构化数据时,该结构化数据如二维表类型的数据,向服务器端提交该Put请求,并执行3步骤;在确定put请求中携带非结构化数据时,该非结构化数据如Lob数据,执行4步骤。
3、将结构化数据正常存储至HBase数据库中的HBase Store中。
4、LobTable创建LobPut对象。
5、客户端将put请求中携带的Lob数据写入LobPut对象所提供的Lob输出流中。其中,该Lob输出流可以看作是客户端的该LobPut对象向服务器端发送的数据流。
6、LobPut对象接收写入了Lob数据的Lob输出流,并分块读取Lob数据,并将分块读取的Lob数据的数据块分别生成对应的Put对象。其中,设定分块读取的阈值可以是4M。例如,每次读取Lob数据满4M时所对应的数据块。其中,当读取到最后一个Lob数据的数据块时,该数据块可能不满4M。
7、将各个Put对象提交至服务器端的HRegion,其中,Put对象包括相应数据块在Lob数据中的块号。
8、服务器端所创建的Lob Corprocessor分块接收各个Put对象对应的数据块。
9、Lob Corprocessor利用设置的转存机制,将接收到的各个Put对象所对应的数据块依次转存至HDFS中的Lob文件中。
在本步骤9中,Lob Corprocessor根据首次接收到的Put对象所对应数据块,确定HDFS***的Lob文件中当前是否包括与该数据块相关的数据,若是,利用设置的转存机制将首次接收到的Put对象所对应的数据块,对与其相关的数据进行更新;若否,利用设置的转存机制,将首次接收到的Put对象所对应的数据块,创建至Lob文件中;并根据提交的Put对象中所包括的块号的顺序,利用设置的转存机制,将后续接收到的Put对象分别对应的数据块转存入Lob文件中,并根据每个数据块的块号将各个数据块组合为Lob数据。
在上述步骤处理结束后,还可以包括:通过调用PrePut对象抛出一个特定的Do Not Retry IO Exception的子类异常,以阻止Lob Corprocessor将各个Put对象所对应的数据块写入到HFile的操作。
其中,客户端新定义的2个新的API:LobTable、LobPut,分别继承自HBase原来的类:HTable和Put。其中,LobTable、LobPut都可以理解为客户端上的接口。另外,客户端在存储Lob数据之前,还可以提交lob列值为byte[0]的Put对象,以将主键存储至HBase中。
步骤303:客户端实现向HBase的服务器端实现数据查询。
如图5所示,在本实施例中,客户端实现向HBase的服务器端的数据查询时,可以扩展如下三个API:LobTable、LobResult和LobGet,可以通过如下方式实现数据查询(scan):
1、客户端向LobTable对象发送Scan请求。
2、LobTable对象向服务器端提交该Scan请求。
3、服务器端的HRegion根据该Scan请求向客户端返回Result。其中,该Result中包括scan请求所查询的Lob数据的Row Key。
4、LobTable对象根据Result中包括Row Key,将Result封装为LobResult对象。
5、LobResult对象根据所查询的Lob数据的Row Key生成LobGet对象。
6、LobGet对象根据所查询的Lob数据所对应的每一块数据块的起始地址向服务器端分块读取Lob数据。其中,LobGet对象也需要分块读取Lob数据,分块读取的阈值可以是4M,LobGet对象根据Lob数据每个数据块的起始地址,向服务器端分块读取。
7、HRegion接收客户端通过LobGet提交的Get对象,Get对象中包括所查询的Lob数据的Row Key。
8、Lob Corprocessor打开LobScanner对象。
9、LobScanner对象根据Get对象中的Row Key,确定Lob数据的存储位置是HFile还是Lob文件,若存储位置是HFile,则直接读取KeyValue值返回给客户端的LobGet对象,并返回给客户端EOF结束标识,若存储位置是Lob文件,LobScanner对象根据每个数据块的起始地址,读取各个数据库,并将各个数据块转换为KeyValue形式,使得服务器端将该KeyValue形式的各个数据块返回给客户端中的LobGet对象。并返回给客户端EOF结束标识。
10、客户端根据LobGet对象提供的输入流中读取数据。其中,该输入流可以看作是LobPut对象从服务器端获取数据的数据流。
在本实施例中,由于对某些应用场景中的Lob数据的大小不太确定,比如网盘应用中存储的文件可能有几kb,也可能有几百MB或上GB。如果将所有的Lob数据均存储在HDFS中的Lob文件中,那么过多的小文件可能会影响HDFS***的效率。因此,可以将HDFS中Lob文件中的小Lob数据进行compact(合并)。
由于对于小Lob数据的问题,hadoop自身提供了三种解决方案:HadoopArchive、Sequence File和CombineFileInputFormat。但是这些方案中,小文件一旦合并到大的归档文件中就无法删除和修改,除非重新打包。因此,本实施例中,可以遍历HDFS中的Lob文件,将多个小于10M的小Lob数据进行合并,并保证合并的文件不大于另一个阈值,如,1G,并将合并后的文件存储到HBase中,存储格式为HFile。实际上HFile的内容也是不能修改删除的,对标记为DELETE的小lob KV,还是通过Major Compact进行清理。也就是遍历多个HFile,清理KV并生成新的HFile文件。
在本实施例中,可以由Lob Corprocessor判断是否lob列删除(包括整行删除、整个列族删除),然后生成lob列的delete对象,并存储到memstore,同时删除hdfs的lob文件(如果有)。
在本实施例中,由于LobStore是与一个Region关联的,因此在Region进行split(拆分)时,LobStore也需要split。其中,Lob文件的split只需要移动到不同目录即可。另外,HFile的split则需要全部遍历,并根据split key进行拆分到不同的Region。
如图6所示,本发明实施例还提供了一种客户端,包括:
扩展单元601,用于根据HTable对象扩展LobTable对象;设置用于识别Lob数据的Qualifier;
处理单元602,用于在向LobTable对象发送存储请求时,LobTable在确定所述存储请求中包括Qualifier时,确定所述存储请求携带Lob数据,则创建LobPut对象;
写入单元603,用于将所述存储请求中携带的Lob数据写入LobPut对象提供的Lob输出流中;
接收单元604,用于利用LobPut对象接收写入了Lob数据的Lob输出流,并在每次接收到的满足第一阈值的数据块时,将满足该第一阈值的数据块生成相应的Put对象,其中,Put对象包括相应数据块在Lob数据中的块号;
提交单元605,用于将生成的Put对象提交至服务器端,以使服务器端根据预先设置的HBase所对应的服务器向HDFS转存数据的转存进制,以及根据提交的Put对象中所包括的块号的顺序,将各个Put对象对应的数据块依次转存至HDFS的Lob文件中。
进一步包括:数据查询单元606,用于调用LobTable对象向服务器端提交查询请求,其中,所述查询请求用于查询服务器端的Lob数据,并接收服务器端针对所述查询请求返回的Result,所述Result包括所述查询请求所查询的Lob数据的Row Key;LobTable对象将所述Result封装为LobResult对象,LobResult对象根据所查询的Lob数据的Row Key生成LobGet对象,以使LobGet对象根据所查询的Lob数据所对应的每一块数据块在Lob数据中的起始地址向服务器端分块读取Lob数据。
如图7所示,本发明实施例还提供了一种服务器,包括:
存储单元701,用于创建Lob Corprocessor,设置HBase所对应的服务器向HDFS转存数据的转存进制;
接收单元702,用于利用Lob Corprocessor分块接收客户端分块提交的各个Put对象,其中,每个Put对象包括相应数据块在其对应Lob数据中的块号;
处理单元703,用于根据首次接收到的Put对象所对应数据块,确定HDFS***的Lob文件中当前是否包括与该数据块相关的数据,若是,利用设置的转存机制将首次接收到的Put对象所对应的数据块,对与其相关的数据进行更新;若否,利用设置的转存机制,将首次接收到的Put对象所对应的数据块,创建至Lob文件中;
转存单元704,用于根据提交的Put对象中所包括的块号的顺序,利用设置的转存机制,将后续接收到的Put对象分别对应的数据块转存入Lob文件中,并根据每个数据块的块号将各个数据块组合为Lob数据。
进一步包括:阻止单元705,用于通过调用PrePut对象抛出一个特定的Do Not Retry IO Exception的子类异常,以阻止Lob Corprocessor将各个Put对象所对应的数据块写入到HBase的操作。
所述存储单元,用于创建读取数据的LobScanner对象;
进一步包括:查询单元706,用于接收客户端通过LobGet提交的Get对象,所述Get对象中包括所查询的Lob数据的Row Key;Lob Corprocessor打开LobScanner对象;LobScanner对象根据所述Get对象中的Row Key确定所查询的Lob数据的存储位置,并在确定的存储位置中分块读取Lob数据的各个数据块,并将各个数据块转换为KeyValue形式,使得服务器端将该KeyValue形式的各个数据块返回给客户端;
或,
进一步地,LobStore进一步以HFile文件的形式和MemStore形式存储Lob数据;
进一步包括:遍历单元707,用于遍历HDFS中的Lob文件,并将遍历到的小于第二阈值的多个Lob数据合并到HFile文件中;
进一步包括:合并单元708,用于将合并为HFile文件的多个Lob数据的删除信息存储至MemStore中。
如上所述,本发明实施例至少可以包括如下有益效果:
1、在将Lob数据存储到服务器端时,由客户端根据预设值,分块上传Lob数据至HBase的服务器端,由服务器端根据分块上传的数据块进行存储,从而避免了服务器端内存溢出的问题。
2、为了避免客户端学习两种存储技术,客户端可以将Lob数据随其他结构化数据均上传至服务器端,由服务器端将Lob数据转存至HDFS中的Lob文件中,客户端只需对数据存储至HBase的存储方式进行编程,从而降低了客户端的工作量,提高了针对数据存储至HBase的存储方式的实用性。
上述设备内的各单元之间的信息交互、执行过程等内容,由于与本发明方法实施例基于同一构思,具体内容可参见本发明方法实施例中的叙述,此处不再赘述。
需要说明的是,在本文中,诸如第一和第二之类的关系术语仅仅用来将一个实体或者操作与另一个实体或操作区分开来,而不一定要求或者暗示这些实体或操作之间存在任何这种实际的关系或者顺序。而且,术语“包括”、“包含”或者其任何其他变体意在涵盖非排他性的包含,从而使得包括一系列要素的过程、方法、物品或者设备不仅包括那些要素,而且还包括没有明确列出的其他要素,或者是还包括为这种过程、方法、物品或者设备所固有的要素。在没有更多限制的情况下,由语句“包括一个······”限定的要素,并不排除在包括所述要素的过程、方法、物品或者设备中还存在另外的相同因素。
本领域普通技术人员可以理解:实现上述方法实施例的全部或部分步骤可以通过程序指令相关的硬件来完成,前述的程序可以存储在计算机可读取的存储介质中,该程序在执行时,执行包括上述方法实施例的步骤;而前述的存储介质包括:ROM、RAM、磁碟或者光盘等各种可以存储程序代码的介质中。
最后需要说明的是:以上所述仅为本发明的较佳实施例,仅用于说明本发明的技术方案,并非用于限定本发明的保护范围。凡在本发明的精神和原则之内所做的任何修改、等同替换、改进等,均包含在本发明的保护范围内。