最近工作中需要手动生成主键,由于是分布式应用,多个应用对多个数据源进行操作,结构图如下:
一个逻辑表可能sharding到多个数据库中,但是要保证在多个数据库中每一个记录的主键不能重复,利用数据库自身的自增策略已经不能满足需求。
借鉴IP网络的划分,可以将一段连续的序列切分为多个子序列,以1-20000000为例,切分长度为100000,可以切分为200个子序列,分别为:
001
000001-100000
002
100001-200000
003
200001-300000
n
(n-1)*100000+1-n*1000000
200
19900001-20000000
把001、002、...、200看成网络号,对应的取值范围成为主机号。然后可以将这些网络号分配给不同的应用程序A、B:
1、A启动,检查配置文件中分配给自己的网络号(假如为001、002、003)和切分长度
2、连接数据库组,查询当前数据库主键在001段区间的最大值,如果该值到达001段的结尾,继续查询在002段区间的最大值,直到找到区间最大值不在该区间末尾的值,设该值为currentMaxValue
3、创建一个AtomicInteger,初始值为currentMaxValue,为上层提供主键生成服务
4、当AtomicInteger增长到当前区间的末尾时,转换到下一个分配的区段
如果为每个应用分配不重合的区间,每个应用都能生成区间连续的主键,各个应用之间也不会出现生成主键重复的现象。很好的解决了分布式情况下的主键生成问题,不需要应用之间协调,只需要预先规划分配一下区段即可。
大小: 24 KB
1
顶
3
踩
分享到:
2012-11-30 01:00
浏览 3978
评论
5 楼
scriptguy
2012-11-30
魔力猫咪 写道
scriptguy 写道
魔力猫咪 写道
UUID不是更好吗。而且你这个架构为什么这么混乱。整个数据库层就不能整合一下吗。
应用集群中的每一个应用通过SQL路由分发到多个数据源进行数据操作,SQL路由对DAO层是透明的。架构不是很混乱吧
即使架构不乱。日后数据库记录多了呢?主键变化就是个天大的麻烦
对,这是个问题,mysql中bigint最大值max=9223372036854775807,切分密集的话,可用主键接近于max个,超过就不行了,如果可以预见业务量会超过max,这种方法不可行,还得寻找其他办法。
4 楼
魔力猫咪
2012-11-30
scriptguy 写道
魔力猫咪 写道
UUID不是更好吗。而且你这个架构为什么这么混乱。整个数据库层就不能整合一下吗。
应用集群中的每一个应用通过SQL路由分发到多个数据源进行数据操作,SQL路由对DAO层是透明的。架构不是很混乱吧
即使架构不乱。日后数据库记录多了呢?主键变化就是个天大的麻烦
3 楼
scriptguy
2012-11-30
魔力猫咪 写道
UUID不是更好吗。而且你这个架构为什么这么混乱。整个数据库层就不能整合一下吗。
应用集群中的每一个应用通过SQL路由分发到多个数据源进行数据操作,SQL路由对DAO层是透明的。架构不是很混乱吧
2 楼
kidneyball
2012-11-30
UUID +1
1 楼
魔力猫咪
2012-11-30
UUID不是更好吗。而且你这个架构为什么这么混乱。整个数据库层就不能整合一下吗。