1.SnowFlake 雪花算法简介
SnowFlake 中文意思为雪花,故称为雪花算法。最早是 Twitter 公司在其内部用于分布式环境下生成唯一 ID。
雪花算法将 64 位二进制位划分为五个部分,分别如下:
- 符号位:始终为 0,占用 1 位。
- 时间戳:精确到毫秒级,占用 41 位。
- 机器 ID:机器 ID 可以划分为两部分,占用 10 位。其中 5 位是数据中心 ID,另外 5 位是机器 ID。
- 序列号:序列号可以精确控制单位时间内最大生成的 ID 数量,占用 12 位。
- 总共 64 位,除去符号位后剩下 63 位,刚好是一个 Java long 类型的取值范围。
2.雪花算法各个部分分析
- 符号位
因为二进制里第一个bit如果为1,则表示为负数。但是雪花算法生成的long类的数字都是整数,所以第一 个bit统一都是0。
- 时间戳
41bit可以表示的数字多达2^41 - 1,也就是可以标识2 ^ 41 - 1个毫秒值,换算成年就是69年的时间。
年 = (1L << 41) / (1000L * 60 * 60 * 24 *365) = 69
- 工作机器ID
工作机器ID有10bit位,就表示这个服务最多部署在2^10台机器上,也就是1024台机器。但是10 bit里5个bit 代表机房id, 5个bit代表机器id。意思就是最多代表2^5个机房(32 个机房),每个机房里可以代表2^5个机器(32 台 机器),也可以根据自己公司的实际情况确定。
- 序列号
12 bit可以代表的最大正整数是2^12- 1 = 4096,也就是说可以用这个12 bit代表的数字来区分同一个毫秒内的
4096个不同的id。
3.雪花算法源码
4.时钟回拨问题
4.1什么是时钟回拨
时钟回拨(Clock Drift Backwards)是指系统时间向后调整的现象。在计算机系统中,系统时间通常由硬件时钟或软件时钟来维护,而这些时钟有时会因各种原因出现不同程度的偏差,以致于系统时间发生了回拨的情况。
时钟回拨对应用程序和系统运行都有很大的影响,尤其是在需要保证数据一致性和唯一性的场景中。例如,在分布式系统中,如果某个节点的时间回拨了,就可能导致该节点产生了重复的ID或者序列号等数据,从而破坏了系统的正确性和可靠性。
4.2时钟回拨解决方案
雪花算法中使用的时间戳一般都是基于当前系统时间生成的,因此如果系统时间发生了回拨,则可能会导致生成的ID出现重复。为了解决这个问题,可以采用以下几种方法:
- 时钟同步:尽量保持系统时间的稳定和精确,避免因系统时间不准确而导致时间回拨。
- 时钟后移:当检测到系统时间发生回拨时,可以将时钟向后调整一段时间,以保证新生成的ID不会与之前已经生成的ID重复。
- 等待处理:当检测到系统时间发生回拨时,可以暂停ID的生成,并等待系统时间恢复正常之后再重新开始生成ID。
需要注意的是,在实际应用中,时钟回拨问题可能并不常见,一般只有在出现硬件故障或者系统异常情况时才会发生。因此,在设计时可以根据具体需求和实际情况来选择相应的解决方案。同时,也可以考虑结合其他技术手段,如NTP(网络时间协议)等,来进一步提高系统的时间稳定性和可靠性。
4.3示例代码