本发明涉及数据库技术领域,更具体的,涉及一种全局且递增的id生成方法及系统。
背景技术:
在分布式系统中,当数据量巨大一张表无法承接时,就会涉及到分库分表操作。为了便于对分库分表后的数据进行查询、更新、迁移等操作,需要生成系统唯一主键id,系统唯一主键id具有以下特性:在整个系统id唯一、id是数字类型且是趋势递增的、简短便于查询。
在分布式系统中存在多个用于生成系统唯一主键id的服务器,如何保证多个服务器生成的系统唯一主键id不重复成为本领域亟待解决的技术问题。
技术实现要素:
有鉴于此,本发明提供了一种全局且递增的id生成方法及系统,保证分布式系统中多个服务器生成系统id的唯一性。
为了实现上述发明目的,本发明提供的具体技术方案如下:
一种全局且递增的id生成方法,应用于全局且递增的id生成系统,所述id生成系统包括zookeeper服务器和多个id服务器,所述方法包括:
所述zookeeper服务器在检测到目标id服务器未注册的情况下,生成所述目标id服务器对应的zookeeper持久顺序节点,所述目标id服务器为所述id生成系统中的任意一个id服务器;
所述zookeeper服务器依据已注册id服务器对应的zookeeper持久顺序节点中存储的机器码标识,按照机器码标识递增的顺序,生成所述目标id服务器的机器码标识,并将所述目标id服务器的机器码标识存储在相应的zookeeper持久顺序节点中,完成对所述目标id服务器的注册;
所述目标id服务器依据自身的机器码标识生成系统id,所述系统id包括第一预设位数的时间戳、第二预设位数的机器码标识和第三预设位数的自增序列。
可选的,在所述目标id服务器依据自身的机器码标识生成系统id之前,所述方法还包括:
所述zookeeper服务器在检测到目标id服务器已注册的情况下,获取所述目标id服务器的本地系统时间;
所述zookeeper服务器获取所有正在提供服务的id服务器的本地系统时间的平均值;
所述zookeeper服务器判断所述目标id服务器的本地系统时间与所述平均值的绝对值是否小于阈值;
若小于所述阈值,所述zookeeper服务器提示所述目标id服务器启动成功;
若不小于所述阈值,所述zookeeper服务器提示所述目标id服务器启动失败,启动报警机制。
可选的,所述目标id服务器的机器码标识包括机房码和机器码。
可选的,所述方法还包括:
所述id生成系统中的每个id服务器基于网络时间同步协议实现时钟同步。
可选的,所述方法还包括:
所述目标id服务器获取所述当前系统时间以及与所述当前系统时间邻近的存储周期内生成系统id的最新时间;
所述目标id服务器计算所述当前系统时间与生成系统id的最新时间之间的时间偏差值;
所述目标id服务器根据所述时间偏差值确定id生成策略,并执行所述id生成策略。
可选的,所述目标id服务器计算所述当前系统时间与生成系统id的最新时间之间的时间偏差值,包括:
所述目标id服务器判断生成系统id的最新时间是否大于所述当前系统时间;
若大于所述当前系统时间,所述目标id服务器计算生成系统id的最新时间与所述当前系统时间之间由于时钟回拨产生的回拨时间偏差值;
若不大于所述当前系统时间,所述目标id服务器计算所述当前系统时间与生成系统id的最新时间之间的增量时间偏差值。
可选的,所述目标id服务器根据所述时间偏差值确定id生成策略,并执行所述id生成策略,包括:
所述目标id服务器在所述增量时间偏差值不小于0的情况下,获取生成系统id的最新时间对应的系统id的自增序列值;
所述目标id服务器判断所述自增序列值是否大于预设增量最大值;
若是,所述目标id服务器的本地时钟从下一毫秒开始计时,得到最新的当前系统时间,依据自身的机器码标识和最新的当前系统时间生成系统id,并更新生成系统id的最新时间和相应系统id的自增序列值;
若否,所述目标id服务器依据自身的机器码标识和所述当前系统时间生成系统id,并更新生成系统id的所述最新时间和相应系统id的自增序列值。
可选的,所述目标id服务器根据所述时间偏差值确定id生成策略,并执行所述id生成策略,包括:
所述目标id服务器判断所述回拨时间偏差值是否小于回拨阈值;
若不小于所述回拨阈值,所述目标id服务器启动报警机制;
若小于所述阈值,所述目标id服务器的本地时钟继续计时两倍所述回拨阈值时间,得到最新的当前系统时间;
所述目标id服务器判断生成系统id的最新时间是否大于所述所述最新的当前系统时间;
若生成系统id的最新时间大于所述最新的当前系统时间,所述目标id服务器启动报警机制;
若生成系统id的最新时间不大于所述最新的当前系统时间,所述目标id服务器返回执行所述计算所述当前系统时间与生成系统id的最新时间之间的增量时间偏差值,这一步骤。
一种全局且递增的id生成系统,包括zookeeper服务器和多个id服务器;
所述zookeeper服务器,用于在检测到目标id服务器未注册的情况下,生成所述目标id服务器对应的zookeeper持久顺序节点,所述目标id服务器为所述id生成系统中的任意一个id服务器,依据已注册id服务器对应的zookeeper持久顺序节点中存储的机器码标识,按照机器码标识递增的顺序,生成所述目标id服务器的机器码标识,并将所述目标id服务器的机器码标识存储在相应的zookeeper持久顺序节点中,完成对所述目标id服务器的注册;
所述目标id服务器,用于依据自身的机器码标识生成系统id,所述系统id包括第一预设位数的时间戳、第二预设位数的机器码标识和第三预设位数的自增序列。
可选的,所述zookeeper服务器还用于:
在所述目标id服务器依据自身的机器码标识生成系统id之前,且在检测到目标id服务器已注册的情况下,获取所述目标id服务器的本地系统时间;
获取所有正在提供服务的id服务器的本地系统时间的平均值;
判断所述目标id服务器的本地系统时间与所述平均值的绝对值是否小于阈值;
若小于所述阈值,提示所述目标id服务器启动成功;
若不小于所述阈值,提示所述目标id服务器启动失败,启动报警机制。
可选的,所述目标id服务器的机器码标识包括机房码和机器码。
可选的,所述id生成系统中的每个id服务器,还用于基于网络时间同步协议实现时钟同步。
可选的,所述目标id服务器还用于:
获取当前系统时间以及生成系统id的最新时间;
计算所述当前系统时间与生成系统id的最新时间之间的时间偏差值;
根据所述时间偏差值确定id生成策略,并执行所述id生成策略。
可选的,所述目标id服务器具体用于:
判断生成系统id的最新时间是否大于所述当前系统时间;
若大于所述当前系统时间,计算生成系统id的最新时间与所述当前系统时间之间由于时钟回拨产生的回拨时间偏差值;
若不大于所述当前系统时间,计算所述当前系统时间与生成系统id的最新时间之间的增量时间偏差值。
可选的,所述目标id服务器具体用于:
在所述增量时间偏差值不小于0的情况下,获取生成系统id的最新时间对应的系统id的自增序列值;
判断所述自增序列值是否大于预设增量最大值;
若是,所述目标id服务器的本地时钟从下一毫秒开始计时,得到最新的当前系统时间,依据自身的机器码标识和最新的当前系统时间生成系统id,并更新生成系统id的最新时间和相应系统id的自增序列值;
若否,依据自身的机器码标识和所述当前系统时间生成系统id,并更新生成系统id的所述最新时间和相应系统id的自增序列值。
可选的,所述目标id服务器具体用于:
判断所述回拨时间偏差值是否小于回拨阈值;
若不小于所述回拨阈值,启动报警机制;
若小于所述回拨阈值,所述目标id服务器的本地时钟继续计时两倍所述回拨阈值时间,得到最新的当前系统时间;
判断生成系统id的最新时间是否大于所述最新的当前系统时间;
若生成系统id的最新时间大于所述最新的当前系统时间,启动报警机制;
若生成系统id的最新时间不大于所述最新的当前系统时间,返回执行所述计算所述当前系统时间与生成系统id的最新时间之间的增量时间偏差值,这一步骤。
相对于现有技术,本发明的有益效果如下:
本发明公开的一种全局且递增的id生成方法,通过zookeeper服务器维护系统内每个id服务器的机器码标识,根据已注册id服务器对应的zookeeper持久顺序节点中存储的机器码标识,按照机器码标识递增的顺序,生成未注册id服务器的机器码标识,保证系统中每个id服务器的机器码标识的唯一性,进而保证id服务器依据自身机器码标识生成的包括第一预设位数的时间戳、第二预设位数的机器码标识和第三预设位数的自增序列的系统id的唯一性。
附图说明
为了更清楚地说明本发明实施例或现有技术中的技术方案,下面将对实施例或现有技术描述中所需要使用的附图作简单地介绍,显而易见地,下面描述中的附图仅仅是本发明的实施例,对于本领域普通技术人员来讲,在不付出创造性劳动的前提下,还可以根据提供的附图获得其他的附图。
图1为现有技术中利用雪花算法生成系统id的结构示意图;
图2为本发明实施例公开的一种全局且递增的id生成方法的流程示意图;
图3为本发明实施例公开的另一种全局且递增的id生成方法的流程示意图;
图4为本发明实施例公开的另一种全局且递增的id生成方法的流程示意图;
图5为本发明实施例公开的另一种全局且递增的id生成方法的流程示意图;
图6为本发明实施例公开的一种全局且递增的id生成系统的结构示意图。
具体实施方式
下面将结合本发明实施例中的附图,对本发明实施例中的技术方案进行清楚、完整地描述,显然,所描述的实施例仅仅是本发明一部分实施例,而不是全部的实施例。基于本发明中的实施例,本领域普通技术人员在没有做出创造性劳动前提下所获得的所有其他实施例,都属于本发明保护的范围。
现有技术利用雪花算法(snowflake)生成64位的二进制正整数,然后转换成10进制的id,请参阅图1,利用雪花算法生成的64位的二进制正整数包括:1位标识符、41位时间戳、10位机器标识码以及12位序列值。其中,1位标识符始终是0;41位时间戳不是存储当前系统时间的时间戳,而是存储时间戳的差值(当前系统时间戳-开始时间戳),10位机器标识码可以部署在1024个节点;12位序列以毫秒内计数,12位的计数顺序号支持每个节点每毫秒产生4096个id序号。利用雪花算法生成id的方法每秒能生成409.6万个id,性能快,由于时间戳在高位自增序列在地位,整个id是趋势递增的,可以生成全局唯一且递增id。
发明人对上述利用雪花算法生成id的方法进行研究,发现上述利用雪花算法生成id的方法依赖机器标识码的唯一性,若分布式系统中出现机器标识码不唯一的问题导致重复id的生成,当分布式系统中存在多个用于生成id的服务器时,若采用人工维护,手动维护成本高,如何保证系统中的多个服务器的机器标识码的唯一性成为本领域亟待解决的技术问题。
为了解决上述技术问题,本发明公开了一种全局且递增的id生成方法,应用于全局且递增的id生成系统,所述id生成系统包括zookeeper服务器和多个id服务器,通过zookeeper服务器维护系统内每个id服务器的机器码标识,保证系统中每个id服务器的机器码标识的唯一性,进而保证id服务器依据自身机器码标识生成的包括第一预设位数的时间戳、第二预设位数的机器码标识和第三预设位数的自增序列的系统id的唯一性。
请参阅图2,本实施例公开的全局且递增的id生成方法具体包括以下步骤:
s101:zookeeper服务器在检测到目标id服务器未注册的情况下,生成所述目标id服务器对应的zookeeper持久顺序节点;
其中,所述目标id服务器为所述id生成系统中的任意一个id服务器。
当一个id服务器启动时,需要与zookeeper服务器进行交互,由zookeeper服务器检测该id服务器是否已经注册,若未注册,对该id服务器进行注册,若已注册,在检测到该id服务器启动成功时,该id服务器不再需要与zookeeper服务器进行交互,可以生成系统id,因此,id服务器生成系统id的过程对zookeeper服务器的依赖极小。
s102:所述zookeeper服务器依据已注册id服务器对应的zookeeper持久顺序节点中存储的机器码标识,按照机器码标识递增的顺序,生成所述目标id服务器的机器码标识,并将所述目标id服务器的机器码标识存储在相应的zookeeper持久顺序节点中,完成对所述目标id服务器的注册;
如已注册id服务器的机器码标识为0000000001、0000000002和0000000003,按照机器码标识递增的顺序,生成目标id服务器的机器码标识为0000000004。
若机器码标识包括2位机房码和8位机器码,如已注册的01机房的id服务器的机器码标识为0100000001、0100000002和0100000003,按照机器码标识递增的顺序,生成的01机房的目标id服务器的机器码标识为0100000004。
zookeeper持久顺序节点用于存储相应的目标id服务器的机器码标识,zookeeper服务器通过判断目标id服务器对应的zookeeper持久顺序节点中是否存储有机器码标识来判定目标id服务器是否已注册。
s103:所述目标id服务器依据自身的机器码标识生成系统id,所述系统id包括第一预设位数的时间戳、第二预设位数的机器码标识和第三预设位数的自增序列。
具体的,系统id可以包括1位标识符、41位时间戳、10位机器码标识和12位自增序列,需要说明的是,根据业务需要可以调整第一预设位数、第二预设位数和第三预设位数的值。
本实施例公开的一种全局且递增的id生成方法,通过zookeeper服务器维护系统内每个id服务器的机器码标识,根据已注册id服务器对应的zookeeper持久顺序节点中存储的机器码标识,按照机器码标识递增的顺序,生成未注册id服务器的机器码标识,保证系统中每个id服务器的机器码标识的唯一性,进而保证id服务器依据自身机器码标识生成的包括第一预设位数的时间戳、第二预设位数的机器码标识和第三预设位数的自增序列的系统id的唯一性。
发明人经过研究还发现:发现上述利用雪花算法生成id的方法依赖机器的时钟,在分布式场景中,每台id服务器上的时钟不可能完全同步,服务器时钟回拨会经常遇到,一般在10ms~100ms之间的回拨,如果id服务器时钟回拨会导致重复id的生成。
为了解决由于id服务器时钟回拨导致重复id生成的问题,本发明提供的全局且递增的id生成方法从两个方面提出解决方案。
其中,一种解决服务器时钟回拨导致重复id生成的问题的方法为:在id服务器启动之前判断id服务器是否发生时钟回拨,具体的,请参阅图3,一种全局且递增的id生成方法包括如下步骤:
s201:zookeeper服务器在检测到目标id服务器未注册的情况下,生成所述目标id服务器对应的zookeeper持久顺序节点;
s202:所述zookeeper服务器依据已注册id服务器对应的zookeeper持久顺序节点中存储的机器码标识,按照机器码标识递增的顺序,生成所述目标id服务器的机器码标识,并将所述目标id服务器的机器码标识存储在相应的zookeeper持久顺序节点中,完成对所述目标id服务器的注册;
s203:所述zookeeper服务器在检测到目标id服务器已注册的情况下,获取所述目标id服务器的本地系统时间;
s204:所述zookeeper服务器获取所有正在提供服务的id服务器的本地系统时间的平均值;
s205:所述zookeeper服务器判断所述目标id服务器的本地系统时间与所述平均值的绝对值是否小于阈值;
若不小于所述阈值,s206:所述zookeeper服务器提示所述目标id服务器启动失败,启动报警机制
若小于所述阈值,s207:所述zookeeper服务器提示所述目标id服务器启动成功;
s208:所述目标id服务器依据自身的机器码标识生成系统id,所述系统id包括第一预设位数的时间戳、第二预设位数的机器码标识和第三预设位数的自增序列。
该方法中zookeeper服务器通过在已注册id服务器在启动时检测已注册id服务器是否发生时钟回拨,避免发生时钟回拨的id服务器生成系统id造成的重复id生成的问题。
另一种解决服务器时钟回拨导致重复id生成的问题的方法为:系统中每个id服务器基于网络时间同步协议实现时钟同步,如每隔3秒(该时间可配置)同步一下所有id服务器的当前系统时间。但是由于网络延迟问题可能会造成时钟回拨,在此基础上,对于每一个id服务器,如本实施例中的目标id服务器获取当前系统时间以及与生成系统id的最新时间,计算当前系统时间与生成系统id的最新时间之间的时间偏差值,并根据该时间偏差值确定id生成策略,并执行所述id生成策略。
具体的,请参阅图4,上述全局且递增的id生成方法包括以下步骤:
s301:目标id服务器获取当前系统时间以及与生成系统id的最新时间;
需要说明的是,目标id服务器会存储生成系统id的最新时间,最新时间精确到毫秒,并存储该系统id对应的自增序列值,存储格式为毫秒-自增序列值。
s302:目标id服务器计算当前系统时间与生成系统id的最新时间之间的时间偏差值;
当目标id服务器生成系统id的最新时间大于当前系统时间时,目标id服务器计算生成系统id的最新时间与当前系统时间之间由于时钟回拨产生的回拨时间偏差值。
当目标id服务器生成系统id的最新时间不大于当前系统时间时,目标id服务器计算当前系统时间与生成系统id的最新时间之间的增量时间偏差值。
s303:目标id服务器根据所述时间偏差值确定id生成策略,并执行所述id生成策略。
id生成策略总体来说包括正常递增、延迟等待和超时异常三类,具体的,请参阅图5所示的全局且递增的id生成方法:
s401:目标id服务器获取当前系统时间以及生成系统id的最新时间;
s402:目标id服务器判断生成系统id的最新时间是否大于当前系统时间;
若生成系统id的最新时间不大于当前系统时间,目标id服务器未发生时钟回拨,执行s403:目标id服务器获取生成系统id的最新时间对应的系统id的自增序列值;
s404:目标id服务器判断自增序列值是否大于预设增量最大值;
若自增序列值大于预设增量最大值,如4096,当前系统时间对应的时间戳已用完,执行s405:目标id服务器的本地时钟从下一毫秒开始计时,得到最新的当前系统时间;
即最新的当前系统时间为原当前系统时间+1毫秒,自增序列值为0。
s406:目标id服务器依据自身的机器码标识和最新的当前系统时间生成系统id,并更新生成系统id的最新时间和相应系统id的自增序列值;
若自增序列值不大于预设增量最大值,即正常递增情况,执行s406;
若生成系统id的最新时间大于当前系统时间,即目标id服务器本地时钟发生回拨,s407:目标id服务器计算生成系统id的最新时间与当前系统时间之间由于时钟回拨产生的回拨时间偏差值;
s408:目标id服务器判断回拨时间偏差值是否小于回拨阈值;
若回拨时间偏差值不小于回拨阈值,即回拨时长大于可以容忍的限度,执行s409:目标id服务器启动报警机制;
若回拨时间偏差值小于回拨阈值,即回拨时长不大于可以容忍的限度,执行s410:目标id服务器的本地时钟继续计时两倍所述回拨阈值时间,得到最新的当前系统时间;
s411:目标id服务器判断生成系统id的最新时间是否大于最新的当前系统时间;
若生成系统id的最新时间大于最新的当前系统时间,执行s409;
若生成系统id的最新时间不大于最新的当前系统时间,执行s403。
该方法中,id服务器通过存储生成的系统id的最新时间以及相应的自增序列值,在生成系统id之间比较生成系统id的最新时间和当前系统时间,确定id服务器的本地时钟是否发生回拨,并确定相应的id生成策略,解决服务器时钟回拨导致重复id生成的问题。
基于上述实施例公开的一种全局且递增的id生成方法,本实施例对应公开了一种全局且递增的id生成系统,请参阅图6,包括zookeeper服务100和多个id服务器200;
所述zookeeper服务器100,用于在检测到目标id服务器未注册的情况下,生成所述目标id服务器对应的zookeeper持久顺序节点,所述目标id服务器为所述id生成系统中的任意一个id服务器200,依据已注册id服务器对应的zookeeper持久顺序节点中存储的机器码标识,按照机器码标识递增的顺序,生成所述目标id服务器的机器码标识,并将所述目标id服务器的机器码标识存储在相应的zookeeper持久顺序节点中,完成对所述目标id服务器的注册;
所述目标id服务器200,用于依据自身的机器码标识生成系统id,所述系统id包括第一预设位数的时间戳、第二预设位数的机器码标识和第三预设位数的自增序列。
可选的,所述zookeeper服务器401,还用于:
在所述目标id服务器依据自身的机器码标识生成系统id之前,且在检测到目标id服务器已注册的情况下,获取所述目标id服务器的本地系统时间;
获取所有正在提供服务的id服务器的本地系统时间的平均值;
判断所述目标id服务器的本地系统时间与所述平均值的绝对值是否小于阈值;
若小于所述阈值,提示所述目标id服务器启动成功;
若不小于所述阈值,提示所述目标id服务器启动失败,启动报警机制。
可选的,所述目标id服务器的机器码标识包括机房码和机器码。
可选的,所述id生成系统中的每个id服务器,还用于基于网络时间同步协议实现时钟同步。
可选的,所述目标id服务器还用于:
获取当前系统时间以及生成系统id的最新时间;
计算所述当前系统时间与生成系统id的最新时间之间的时间偏差值;
根据所述时间偏差值确定id生成策略,并执行所述id生成策略。
可选的,所述目标id服务器具体用于:
判断生成系统id的最新时间是否大于所述当前系统时间;
若大于所述当前系统时间,计算生成系统id的最新时间与所述当前系统时间之间由于时钟回拨产生的回拨时间偏差值;
若不大于所述当前系统时间,计算所述当前系统时间与生成系统id的最新时间之间的增量时间偏差值。
可选的,所述目标id服务器具体用于:
在所述增量时间偏差值不小于0的情况下,获取生成系统id的最新时间对应的系统id的自增序列值;
判断所述自增序列值是否大于预设增量最大值;
若是,所述目标id服务器的本地时钟从下一毫秒开始计时,得到最新的当前系统时间,依据自身的机器码标识和最新的当前系统时间生成系统id,并更新生成系统id的最新时间和相应系统id的自增序列值;
若否,依据自身的机器码标识和所述当前系统时间生成系统id,并更新生成系统id的所述最新时间和相应系统id的自增序列值。
可选的,所述目标id服务器具体用于:
判断所述回拨时间偏差值是否小于回拨阈值;
若不小于所述回拨阈值,启动报警机制;
若小于所述回拨阈值,所述目标id服务器的本地时钟继续计时两倍所述回拨阈值时间,得到最新的当前系统时间;
判断生成系统id的最新时间是否大于所述最新的当前系统时间;
若生成系统id的最新时间大于所述最新的当前系统时间,启动报警机制;
若生成系统id的最新时间不大于所述最新的当前系统时间,返回执行所述计算所述当前系统时间与生成系统id的最新时间之间的增量时间偏差值,这一步骤。
本实施例公开的一种全局且递增的id生成系统,通过zookeeper服务器维护系统内每个id服务器的机器码标识,根据已注册id服务器对应的zookeeper持久顺序节点中存储的机器码标识,按照机器码标识递增的顺序,生成未注册id服务器的机器码标识,保证系统中每个id服务器的机器码标识的唯一性,进而保证id服务器依据自身机器码标识生成的包括第一预设位数的时间戳、第二预设位数的机器码标识和第三预设位数的自增序列的系统id的唯一性。
同时,zookeeper服务器通过在已注册id服务器在启动时检测已注册id服务器是否发生时钟回拨,避免发生时钟回拨的id服务器生成系统id造成的重复id生成的问题。
id服务器通过存储生成的系统id的最新时间以及相应的自增序列值,在生成系统id之间比较生成系统id的最新时间和当前系统时间,确定id服务器的本地时钟是否发生回拨,并确定相应的id生成策略,解决服务器时钟回拨导致重复id生成的问题。
对所公开的实施例的上述说明,使本领域专业技术人员能够实现或使用本发明。对这些实施例的多种修改对本领域的专业技术人员来说将是显而易见的,本文中所定义的一般原理可以在不脱离本发明的精神或范围的情况下,在其它实施例中实现。因此,本发明将不会被限制于本文所示的这些实施例,而是要符合与本文所公开的原理和新颖特点相一致的最宽的范围。