一种基于二维地理位置信息的数据集分片方法

文档序号:6623601阅读:561来源:国知局
一种基于二维地理位置信息的数据集分片方法
【专利摘要】本发明公开了一种基于二维地理位置信息的数据集分片方法,包括:(1)将每条数据的二维的地理位置信息转化为2进制geoHash值;(2)依据geoHash值进行分片,每个分片有公共的geoHash前缀,并在分片的过程中建立或更新片索引;(3)当有新增数据时,在索引中查找与新增数据具有最长公共geoHash前缀的片,然后将数据插入到该片中,若数据插入导致片的大小超过设定值,则按照(2)对片进行分裂。本发明利用将二维地理位置信息转化为geoHash值后进行数据分片,能尽量的保证地理位置上相邻的数据被分在相同的片上,对基于地理位置的分布式应用有很好的优化作用。
【专利说明】一种基于二维地理位置信息的数据集分片方法

【技术领域】
[0001]本发明属于数据存储【技术领域】,具体涉及一种基于二维地理位置信息的数据集分片方法。

【背景技术】
[0002]在大数据时代,当数据量达到兆级别时,单个内存或磁盘存储不下。在这种情况下,需要将数据集以分布式的方式进行存储。当进行分布式存储时,需要对数据集进行分片,从而方便以片为单位对数据进行组织、管理、迁移等操作。当前热门的NOSQL数据库MongoDB在进行分布式存储时,正是先对数据集进行分片,然后在多个服务器上对片进行管理。
[0003]我们在数据库设计时,通常把一个较大的全局数据库按其数据项(即字段)或按某关键字的某些特征来进行划分,在这里我们称之为数据分片,划分出的各个片段组成一个个较小的局部数据库。
[0004]在进行数据分片时并不是盲目地对数据库进行划分。为了达到分片的目的,我们分片时必须遵循以下三个准则;数据分片的类型一般可分为水平分片、垂直分片、混合分片三类。
[0005](I)完备性准则;必须把全局数据库的所有数据都映射到各个局部数据库中,即绝不允许发生一个属于全局关系的数据项目而不属于任一个局部数据库的情况。
[0006](2)重构准则;划分所采用的方法必须确保能够由全局关系的各个局部数据库来重建全局数据库。
[0007](3)不相交准则;对于水平划分,要求一个全局关系被划分后所得的各个数据片段互相不重叠,垂直划可放宽此限制。
[0008]当前已有的分片方案中,一般是选择一个一维的属性作为片键,比如数据的ID,然后对这一维属性根据线性范围直接划分为不同的片,这些分片方式不能保证同一个片上的数据在地理上是相近的,或者即使利用了 GeoHash来分片,也只是将GeoHash作为一个普通的一维属性,然后根据GeoHash的范围进行划分,没有很好的利用GeoHash的特性,不能很好的保证片上数据在地理位置上是相邻的。
[0009]GeoHash是一种对地图上的点进行编码的方法,它逐步的对地图划分为一个个网格,并按照点所在的网格来标识点;它将点的二维经纬度信息转化成一个一维的串,并且在大部分情况下,两个串的公共前缀越长,他们在地理上就越接近,而且,串的长度越长,精度也就越高。


【发明内容】

