在高并发或者分表分库情况下保证数据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() + “”);



		
		
		

还没有评论,来说两句吧...