OOOOlh

Results 7 comments of OOOOlh

@ZLBer yes, it can produce increasing uid correctly

## 1、位数分配 下面各个部分的位数支持用户根据需要自定义。 - sign(1 bit) - delta seconds(28bits) 精确到秒,大约可以使用8.7年 - worker id(22 bits) 机器id,最多可支持约420w次机器启动。内置实现为在启动时由数据库分配,默认分配策略为用后即弃 - sequence(12 bits) 每秒下的并发序列,13 bits可支持每秒8192个并发。 ## 2、worker id生成 ​ 在程序启动时,将“主机IP”和“当前时间戳 (单位:秒) - (0-10000之内的随机数)”两个字段作为一条记录写入Mysql,并获得一个唯一自增id作为work id,如下。 ![image](https://user-images.githubusercontent.com/83326634/178212103-c847daaa-4460-46fb-ab0f-158fc0a493ba.png)...

1、传统雪花算法是完全依赖时间,所以发生时钟回拨后容易出问题。所以为了减少对时间的依赖,就采取序列依次+1,满后delta seconds +1的方法。只在程序启动时读取当前时间(这个时间一般是比上次RingBuffer中的uid的时间戳晚的),这也可以保证趋势递增。这种方法的一个主要不足是业务请求的uid反解析后的时间不是业务真实发生的时间,我不确定这个影响算不算大。 2、使用RingBuffer存储提前生成的uid。RingBuffer的容量是比sequence大几倍的,而且当RingBuffer中可用uid数小于阈值会异步填充,所以在同一秒内并发请求RingBuffer中的uid应该是承受的住的。百度UidGenerator官方测试是单机可提供600万/s的稳定吞吐量。 @ZLBer

百度的这个雪花算法顺序是sign+delta seconds+work id +sequence,delta seconds在高位,所以必须读当前时间。@ZLBer

1、程序开始时,从mysql读workid,再结合当前时间生成uid,并填满整个RingBuffer; 2、然后其它程序来读,读后的uid标志位设为false,表示不可用; 3、当RingBuffer中可用uid少于阈值时(比如buffer容量的三分之一),进行异步填充。循环2、3步。