[0010]针对现有技术所存在的上述技术问题,本发明提供了一种基于二维地理位置信息的数据集分片方法,能够保证地理上相邻的数据尽量分布在相同的片上。
[0011]一种基于二维地理位置信息的数据集分片方法,所述的数据集中每条数据均含有关于经度和纬度的二维地理位置信息,所述的数据集分片方法包括如下步骤:
[0012](I)将数据集中每条数据的二维地理位置信息转换为二进制的GeoHash值;
[0013](2)根据所述的GeoHash值对数据集进行分片且每个片中的数据具有公共的GeoHash前缀,并在分片过程中建立并更新片的索引树;
[0014](3)当数据集有新增数据时,从所述的索引树中查找出与该新增数据具有最长公共GeoHash前缀的片,并将该新增数据插入该片中;若插入新增数据后,该片的大小超过预设的上限值,则对该片进行分裂并更新索引树。
[0015]所述的步骤(2)中对数据集进行分片的过程如下:
[0016]初始时,新建一个片作为父片,将数据集中所有数据放入父片中,且令父片的公共GeoHash前缀为null ;此时,若父片的大小未超过预设的上限值M,则分片结束;若父片的大小超过上限值M,则对父片进行分裂:
[0017]将父片分成两个子片A0和A1,令子片A0的公共GeoHash前缀为0,子片A1的公共GeoHash前缀为I ;进而根据二进制GeoHash值的首位编码,将父片中的所有数据分配至子片A0和A1中,即GeoHash值首位编码为O的数据分配至子片A0中,GeoHash值首位编码为I的数据分配至子片A1中;分配完毕后,判断子片Ac^P A1的大小是否超过上限值M:若均未超过,则分片结束;若子片Ai的大小超过上限值M,则使子片Ai作为父片并对其进行分裂:
[0018]将父片Ai分成两个子片Aitl和An,i为O或1,令子片Ai0的公共GeoHash前缀为1,子片Ail的公共GeoHash前缀为il ;进而根据二进制GeoHash值的第二位编码,将父片Ai中的所有数据分配至子片Aitl和Ail中,即GeoHash值第二位编码为O的数据分配至子片Ai0中,GeoHash值第二位编码为I的数据分配至子片Ail中;分配完毕后,进而判断子片Aki和Ail的大小是否超过上限值M,若仍存在大小超过上限值M的子片,则根据以上操作继续对该子片进行分裂,直至所有子片大小都在上限值M以下,则分片结束。
[0019]所述的步骤(2)中通过以下方法建立并更新片的索引树:
[0020]分片过程中当初始新建一个片作为父片时,则为该父片对应新建一个索引节点并使该节点作为索引树的根节点,并使该索引节点的片地址对应为该父片在服务器中的存储地址,左孩子节点地址和右孩子节点地址均为null ;
[0021]在对任一父片进行分裂后,为分裂得到的且不为空的子片对应新建一个索引节点,并令该索引节点的片地址对应为子片在服务器中的存储地址,左孩子节点地址和右孩子节点地址均为null ;同时将父片对应索引节点的片地址置为null,左孩子节点地址指向父片分裂得到的且公共GeoHash前缀尾号为O的子片对应的索引节点在服务器中的存储地址,右孩子节点地址指向父片分裂得到的且公共GeoHash前缀尾号为I的子片对应的索引节点在服务器中的存储地址;
[0022]所述的索引节点均包含有三个地址:左孩子节点地址、片地址、右孩子节点地址。
[0023]所述的步骤(3)中通过以下方法从索引树中查找出与新增数据具有最长公共GeoHash前缀的片,并将该新增数据插入该片中:
[0024]从索引树的根节点开始,判断新增数据GeoHash值的首位编码:若首位编码为O,则根据根节点的左孩子节点地址查找到下一索引节点并作为当前节点;若首位编码为1,则根据根节点的右孩子节点地址查找到下一索引节点并作为当前节点;
[0025]判断当前节点是否为索引树的叶子节点:若是,则根据当前节点的片地址查找到对应的片,作为与新增数据具有最长公共GeoHash前缀的片,并将该新增数据插入该片中;若否,则判断新增数据GeoHash值的下一位编码:若下一位编码为0,则根据当前节点的左孩子节点地址查找到下一索引节点并使其作为当前节点;若首位编码为1,则根据当前节点的右孩子节点地址查找到下一索引节点并使其作为当前节点;
[0026]依此往下搜索直至判断出当前节点为索引树的叶子节点,则根据当前节点的片地址查找到对应的片,作为与新增数据具有最长公共GeoHash前缀的片,并将该新增数据插入该片中。
[0027]本发明分片方法利用地理位置信息作为片键,并利用GeoHash的特点,将具有相同GeoHash公共前缀的数据分在同一个片上,能尽量保证地理上相邻的数据分布在相同的片上。这种分片方式,对于基于地理位置的应用具有很好的实用价值,能够优化按照地理位置进行查询、统计的效率,能够按照地理位置范围来对数据进行管理,按照这种方式分片后查询效率大大提升。

【专利附图】

【附图说明】
[0028]图1为本发明分片方法的步骤流程示意图。
[0029]图2为分片索引结构的示意图。

