雪花算法 Snowflake 生成分布式自增 ID 详解

文章目录

  • 1、雪花算法概述
  • 2、雪花算法结构
  • 3、雪花算法生成的 ID 性质
  • 4、雪花算法的优点
  • 5、雪花算法的缺点

1、雪花算法概述

Snowflake 是 twitter 开发的全局唯一 ID 生成服务。

Twitter 的分布式雪花算法 Snowflake,经测试 Snowflake 每秒能够产生 26 万个自增可排序的ID

  1. twitter 的 Snowflake 生 成ID能够按照时间有序生成
  2. Snowflake 算法生成 id 的结果是一 个 64bit 大小的整数, 为一个 Long 型(转换成字符串后长度最多 19)。
  3. 分布式系统内不会产生 ID 碰撞(由 datacenter 和 workerld 作区分)并且效率较高。

分布式系统中,有一些需要使用全局唯一 ID 的场景, 生成ID的基本要求如下:

  1. 在分布式的环境下必须全局且唯一 。

  2. 一般都需要单调递增,因为一般唯一ID都 会存到数据库,而 innodb 的特性就是将内容存储在主键索引树上的叶子节点而且是从左往右,递增的,所以考虑到数据库性能,一般生成的 id 也最好是单调递增。为了防止 ID 冲突可以使用 36 位的 UUID,但是 UUID 有一些缺点, 首先他相对比较长,另外 UUID 一般是无序的。

  3. 可能还会需要无规则,因为如果使用唯一 ID 作为订单号这种,为了不让别人知道一天的订单量是多少,就需要这个规则。

2、雪花算法结构

雪花算法 Snowflake 生成分布式自增 ID 详解_第1张图片
上图的号段解析:

  1. 1bit 不使用,因为二进制中最高位是符号位,1 表示负数,0 表示正数。生成的 id 一般都是用整数,所以最高位固定为 0。

  2. 41bit 时间戳,用来记录时间戳,亳秒级。

  • 41位可以表示2^{41}-1个数字,
  • 如果只用来表示正整数(计算机中正数包含0),可以表示的数值范围是: 0至2^{41}-1, 减1是因为可表示的数值范围是从0开始算的,而不是1。
  • 也就是说41位可以表示2{41}-1个亳秒的值,转化成单位年则是(2{41-1)/ (1000 *60 * 60 * 24“365) = 69年
  1. 10bit 工作机器 id, 用来记录工作机器的 id。
  • 可以部署在2^{10}= 1024个节点,包括5位 datacenterld(数据中心id) 和5位 workerld(机器码id)。即使用 机房号 + 机器号的方式划分每一台机器。
  • 5位(bit) 可以表示的最大正整数是2^(5}-1=31, 即可以用0、1、2、3、…1这32个数字, 来表示不同的 datecenterld 或 workerld。
  1. 12bit 序列号,序列号,用来记录同毫秒内产生的不同id。
  • 12位(bit) 可以表示的最大正整数是2^{12}-1 = 4095, 即可以用 0、1、2、3、…4094 这 4095 个数字,来表示同一机器同一时间截(亳秒)内产生的 4095 个ID序号。

3、雪花算法生成的 ID 性质

Snowflake 可以保证:
所有生成的 id 按时间趋势递增
整个分布式系统内不会产生重复 id (因为有datacenterld和Iworkerld来做区分)

即保证了:

  1. 全局唯一性
  2. 趋势递增性
  3. 信息安全
  4. 包含了时间戳
  5. 主键只有 19 个字符(小于 UUID 的32个字符)

4、雪花算法的优点

毫秒数在高位,自增序列在低位,整个 ID 都是趋势递增的。

不依赖数据库第三方系统(区别于 Redis 集群生成的分布式 ID),以服务的方式部署,稳定性更高,生成 ID 的性能也常高。

可以根据自身业务特性分配 bit 位,非常灵活。

5、雪花算法的缺点

依赖于机器时钟,如果机器时钟回拨了,会导致重复 ID 生成。

在单机上是递增的,但是在分布式环境下,每台机器的时钟不一定完全同步,所以不能满足严格递增,只能满足趋势递增。

你可能感兴趣的:(分布式架构)