推荐一款开源的雪花算法主键ID生成工具

上一篇文章【推荐一款开源的分布式任务调度系统】提到了利用雪花算法来生成主键ID的事,今天将这个开源的工具分享出来

之前都是按着技术贴照着写个工具类。偶然间发现了一个开源的工具类。该开源程序包含了多种语言版本的雪花算法。而且使用简单,基本属于开箱即用。

一、什么是雪花算法

雪花算法(Snowflake)是一种生成分布式全局唯一ID的算法,生成的ID称为Snowflake IDs或snowflakes。这种算法由Twitter创建,并用于推文的ID。Discord和Instagram等其他公司采用了修改后的版本。维基百科

一个Snowflake ID有64位元,包含如下四部分。

  • 第一部分:符号位,固定0(二进制0代表正数1代表负数)

  • 第二部分:41位是时间戳,表示了自选定的时期以来的毫秒数

  • 第三部分:接下来的10位代表计算机ID,防止冲突

  • 第四部分:其余12位代表每台机器上生成ID的序列号

如下格式:


这个算法最大弊端就不能解决时间回拨问题,对于服务器较少的项目似乎影响不大。

原雪花算法开源已关闭,保留了初级版本的源码包下载地址

https://github.com/twitter-archive/snowflake/releases/tag/snowflake-2010

二、算法介绍

简单介绍完雪花算法后,下面介绍下推荐的改良版的雪花算法工具类。

(以下内容来自官方介绍)

❄ 这是优化的雪花算法(雪花漂移),它生成的ID更短、速度更快。

❄ 支持 k8s 等容器环境自动扩容(自动注册 WorkerId),可在单机或分布式环境生成数字型唯一ID。

❄ 原生支持 C#/Java/Go/Rust/C/SQL/Node.js/PHP(C扩展) 等语言,并提供Python、PB多线程安全调用动态库(FFI)。

❄ 兼容所有雪花算法(号段模式或经典模式,大厂或小厂),将来你可做任意的升级切换。(一般无须升级,但理论上支持)

❄ 这是计算机历史上最全面的雪花ID生成工具。

ID组成说明

  • 本算法生成的ID由3部分组成(沿用雪花算法定义):

  • +————————-+————–+———-+

  • | 1.相对基础时间的时间差 | 2.WorkerId | 3.序列数 |

  • +————————-+————–+———-+

  • 第1部分,时间差,是生成ID时的系统时间减去 BaseTime 的总时间差(毫秒单位)。

  • 第2部分,WorkerId,是区分不同机器或不同应用的唯一ID,最大值由 WorkerIdBitLength(默认6)限定。

  • 第3部分,序列数,是每毫秒下的序列数,由参数中的 SeqBitLength(默认6)限定。

能用多久

能用多久的解释,是指生成的ID数字,何时能增长到超过 long(有符号64位,8字节)最大值。

在默认配置下,ID可用 71000 年不重复。

在支持 1024 个工作节点时,ID可用 4480 年不重复。

在支持 4096 个工作节点时,ID可用 1120 年不重复

三、如何集成

以java的方式集成,看起来十分简单。

引用 maven 包

<dependency>
    <groupId>com.github.yitter</groupId>
    <artifactId>yitter-idgenerator</artifactId>
    <version>1.0.6</version>
</dependency>

调用示例(Java)

第1步,全局 初始化(应用程序启动时执行一次):

// 创建 IdGeneratorOptions 对象,请在构造函数中输入 WorkerId:
IdGeneratorOptions options = new IdGeneratorOptions(1);
// options.WorkerIdBitLength = 10; // WorkerIdBitLength 默认值6,支持的 WorkerId 最大值为2^6-1,若 WorkerId 超过64,可设置更大的 WorkerIdBitLength
// ...... 其它参数设置参考 IdGeneratorOptions 定义,一般来说,只要再设置 WorkerIdBitLength (决定 WorkerId 的最大值)。
// 保存参数(必须的操作,否则以上设置都不能生效):
YitIdHelper.setIdGenerator(options);
// 以上初始化过程只需全局一次,且必须在第2步之前设置。

第2步,生成ID:

// 初始化以后,即可在任何需要生成ID的地方,调用以下方法:
long newId = YitIdHelper.nextId();

如果基于DI框架集成,可以参考 YitIdHelper 去管理 IdGenerator 对象,须使用 单例 模式。

开源地址

感兴趣的朋友可以访问开源地址进一步研究,

https://github.com/yitter/idgenerator

微信公众号:王同学爱学习
本文同步发布到公众号【王同学爱学习】欢迎关注本公众号