SnowFlake 雪花算法(Java实现)

SnowFlake 雪花算法

SnowFlake算法生成的ID大致上是按照时间递增的,用在分布式系统中时,需要注意数据中心标识和机器标识必须唯一,这样就能保证每个节点生成的ID都是唯一的。它可以满足Twitter每秒上万条消息ID分配的请求,这些消息ID是唯一的且有大致的递增顺序,且是一个64位整形,即8字节,可以展示为一个Long类型的整数。结构如下(每一部分用“-”符号分隔):

SnowFlake 雪花算法(Java实现)

  • 1位标识部分,在java中由于long的最高位是符号位,正数是0,负数是1,一般生成的ID为正数,所以为0;
  • 41位时间戳部分,这个是毫秒级的时间,一般实现上不会存储当前的时间戳,而是时间戳的差值(当前时间-固定的开始时间),这样可以使产生的ID从更小值开始;41位的时间戳可以使用69年,(1L << 41) / (1000L * 60 * 60 * 24 * 365) = 69年;
  • 10位节点部分,Twitter实现中使用前5位作为数据中心标识(Data Center ID),后5位作为机器标识(Worker ID),可以部署1024个节点;
  • 12位序列号部分,支持同一毫秒内同一个节点可以生成4096个ID;

Snowflake算法核心

把时间戳,工作机器id,序列号组合在一起。

SnowFlake 的优点如下:

  • 比UUID 短,一般为9-17位。
  • 生成的ID是数字,可以做到单调递增。由于无法统一分布式环境中每台服务器的时钟,它只能做到单台机器单调递增,无法做到全局递增。
  • 性能非常出色,吞吐量达到几十万TPS。

应用场景

参考上面的SnowFlake的优点,对应的应用场景如下。

1、数据库表主键:很多DBA在大型生产应用禁用auto_increment的ID,这时可以选SnowFlake替代。

2、TraceId:分布式系统追踪,希望用一个ID贯穿所有子系统来追踪分布式交互过程。如果系统产生一个Exception,我们需要对Exception编号等。

3、短时间内访问特别大,需要生成大量的唯一ID。

SnowFlake算法,Java版源代码

Github 源码地址:

https://github.com/rickiechina/CloudNative/blob/master/common/src/main/java/com/cloudnative/common/SnowflakeIdWorker.java

在具体的业务场景中,可以将上述代码进一步封装。

如想基于不同的table name,或者业务创建,实例化不同SnowflakeIdWorker 对象,然后存放在HashMap,在调用时,取出对应SnowflakeIdWorker对象,调用nextId() 方法。

Twitter 官方code:

https://github.com/twitter-archive/snowflake

SnowFlake 雪花算法(Java实现)

相关推荐