雪花算法生成分布式id
介绍
雪花算法的原始版本是scala版,用于生成分布式ID(纯数字,时间顺序),订单编号等。
SnowFlake的优点是,整体上按照时间自增排序,并且整个分布式系统内不会产生ID碰撞(由datacenter数据中心ID和workerId机器ID作区分),并且效率较高,经测试,SnowFlake每秒能够产生26万ID左右。
其他id:
- 自增ID:对于数据敏感场景不宜使用,且不适合于分布式场景。
- GUID:采用无意义字符串,数据量增大时造成访问过慢,且不宜排序。
图解
- 1位标识,由于long基本类型在Java中是带符号的,最高位是符号位,正数是0,负数是1,所以id一般是正数,最高位是0
- 41位时间截(毫秒级),注意,41位时间截不是存储当前时间的时间截,而是存储时间截的差值(当前时间截 - 开始时间截),
- 开始时间截一般是我们的id生成器开始使用的时间,由我们程序来指定的。
- 41位的时间截,可以使用69年,年T =
(1L << 41) / (1000L * 60 * 60 * 24 * 365) = 69
- 10位的数据机器位,可以部署在1024个节点,包括5位datacenterId和5位workerId
- 12位序列,毫秒内的计数,12位的计数顺序号支持每个节点每毫秒(同一机器,同一时间截)产生4096个ID序号
加起来刚好64位,为一个Long型。(转换成字符串后长度最多19)
优点:
- 毫秒数在高位,自增序列在低位,整个ID都是趋势递增的。
- 不依赖数据库等第三方系统,以服务的方式部署,稳定性更高,生成ID的性能也是非常高的。
- 可以根据自身业务特性分配bit位,非常灵活。
缺点:
- 强依赖机器时钟,如果机器上时钟回拨,会导致发号重复或者服务会处于不可用状态。