Fetch the repository succeeded.
导致在实际应用的生成数值为如下
@juapk 没有发现大量偶数呀
@juapk 实际场景也是大批量的休眠生成?
@juapk 该算法的序列包括四部分:
1bit校验位+41bit的毫秒级时间戳位+10bit机器ID位+12bit序列位
在相同的毫秒时间戳时刻,最多可以产生4096个有序序列号。所以非休眠的情况,产生的序列号则会有多个值,但你所描述的场景中是做了一定的休眠的,所以说41位的毫秒级时间戳位已经不同,基本可以认为你所产生的所有序列都是不同毫秒级时间戳的,因此其相对的序列位都只是第一个序列值(即0),所以进行转换后基本都是偶数了。
这是没办法解决,或者说该序列不适合用来解决该场景的问题
改成下面的试试。
// 如果是同一时间生成的,则进行毫秒内序列
if (lastTimestamp == timestamp) {
long old = sequence;
sequence = (sequence + 1) & sequenceMask;
// 毫秒内序列溢出
if (sequence == old) {
// 阻塞到下一个毫秒,获得新的时间戳
timestamp = tilNextMillis(lastTimestamp);
}
} else {// 时间戳改变,毫秒内序列重置
sequence = ThreadLocalRandom.current().nextLong(0,2);
}
兄弟我看差了,毫秒内序列溢出应该还是if (sequence == 0),你这个nextId方法是同步的估计很难达到一毫秒内超过4095个序列号,所以这个if基本不会走。
@juapk 对于吞吐量不是很大的应用是会遇到偶数分布占比扩大的情况。这个是雪花算法的特性决定的,所以常规的id hash分表的策略在此并不合适,原因很简单,数据分布不均匀。因此需要结合你们的业务特性做流水号定制化,比如融入一些基因特质。
Sign in to comment