Print

雪花算法生成id重复

问:雪花算法之【线上订单号重复了?一招搞定它!】
  1. 答:公司老的系统原先采用的时间戳生成订单号,导致了如下情形
    打断一下:大家知道怎么查系统某项重复的数据吧
    不得了,这样重复岂不是一单成功三方回调导致另一单也成功了。
    多个服务怎么保证生成的订单号唯一呢?
    先上code
    以上是采用snowflake算法生成分布式唯一ID
    41-bit的时间可以表示 (1L<<41)/(1000L360024*365)=69 年的时间,10-bit机器可以分别表示1024台机器。如果我们对IDC划分有需求,还可以将10-bit分5-bit给IDC,分5-bit给工作机器。
    这样就可以表示32个IDC,每个IDC下可以有32台机器,可以根据自身需求定义。12个自增序列号可以表示 2^12 个ID,理论上snowflake方案的QPS约为 409.6w/s ,这种分配方式可以保证在任何一个IDC的任何一台机器在任意毫秒内生成的ID都是不同的。
    这种方式的优缺点是:
    优点:
    缺点:
    一般来说,采用这种方案就解决了。
    还有诸如,mysql的 auto_increment策略,redis的INCR,zookeeper的单一节点修改版本号递增,以及zookeeper的持久顺序节点。
问:ID号生成 雪花算法
  1. 答:1、twitter的SnowFlake生成ID能够按照时间有序生成
    2、SnowFlake算法生成id的结果是一个64bit大小的整数
    3、分布式系统内不会产生重复id(用有datacenterId和machineId来做区分)
    datacenterId(分布式)(服务ID 1,2,3.....) 每个服务中写死
    machineId(用于集群) 机器ID 读取机器的环境变量MACHINEID 部署时每台服务器ID不一样
问:雪花算法(SnowFlake)
  1. 答:解决方法:
    首先,SnowFlake的末尾12位是序列号,用来记录同一毫秒内产生的不同id,同一毫秒总共可以产生4096个id,每一毫秒的序列号都是从0这个基础序列号开始递增。假设我们的业务系统在单机上的QPS为3w/s,那么其实平均每毫秒只需要产生30个id即可,远没有达到设计的4096,也就是说通常情况下序列号的使用都是处在一个低水位,当发生时钟回拨的时候,这些尚未被使用的序号就可以派上用场了。
    因此,可以对给定的基础序列号稍加修改,后面每发生一次时钟回拨就将基础序列号加上指定的步长,例如开始时是从0递增,发生一次时钟回拨后从1024开始递增,再发生一次时钟回拨则从2048递增,这样还能够满足3次的时钟回拨到同一时间点。
    改变原来的末尾sequence生成方法:
    snowflake算法给workerId预留了10位,即workId的取值范围为[0, 1023],事实上实际生产环境不大可能需要部署1024个分布式ID服务,所以:将workerId取值范围缩小为[0, 511],[512, 1023]这个范围的workerId当做备用workerId。workId为0的备用workerId是512,workId为1的备用workerId是513,以此类推……

本文来源: https://www.lw50.cn/article/fda138f4b8ecc7d160a530af.html