在高并发或者分表分库情况下保证数据id的幂等性,经常用到的解决方案有以下几种。
1:微软公司通用唯一识别码(UUID)
2:Twitter公司雪花算法(SnowFlake)
3:基于数据库的id自增
4:对id进行缓存
这里我们以snowflake算法为例
snowflake是Twitter开源的分布式ID生成算法,结果是一个long型的ID。其核心思想是:使用41bit作为毫秒数,10bit作为机器的ID(5个bit是数据中心,5个bit的机器ID),12bit作为毫秒内的流水号,最后还有一个符号位,永远是0。
整个结构是64位,所以我们在Java中可以使用long来进行存储。该算法实现基本就是二进制操作,单机每秒内理论上最多可以生成1024*(2^12),也就是409.6万个ID(1024 X 4096 = 4194304)
snowFlake算法的优点
1:生成ID时不依赖于DB,完全在内存生成,高性能高可用。
2:ID呈趋势递增,后续插入索引树的时候性能较好。
SnowFlake算法的缺点
依赖于系统时钟的一致性。如果某台机器的系统时钟回拨,有可能造成ID冲突,或者ID乱序
算法代码如下
twepoch
workerIdBits
datacenterIdBits
maxWorkerId workerIdBits
maxDatacenterId datacenterIdBits
sequenceBits
workerIdShift sequenceBits
datacenterIdShift sequenceBits workerIdBits
timestampLeftShift sequenceBits workerIdBits datacenterIdBits
sequenceMask sequenceBits
workerId
datacenterId
sequence
lastTimestamp
* 构造函数
workerId datacenterId
workerId maxWorkerId workerId
maxWorkerId
datacenterId maxDatacenterId datacenterId
maxDatacenterId
workerId workerId
datacenterId datacenterId
* 获得下一个ID (该方法是线程安全的)
timestamp
timestamp lastTimestamp
lastTimestamp timestamp
lastTimestamp timestamp
sequence sequence sequenceMask
sequence
timestamp lastTimestamp
sequence
lastTimestamp timestamp
timestamp twepoch timestampLeftShift
datacenterId datacenterIdShift
workerId workerIdShift
sequence
* 阻塞到下一个毫秒,直到获得新的时间戳
lastTimestamp
timestamp
timestamp lastTimestamp
timestamp
timestamp
* 返回以毫秒为单位的当前时间
args
idWorker
i i i
id idWorker
outid
outid
快速使用snowflake算法只需以下几步
引入hutool依赖
cnhutoolgroupId
hutoolcaptchaartifactId
$hutoolversionversion
dependency
ID 生成器
workerId
workerId
log workerId
e
log e
workerId
log workerId
* 获取一个批次号,形如 2019071015301361000101237
* 数据库使用 char(25) 存储
*
tenantId
prefix PURE_DATETIME_MS_PATTERN
prefix tenantId
tenantId
tenantId
* 生成的是不带-的字符串,类似于:b17f24ff026d40949c85a24f4f375d42
*
* 生成的UUID是带-的字符串,类似于:a5c8a5e8-df2b-4706-bea4-08d0939410e3
*
snowflake workerId
snowflake
workerId dataCenterId
snowflake workerId dataCenterId
snowflake
* 生成类似:5b9e306a4df4f8c54a39fb0c
* ObjectId 是 MongoDB 数据库的一种唯一 ID 生成策略,
* 是 UUID version1 的变种,详细介绍可见:服务化框架-分布式 Unique ID 的生成方法一览。
*
测试类
idGenerator
i i i
batchId idGenerator
log batchId
i i i
simpleUUID idGenerator
log simpleUUID
i i i
randomUUID idGenerator
log randomUUID
i i i
objectId idGenerator
log objectId
executorService
i i i
executorService
log idGenerator
executorService
在项目中我们只需要注入 @Autowired private IdGenerator idGenerator;即可
然后设置id order.setId(idGenerator.snowflakeId() + “”);
还没有评论,来说两句吧...