一种基于动态镜像的实时数据仓库数据预存取方法
技术领域
本发明涉及一种实时数据仓库中实时数据访问预存取方法,具体涉及一种基于动态镜像技术的实时数据仓库中数据查询竞争处理方法。
背景技术
近年来,电子信息数据在企业的运营中越来越重要,企业需要对电子信息数据进行高效、及时、精确地分析。传统的数据仓库采用ETL工具周期性地从数据源中抽取数据,经过处理后加载到数据仓库,而数据抽取的周期通常为一个月一次、一周一次、或者一天一次,通常只支持历史数据的查询与分析,不能实时捕获数据源中的变化。然而,在实时数据仓库中,实时数据导入与实时数据查询会引发查询竞争问题,其产生的冲突将严重影响联机在线分析(On-Line AnalysisProcessing,OLAP)的精度和效率,降低了数据仓库的性能。
面对实时数据仓库中的数据查询与导入引发的竞争问题,近年来,开展了许多研究工作,包括提高数据库的性能、增加外部实时数据缓存、即时(Just In Time)合并外部数据缓存信息、反向即时数据合并、实时分区、主动分区等。
(1)单独实时数据缓存方法是使用一种与数据仓库分离的外部缓存。外部数据缓存持续更新,数据仓库使用数据抽取与转换工具(ETL工具)以批处理模式进行数据更新,所有实时数据或准实时数据的查询直接定位到外部的数据缓存,从而避免了在数据仓库中的查询竞争问题。但是,如果数量巨大的复杂查询与分析运行在外部实时数据缓存,则同样会出现数据仓库的查询竞争问题。
(2)简化和限制实时报表方法,需要实时数据的用户只能发出简单的查询要求,限制复杂查询语句。这种方法可以消除查询竞争,但是无法满足用户对复杂查询的要求。
(3)升级硬件,可以为高端的SMP数据库系统增加更多的节点或者为数据仓库配备更快的处理器和更大的内存。这种方法只能短期内解决问题,但是增加了成本并且可扩展性低。
(4)反向即时数据合并,将所需要的历史数据临时反向加载到实时数据缓存中,查询在缓存中进行。这种方法可以有效的解决查询竞争,但是,查询结果的精度却不尽理想。
(5)实时分区是将实时数据进行数据量均衡的分区,然后分别各分区数据进行查询导入操作。这种方法有效的缓解了查询竞争,但是关于分区的个数和数据量的均衡算法的研究一直未成熟,分区算法随着分区个数增加时间复杂度也线性增加,海量数据环境下给系统带来沉重的负担,难以满足实时性的要求。
因此,如何解决实时数据仓库中实时数据查询与数据导入引发的查询竞争问题,在保证数据查询精度的前提下,提供实时数据查询的效率,是实时数据仓库数据存取预处理必须解决的问题,也是本发明所要解决的问题。
发明内容
本发明的目的是为了解决在实时数据仓库中实时数据导入和实时数据查询相冲突的问题。当ETL工具连续向实时数据存储区加载数据时,此时,用户也会对实时数据存储区进行发送多次数据查询,而多次数据查询结果纳入同一个统计结果。由于数据被实时加载到实时数据存储区,若不考虑新加载的数据,OLAP查询结果的精度会受到影响;若考虑新加载的数据,查询的效率会降低。如何解决查询效率与查询结果精度的矛盾,本发明披露一种基于动态镜像结构的实时数据仓库预存取方法,解决此问题。
技术方案:一种基于动态镜像的实时数据仓库数据预存取方法,包括以下三个方面:
(1)实时数据仓库的分类ETL结构。
(2)在数据仓库外部构建动态存储区域,动态存储区域由多个数据镜像与基于双重链接的镜像索引组成;
(3)动态镜像管理,包括镜像创建与回收、基于双重链接的镜像索引维护。
本发明披露的基于动态镜像的实时数据仓库数据预存取方法,所述内容(1)实时数据仓库的分类ETL结构的具体包括如下:
(1.1)实时数据仓库的分类ETL结构包括实时ETL和历史ETL。ETL(ExtractTransform Load)过程可以实现对数据的清洗、转化和加载。OLTP系统中的数据,根据其数据生成时间戳,将查询任务提交之前与之后存入OLTP的数据分别由历史ETL和实时ETL对数据进行清洗、转化和加载。
(1.2)数据仓库存储区域分成实时数据存储区和静态数据存储区。历史ETL将OLTP系统中的历史数据清洗、转化和加载后,直接存入数据仓库的静态数据存储区。实时ETL将OLTP系统中的实时数据清洗、转化和加载后,存入动态存储区域,然后根据系统触发条件,由动态存储区域存入数据仓库的实时数据存储区。
(1.3)历史ETL将OLTP系统中查询任务提交时间之前存储的数据,以批处理方式直接导入数据仓库的静态数据存储区。
(1.4)实时ETL通过CDC技术捕获OLTP系统中查询任务提交时间之后更新的数据,并加载到动态存储区域。在动态存储区域实现对加载的实时数据进行分配存储空间、管理,当满足系统触发条件后,再以批处理方式导入到数据仓库中的实时数据存储区。
本发明披露的基于动态镜像的实时数据仓库数据预存取方法,所述内容(2)动态存储区域,包括动态镜像与基于双重链接的镜像索引。
动态镜像的具体内容包括如下:
(2.1)镜像是具有相同的逻辑结构和物理结构的数据存储区域,并根据数据查询任务的需求,在动态存储区中动态创建。系统可以将OLTP中实时数据加载至镜像中。
(2.2)当创建一个镜像时,系统在动态存储区中保存一个相应的镜像文件,用四元组表示:τ<image_address,image_size,data_id,timestape>。其中,image_address表示镜像在动态存储区中的首地址;image_size表示镜像分配的存储空间大小,默认为4MB;data_id表示镜像存储的数据源;timestamp表示数据的时间戳。
根据用户数据查询与更新的需求,系统可以对动态存储区域中镜像动态地分配与回收。为了提高镜像管理的效率,方便、快速地将镜像的数据批量导入到数据仓库的实时数据存储区,本发明披露了基于双重链接的镜像索引结构,具体内容包括如下:
(2.3)根据每个镜像文件中data_id,将所有data_id相同的镜像构建成一个镜像链表Link_img。镜像链表Link_img由链表头节点img_head和链表节点img_node组成。
(2.4)链表头节点img_head由镜像数据源data_id与指向链表第一个节点的地址head_next组成。由于在一个镜像链表中,所有镜像的数据源是来自同一的数据源,数据源data_id相同。指向链表第一个节点的地址head_next存放第一个镜像首地址image_address。
(2.5)根据镜像文件内容,链表节点img_node由镜像大小image_size,镜像数据时间戳timestamp,操作标识符tag,及指向下一个链表节点的地址img_next组成。
操作标识符tag用于记录当前镜像数据的操作类型,其初始值为0。若当前镜像内容节点的数据是从源数据库系统OLTP导入至动态存储区,则此镜像内容节点的操作标识符置为0;若当前镜像内容节点的数据需要从动态存储区批量加载至数据仓库的实时数据存储区,则操作标识符置为1。
对于当前镜像而言,若在动态存储区中,不存在来自同一数据源的镜像,则img_next设为空。否则,img_next存放下一个来自同一数据源的镜像的首地址image_address。
(2.6)在同一个镜像链表中,存储了来自同一数据源,但是更新时间不同的数据镜像信息。随着系统运行,最近更新数据的时间戳一定大于较早更新数据的时间戳,所以,镜像链表中的节点按其数据时间戳倒序(从大至小)排序。
(2.7)所有来自同一数据源的镜像构成一个镜像链表,称之为一个镜像桶bucket,其中镜像桶的首地址bucket_address为链表头节点地址。
(2.8)在动态存储区中,若存储了n个数据源的数据,就有n个镜像桶。为了加快镜像数据的查找与定位,本发明将多个镜像桶采用链表结构,构成一个镜像桶链表Link_bucket。镜像桶链表Link_bucket是一个无链表头节点的链表,仅仅由镜像桶链表节点bucket_node构成。
(2.9)每个镜像桶链表节点bucket_node由数据源data_id,镜像桶的首地址bucket_address,与指向下一个镜像桶链表节点的地址bucket_next组成。其中,数据源data_id存放对应的镜像链表的数据源data_id;镜像桶的首地址bucket_address存放对应镜像链表头节点地址;向下一个镜像桶链表节点的地址bucket_next存放下一个镜像桶的地址bucket_address。若动态存储区中不存在任何数据,即不存在任何数据源的镜像桶,则不存在镜像桶链表。在动态存储区中,若只有一个镜像桶,则其bucket_next为空;否则,bucket_next存放下一个bucket_address。
本发明披露的基于动态镜像的实时数据仓库数据预存取方法,所述内容(3)动态镜像管理,包括镜像创建与回收,及基于双重链接的镜像索引维护。下面分别说明其具体过程。
动态镜像创建的具体过程如下:
(3.1)当有新的数据New_Data需要从OLTP系统加载至动态存储区时,动态镜像管理模块在动态存储区中分配一块存储空间,创建一个镜像,用于存储新数据New_Data。同时,系统在动态存储区中保存一个相应的镜像文件,用四元组表示:τ<image_address,image_size,data_id,timestape>。
(3.2)动态镜像管理模块采用顺序查找方式,遍历镜像桶链表Link_bucket中的每个镜像链表节点bucket_node,检查新数据的数据源是否与镜像链表节点bucket_node的数据源data_id相同,即检查动态存储区中是否存在与新数据是属于同一数据源的数据。若存在,则转入(3.3);否则,若不存在,则转入(3.9)。
(3.3)根据镜像桶链表节点bucket_node的bucket_address,可以查找到来自同一数据源的镜像链表Link_img的头节点。
(3.4)为新创建的镜像,在对应的镜像链表中创建一个新的镜像链表节点new_img_node,其中new_img_node的镜像大小image_size设为其镜像文件四元组的image_size,数据时间戳timestamp为其镜像文件四元组的timestamp,操作标识符tag设为0,指向下一个链表节点的地址img_next设为空。
(3.5)根据其时间戳,将新镜像链表节点new_img_node插入至相应的Link_img。在镜像链表中,镜像节点按其数据更新时间戳倒序(从大至小)排序,所以,新镜像链表节点new_img_node的时间戳timestamp最大,将其插入在链表头节点之后。
(3.6)对于镜像M而言,若镜像的数据满足查询条件,或者接收到系统操作指令,需要将数据批量地从动态存储区导入数据仓库的实时数据存储区时,将镜像链表节点img_node的操作标识符tag设为1,同时,相应的数据批量地写入数据仓库的实时数据存储区。
(3.7)对于镜像M而言,若系统接收到数据更新指令,此时,动态镜像管理负责检查同一数据源的镜像数据是否正在从动态存储区导入数据仓库的实时数据存储区。
若存在,正在导入数据的镜像内容节点无法进行更新操作,则动态镜像管理在动态存储区采用步骤(3.1),分配存储空间,创建镜像,更新所属同一数据源的镜像链表,并接收来自OLTP的更新数据。以此类推,若需要将不断更新的数据导入动态存储区,系统不断分配存储空间,创建后续镜像,更新镜像链表。转入(3.11)。
若不存在,则转入步骤(3.8)。
(3.8)动态镜像管理模块在动态存储区中分配存储空间,创建镜像,用于存储新数据New_Data。同时,系统在动态存储区中保存相应的镜像文件,用四元组表示:τ<image_address,image_size,data_id,timestape>。
(3.9)为新数据源的镜像,创建一个新的镜像链表new_Link_img。链表头节点img_head的data_id存放镜像文件四元组的数据源data_id;指向链表第一个节点的地址head_next存放新创建的镜像首地址image_address。镜像链表节点img_node的镜像大小image_size、数据时间戳timestamp分别存放镜像文件四元组的image_size和timestamp,img_node的操作标识符tag设为0,img_node的指向下一个链表节点的地址img_next设为空。
(3.10)根据新创建的镜像链表new_Link_img,更新镜像桶链表Link_bucket。在原镜像桶链表的尾部增加一个新镜像桶链表节点new_bucket_node。bucket_node的数据源data_id存放新数据源的data_id,bucket_node的首地址bucket_address存放新创建的镜像链表new_Link_img的首地址,bucket_node的指向下一个镜像桶链表节点地址bucket_next设为空。
(3.11)动态镜像创建完毕,基于双重链表的镜像索引也完成相应的更新。
动态镜像回收的具体过程如下:
(3.12)对于镜像M而言,当系统将镜像的数据批量地从动态存储区导入数据仓库的实时数据存储区完毕后,实时数据仓库系统将发送反馈信息至动态镜像管理模块。
(3.13)动态镜像管理模块根据收到的反馈信息,释放导入镜像数据所占用的存储空间。
(3.14)动态镜像管理模块根据镜像的data_id和image_address,定位到同一数据源的镜像链表中对应的镜像链表节点,将其节点从镜像链表中删除。
(3.15)若删除镜像链表节点后,其所属镜像链表Link_img的节点个数为0,仅存在链表头节点时,则动态镜像管理块将此镜像链表所对应的镜像桶链表节点bucket_node从镜像桶链表Link_bucket中删除,并释放其占用的存储空间。
附图说明
图1为基于动态镜像的实时数据仓库预存取系统结构图;
图2为基于动态镜像的实时数据仓库预存取方法的镜像链表结构图;
图3为基于动态镜像的实时数据仓库预存取方法的镜像桶链表结构图;
图4为基于动态镜像的实时数据仓库预存取方法的动态镜像分配流程图;
图5为基于动态镜像的实时数据仓库预存取方法的动态镜像回收流程图。
具体实施方式
下面结合具体实施例,进一步阐明本发明,应理解这些实施例仅用于说明本发明而不用于限制本发明的范围,在阅读了本发明之后,本领域技术人员对本发明的各种等价形式的修改均落于本申请所附权利要求所限定的范围。
图1为基于动态镜像的实时数据仓库预存取系统结构图。可以看出,动态存储区域结构图中包括OLTP系统101、历史ETL102、实时ETL103、动态存储区域104、镜像1.1-镜像k.z、镜像管理模块106、数据仓库107、实时数据存储区108和静态数据存储区109;
OLTP系统101提供本技术要处理的数据,通过对数据的分析,将OLTP系统101中查询任务提交时间之前存在的数据分割为定期ETL102,将OLTP系统101中查询任务提交时间之后更新的数据分割为实时ETL103。
动态存储区域104用于存储由实时ETL存入的数据并对其进行管理,将实时数据在动态存储区中以镜像形式存储,即镜像1.1,镜像1.2……镜像1.x;镜像2.1……镜像2.y;……;镜像k.1……镜像k.z。在同一个镜像链表中,存储了来自同一数据源,但是更新时间不同的数据镜像信息。同时建立基于双重链接的镜像索引结构,在动态存储区域104中由镜像管理模块106对镜像索引进行管理,可以完成数据查询、更新、删除,当满足系统出发条件后再以批处理方式存入到数据仓库107中的实时数据存储区108中。
数据仓库107包含实时数据存储区108和静态数据存储区109。历史ETL102将OLTP系统101中查询任务提交时间之前存在的数据以批处理方式存入数据仓库107的静态数据存储区109中。
图2为基于动态镜像的实时数据仓库预存取技术镜像链表结构图。可以看出,镜像1.1所在的镜像链表包含链表头节点img_head1051、镜像数据源data_id1052、指向链表第一个节点的地址head_next1053和镜像1.1的首地址image_address1054。镜像1.2所在的镜像链表包含链表节点img_node1061、镜像大小image_size1062、镜像数据时间戳timestamp1063,操作标识符tag1064、指向下一个链表节点的地址img_next1065和镜像1.2的首地址image_address1066。
镜像1.1是其所在镜像链表中第一个镜像,所以其对应的镜像链表节点为链表头节点img_head1051,链表头节点img_head1051由镜像数据源data_id1052与指向链表第一个节点的地址head_next1053组成。由于在一个镜像链表中,所有镜像的数据源是来自同一的数据源,数据源data_id1052相同。指向链表第一个节点的地址head_next1053存放第一个镜像首地址image_address1054,也就是镜像1.1的首地址。
镜像1.2不是其所在镜像链表的第一个镜像,其对应的镜像链表节点为链表节点img_node1061,链表节点img_node1061由镜像大小image_size1062、镜像数据时间戳timestamp1063、操作标识符tag1064和指向下一个链表节点的地址img_next1065组成。
操作标识符tag1064用于记录当前镜像数据的操作类型,其初始值为0。若当前镜像内容节点的数据是从源数据库系统OLTP导入至动态存储区,则此镜像内容节点的操作标识符置为0;若当前镜像内容节点的数据需要从动态存储区批量加载至数据仓库的实时数据存储区,则操作标识符置为1。
对于当前镜像而言,若在动态存储区中,不存在来自同一数据源的镜像,则img_next1065设为空。否则,img_next1065存放下一个来自同一数据源的镜像的首地址image_address1066,也就是镜像1.2的首地址。
镜像1.1、镜像1.2和同数据源中的其他镜像之间用链表相连,具有相同的物理结构和逻辑结构,用于存放不同的时间更新的同源数据。
图3为基于动态镜像的实时数据仓库预存取技术镜像桶链表结构图。可以看出,镜像桶链表结构图中包括镜像桶链表节点bucket_node201、数据源data_id202、镜像桶的首地址bucket_address203和指向下一个镜像桶链表节点的地址bucket_next204。
镜像桶,是指将所有来自同一数据源的镜像组成一个镜像链表,称之为一个镜像桶bucket,其中镜像桶的首地址bucket_address203为链表头节点地址。
镜像桶链表节点bucket_node201由数据源data_id202、镜像桶的首地址bucket_address203与指向下一个镜像桶链表节点的地址bucket_next204组成。其中,数据源data_id202存放对应的镜像链表的数据源data_id;镜像桶的首地址bucket_address203存放对应镜像链表头节点地址;向下一个镜像桶链表节点的地址bucket_next204存放下一个镜像桶的地址bucket_address。若动态存储区中不存在任何数据,即不存在任何数据源的镜像桶,则不存在镜像桶链表。若在动态存储区中,若只有一个镜像桶,则其bucket_next204为空;否则,bucket_next204存放下一个bucket_address。
图4为基于动态镜像的实时数据仓库预存取技术动态镜像分配流程图。下面结合图4说明动态镜像分配的基本过程。
动态镜像由于动态存储区空间有限,当从源数据库系统中导入数据至动态存储区的镜像时,镜像不是按物理地址连续分配,所以,为了提高动态存储区的空间利用率,需要对动态镜像进行有效分配,保证动态存储区域中数据查询与数据导入。
S301:存在新的数据New_Data需要从OLTP系统加载至动态存储区;
S302:动态镜像管理模块在动态存储区中分配一块存储空间,创建一个镜像,用于存储新数据New_Data。同时,系统在动态存储区中保存一个相应的镜像文件,用四元组表示:τ<image_address,image_size,data_id,timestape>。
S303:动态镜像管理模块采用顺序查找方式,遍历镜像桶链表Link_bucket中的每个镜像链表节点bucket_node;
S304:检查新数据的数据源是否与镜像链表节点bucket_node的数据源data_id相同,即检查动态存储区中是否存在与新数据是属于同一数据源的数据。若存在,则转入S305;否则,若不存在,则转入S314。
S305:根据镜像桶链表节点bucket_node的bucket_address,可以查找到来自同一数据源的镜像链表Link_img的头节点;
S306:为新创建的镜像,在对应的镜像链表中创建一个新的镜像链表节点new_img_node,其中new_img_node的镜像大小image_size设为其镜像文件四元组的image_size,数据时间戳timestamp为为其镜像文件四元组的timestamp,操作标识符tag设为0,指向下一个链表节点的地址img_next设为空。
S307:根据其时间戳,将新镜像链表节点new_img_node插入至相应的Link_img。在镜像链表中,镜像节点按其数据更新时间戳倒序(从大至小)排序,所以,新镜像链表节点new_img_node的时间戳timestamp最大,将其插入再链表头节点之后。
S308:判断对于镜像M而言,镜像的数据是否满足查询条件,若满足,进入S310。
S309:判断对于镜像M而言是否接收到系统操作指令,需要将数据批量地从动态存储区导入数据仓库的实时数据存储区时,若接收到,进入S310。
S310:将镜像M对应的镜像链表节点img_node的操作标识符tag设为1;
S311:将镜像M相应的数据批量地写入数据仓库的实时数据存储区。
S312:对于镜像M而言,判断系统是否接收到数据更新指令,若接收到,进入S313。
S313:动态镜像管理负责检查同一数据源的镜像数据是否正在从动态存储区导入数据仓库的实时数据存储区,若存在,正在导入数据的镜像内容节点无法进行更新操作,则动态镜像管理在动态存储区采用步骤S301,分配存储空间,创建镜像,更新所属同一数据源的镜像链表,并接收来自OLTP的更新数据。以此类推,若需要将不断更新的数据导入动态存储区,系统不断分配存储空间,创建后续镜像,更新镜像链表。若不存在,进入S314。
S314:动态镜像管理模块在动态存储区中分配存储空间,创建镜像,用于存储新数据New_Data。同时,系统在动态存储区中保存相应的镜像文件,用四元组表示:τ<image_address,image_size,data_id,timestape>。
S315:为新数据源的镜像,创建一个新的镜像链表new_Link_img。链表头节点img_head的data_id存放镜像文件四元组的数据源data_id;指向链表第一个节点的地址head_next存放新创建的镜像首地址image_address。镜像链表节点img_node的镜像大小image_size、数据时间戳timestamp分别存放镜像文件四元组的image_size和timestamp,img_node的操作标识符tag设为0,img_node的指向下一个链表节点的地址img_next设为空。
S316:根据新创建的镜像链表new_Link_img,更新镜像桶链表Link_bucket。在原镜像桶链表的尾部增加一个新镜像桶链表节点new_bucket_node。bucket_node的数据源data_id存放新数据源的data_id,bucket_node的首地址bucket_address存放新创建的镜像链表new_Link_img的首地址,bucket_node的指向下一个镜像桶链表节点地址bucket_next设为空。
动态镜像创建完毕,基于双重链表的镜像索引也完成相应的更新。
图5为基于动态镜像的实时数据仓库预存取技术动态镜像回收流程图。下面结合图5说明动态镜像分配的基本过程。
当系统将镜像的数据批量地从动态存储区导入数据仓库的实时数据存储区完毕后,系统启动动态镜像回收过程,具体步骤如下:
S401:对于任一镜像M而言,系统定期地判断是否将镜像的数据批量地从动态存储区导入数据仓库的实时数据存储区完毕,若导入完毕,进入S402;否则,不做任何操作。
S402:实时数据仓库系统将发送反馈信息至动态镜像管理模块。
S403:动态镜像管理模块根据收到的反馈信息,释放导入镜像数据所占用的存储空间。
S404:动态镜像管理模块根据镜像的data_id和image_address,定位到同一数据源的镜像链表中对应的镜像链表节点,将其节点从镜像链表中删除。
S405:判断删除镜像链表节点后,其所属镜像链表Link_img的节点个数是否为0,即仅存在链表头节点,若是,进入S406。
S406:动态镜像管理块将此镜像链表所对应的镜像桶链表节点bucket_node从镜像桶链表Link_bucket中删除,并释放其占用的存储空间。