【具体实施方式】
[0030]为了更为具体地描述本发明,下面结合附图及【具体实施方式】对本发明的技术方案进行详细说明。
[0031]以下更为具体讲述分片过程,首先需要分片的数据集中每条数据中的二维地理位置信息,即将经纬度值转化为geoHash ;如可将(纬度为42.6,经度为-5.6)转化成0110111111 11000 00100 00010,然后依据转化所得的这个二进制的geoHash值来对数据进行分片,geoHash值长度N根据数据地理位置精度要求进行配置,长度越长,误差越小。
[0032]如图1所示,具体的分片过程如下:
[0033](I)初始时,所有的数据都在同一个片上,这个片的公共geoHash的前缀长度初始时为0,即没有公共前缀,此时,建立一个索引的头节点,该头结点值域为初始片存储位置,左孩子和右孩子均为空。
[0034](2)如果片的数据量大于M,则将其拆分为两个子片,设父片的公共前缀为XXXXX,则两个子片的公共前缀分别为XXXXX0、XXXXX1 ;Μ值可根据应用的需求进行配置,M值大,则分片的大小越大,片的数量较少。
[0035](3)将geoHash前缀为xxxxxO的数据分配到公共前缀为xxxxxO的子片上,前缀为XXXXXl的数据分配到公共前缀为xxxxxl的子片上;数据分配完后,为不为空的子片建立新的节点,让父节点的左孩子指向前缀为xxxxxO的节点,右孩子指向xxxxxl节点;
[0036]如果子片的数据量还是大于M,则重复(2)?(3)过程。
[0037](4)如果片的公共前缀已经达到了最大值,即公共前缀已经与geoHash长度相同,片的数据量还是大于M,这种情况说明是geoHash精度不够或者同一个地点的数据很多,因为此时片中所有数据都有相同的geoHash,。这可能有如下3种情况:a) N的值设置过小;b)M设置过小;c)数据集中有大量数据集中在相同的地点上,对于a)b)种情况,可以调整N和M值后重新分片,对于c)可对该片中的数据再选择另外的关键字按照传统的方法再进行分片。
[0038]建立如图2所示的索引结构概念图,其中节点上方的值代表当前节点所代表的数据片的公共geoHash前缀,即该片中所有的数据的geoHash都具有该前缀。
[0039]索引中每个节点包含三个域,左孩子节点,右孩子节点,以及值域,值域代表当前片的存储位置。所有非叶子节点中的值域都为空,所有叶子节点中的左孩子和右孩子节点为空,叶子节点的值域一定不为空。
[0040]初始片分好后,如果有新增的数据,需要先在索引树中查找到需要插入的片,然后进行插入,插入后,如果片的大小超过M,则按照上述的分片过程对该片进行拆分。
[0041]查找的过程是根据待插入数据的geoHash值,从索引树的头结点和geoHash值得第一位开始,依次取出geoHash值的每一位的值,如果为0,则查找左子树,为I则查找右子树,直到查找到叶子节点。如果查找到不为空的叶子节点,则将数据插入到该节点指向的分片上;如果最后查找到空节点,则需要新建一个分片将数据插入,并且需要新建一个索引节点来替换该空节点。
[0042]按照上述方法步骤,我们对一个具体数据集进行分片操作,该数据集初始时有371222条数据,每条数据都具有经纬度信息,经纬度信息精确到小数点后6位。在本实施例中,将N设定为63位,以32位二进制位表示精度,31位二进制位表示纬度,数据分片大小M设定为500条数据;数据分片过程是在内存中进行的,编程语言采用java。
[0043]将数据读入内存后,用一个List进行存放,将所有数据的经纬度信息转化为63位的geoHash值;本实施例中采用分别将精度纬度转化之后再合并的方法。为了方便起见,将所有的geoHash前面再拼接一个O,刚好64位,可以用一个long型的变量存储。
[0044]初始化一个空的索引头,初始片为所有数据,初始公共geoHash前缀为O (因为第一步为了方便,每条数据的geoHash前面都拼接一个0)。
[0045]从初始片开始,按上述进行分裂,每个父片分裂得到两个子List,并对应的创建子节点。子节点的值域指向子List。并将父节点的孩子节点指向对应的子节点,然后将父节点的值域置为空。如果子List中的数据量仍然大于M,则继续分裂,直到分裂后的片数据量小于500。
[0046]当后面有新增数据时,按照上述相应操作进行数据插入,如果数据插入导致插入的片数据量大于500,则按照上述相应操作进行数据拆分。
[0047]我们对本实施方式做的一个矩形搜索的性能对比结果如下,矩形范围:左上角(经度127,纬度29),右下角(经度129,纬度27)。
[0048]内存分片搜索时间:0ms (按照本实施方式进行分片);
[0049]内存不分片搜索时间:16ms (不分片);
[0050]MongoDB搜索时间:3lms (按照id进行分片)。
【权利要求】
1.一种基于二维地理位置信息的数据集分片方法,所述的数据集中每条数据均含有关于经度和纬度的二维地理位置信息,所述的数据集分片方法包括如下步骤: (1)将数据集中每条数据的二维地理位置信息转换为二进制的GeoHash值; (2)根据所述的GeoHash值对数据集进行分片且每个片中的数据具有公共的GeoHash前缀,并在分片过程中建立并更新片的索引树; (3)当数据集有新增数据时,从所述的索引树中查找出与该新增数据具有最长公共GeoHash前缀的片,并将该新增数据插入该片中;若插入新增数据后,该片的大小超过预设的上限值,则对该片进行分裂并更新索引树。
2.根据权利要求1所述的数据集分片方法,其特征在于:所述的步骤(2)中对数据集进行分片的过程如下: 初始时,新建一个片作为父片,将数据集中所有数据放入父片中,且令父片的公共GeoHash前缀为null ;此时,若父片的大小未超过预设的上限值M,则分片结束;若父片的大小超过上限值M,则对父片进行分裂: 将父片分成两个子片A0和A1,令子片A0的公共GeoHash前缀为0,子片A1的公共GeoHash前缀为I ;进而根据二进制GeoHash值的首位编码,将父片中的所有数据分配至子片A0和A1中,即GeoHash值首位编码为O的数据分配至子片A0中,GeoHash值首位编码为I的数据分配至子片A1中;分配完毕后,判断子片Ac^P A1的大小是否超过上限值M:若均未超过,则分片结束;若子片Ai的大小超过上限值M,则使子片Ai作为父片并对其进行分裂: 将父片Ai分成两个子片Aitl和An,i为O或I,令子片Aitl的公共GeoHash前缀为1,子片Ail的公共GeoHash前缀为il ;进而根据二进制GeoHash值的第二位编码,将父片Ai中的所有数据分配至子片Aitl和Ail中,即GeoHash值第二位编码为O的数据分配至子片Aitl中,GeoHash值第二位编码为I的数据分配至子片Ail中;分配完毕后,进而判断子片Aitl和Ail的大小是否超过上限值M,若仍存在大小超过上限值M的子片,则根据以上操作继续对该子片进行分裂,直至所有子片大小都在上限值M以下,则分片结束。
3.根据权利要求2所述的数据集分片方法,其特征在于:所述的步骤(2)中通过以下方法建立并更新片的索引树: 分片过程中当初始新建一个片作为父片时,则为该父片对应新建一个索引节点并使该节点作为索引树的根节点,并使该索引节点的片地址对应为该父片在服务器中的存储地址,左孩子节点地址和右孩子节点地址均为null ; 在对任一父片进行分裂后,为分裂得到的且不为空的子片对应新建一个索引节点,并令该索引节点的片地址对应为子片在服务器中的存储地址,左孩子节点地址和右孩子节点地址均为null ;同时将父片对应索引节点的片地址置为null,左孩子节点地址指向父片分裂得到的且公共GeoHash前缀尾号为O的子片对应的索引节点在服务器中的存储地址,右孩子节点地址指向父片分裂得到的且公共GeoHash前缀尾号为I的子片对应的索引节点在服务器中的存储地址; 所述的索引节点均包含有三个地址:左孩子节点地址、片地址、右孩子节点地址。
4.根据权利要求3所述的数据集分片方法,其特征在于:所述的步骤(3)中通过以下方法从索引树中查找出与新增数据具有最长公共GeoHash前缀的片,并将该新增数据插入该片中: 从索引树的根节点开始,判断新增数据GeoHash值的首位编码:若首位编码为0,则根据根节点的左孩子节点地址查找到下一索引节点并作为当前节点;若首位编码为1,则根据根节点的右孩子节点地址查找到下一索引节点并作为当前节点; 判断当前节点是否为索引树的叶子节点:若是,则根据当前节点的片地址查找到对应的片,作为与新增数据具有最长公共GeoHash前缀的片,并将该新增数据插入该片中;若否,则判断新增数据GeoHash值的下一位编码:若下一位编码为0,则根据当前节点的左孩子节点地址查找到下一索引节点并使其作为当前节点;若首位编码为1,则根据当前节点的右孩子节点地址查找到下一索引节点并使其作为当前节点; 依此往下搜索直至判断出当前节点为索引树的叶子节点,则根据当前节点的片地址查找到对应的片,作为与新增数据具有最长公共GeoHash前缀的片,并将该新增数据插入该片中。
【文档编号】G06F17/30GK104199860SQ201410403157
【公开日】2014年12月10日 申请日期:2014年8月15日 优先权日:2014年8月15日
【发明者】吴朝晖, 刘娜, 陈华钧, 郑国轴 申请人:浙江大学
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1