如何设计分布式ID?


一、为什么要使用分布式ID?

  • 比如MySQL的主键ID一般用自增的方式,但如果用分表的话,多个表中会生成重复的ID

二、设计方案

  • 使用MySQL的全局表:每获取一次都需要更新数据库,性能差
  • 使用redis的自增id
  • UUID
  • 雪花算法

三、考虑因素

  • 有序性:有序的ID能更好地确认数据的位置,也可以提高范围搜索的效率
  • 安全性:避免数据泄露
  • 可用性:全局ID生成系统的可用性要求非常高,一旦出现故障会造成业务不可用的问题
  • 性能:全局ID生成系统需满足整个公司的业务需求,涉及到亿级别的调用,对性能要求较高

四、最佳方案-雪花算法

介绍雪花算法是目前市面上主流的全局ID解决方案,由64位长度组成的全局ID生成算法,通过对64位区间划分来表述不同含义来实现唯一性
ID划分

  • 最高1位:固定位0(0表示位正数,因为生成的id是正整数,如果是1就是负数了)
  • 接下来41位:毫秒级时间戳(2^41/1000606024365=69,也就是大概可以使用69年)
  • 再接下来10位:机器码(包括5位datacenterId和5位workerId,最后可以部署2^10=1024台机器)
  • 最后12位:序列号(同一毫秒时间戳时,通过这个递增的序列号来区分,即对于同一台机器而言,同一个毫秒时间戳瞎,可以生成2^12=4096个不重复id)

如何使用?:可单独将雪花算法部署到一个单独的服务,然后每一个需要使用全局唯一ID的系统,请求雪花算法服务即可
优点

  • 高并发分布式环境下,每秒可生成百万个不重复ID
  • 基于时间戳+同一时间戳下序列号自增,基本保证ID有序递增
  • 不依赖第三方或中间件
  • 算法简单,在内存中进行,效率高

缺点

  • 依赖服务器时间:服务器时钟回拨时可能会生成重复ID
    • 解决:可在算法中记录最后一个生成ID的时间戳来解决,每次生成ID判断当前服务器时钟是否被回拨,避免生成重复ID
  • 低并发下生成的ID会大概率位偶数

文章作者: GaryLee
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 GaryLee !
  目录