Snowflake算法是Twitter提出,为了快速生成全局唯一且总体有序的ID,且ID生成过程不依赖任何中间件,无网络通信[其性能每秒生成300w+]。

在分布式系统中,我们需要各种各样的ID,既然是ID那么必然是要保证全局唯一,除此之外,不同当业务还需要不同的特性,比如像并发巨大的业务要求ID生成效率高,吞吐大;比如某些银行类业务,需要按每日日期制定交易流水号;又比如我们希望用户的ID是随机的,无序的,纯数字的,且位数长度是小于10位的。不同的业务场景需要的ID特性各不一样,于是,衍生了各种ID生成器。

以前我们可以用UUID作为唯一标识[例如123e4567-e89b-12d3-a456-426655440000],但是UUID是无序的,又是英文、数字、横杆的结合。当我们要生成有序的id并且按时间排序时,UUID必然不是最好的选择。

当我们需要有序的id时,可以用数据库的自增长id,但是在当今高并发系统时代下,自增长id速度太慢,满足不了需求。然而,对于有‘有序的id按时间排序’这一需求时,Twitter提出了Snowflake算法,并且用于Twitter中。Snowflake就是一个不需要依赖任何中间件[如数据库,分布式缓存服务等]的ID生成器。

Twitter-Snowflake算法产生的背景相当简单,为了满足Twitter每秒上万条消息的请求,每条消息都必须分配一条唯一的id,这些id还需要一些大致的顺序[方便客户端排序],并且在分布式系统中不同机器产生的id必须不同。

Snowflake生产的ID是一个64位的数字,二进制结构表示如下[每部分用-分开]: 0 - 00000000 00000000 00000000 00000000 00000000 0 - 00000 - 00000 - 00000000 0000

第一位未使用,接下来的41位为毫秒级时间[41位的长度可以使用69年,从1970-01-01 08:00:00],然后是5位datacenter_Id[最大支持2^5=32个,二进制表示从00000-11111,也即是十进制0-31],和5位worker_Id[最大支持2^5=32个,原理同datacenter_Id],所以datacenter_Id*worker_Id最多支持部署1024个节点,最后12位是毫秒内的计数[12位的计数顺序号支持每个节点每毫秒产生2^12=4096个ID序号].

所有位数加起来共64位,恰好是一个Long型[转换为字符串长度为18].

算法开源:https://github.com/twitter/snowflake