常见分布式主键生成策略对比

Dec 19, 2019


参考这里这里

分布式主键的两大需求:

  1. 全局唯一
  2. 趋势有序

数据库自增

优点:

  • 简单
  • 能够保证唯一性
  • 能够保证递增性
  • 主键的步长是固定且可自定义的

缺点:

  • 可用性难以保证:数据库常见架构是 一主多从 + 读写分离,生成自增主键是写请求,有单点故障的风险
  • 扩展性差,性能有上限:因为写入是单点,数据库主库的写性能决定主键的生成性能上限,并且难以扩展

单点批量主键生成服务

优点:

  • 保证了主键生成的绝对递增有序
  • 大大降低了数据库的压力,主键生成可以做到每秒生成几万几十万个

缺点:

  • 服务仍然是单点
  • 如果服务挂了,服务重启之后,继续生成的主键可能会不连续,中间出现空洞(服务内存保存着0,1,2,3,4,数据库中最大主键是4,分配到3时,服务重启了,下次会从5开始分配,3和4就成了空洞,不过这个问题不大)
  • 虽然每秒可以生成几万几十万个主键,但还是有性能上限,无法进行水平扩展

UUID / GUID

优点:

  • 本地生成,不需要进行远程调用,时延低
  • 扩展性好,基本可以认为没有性能上限

缺点:

  • 无法保证趋势递增
  • UUID 过长,往往用字符串表示,作为主键建立索引查询效率低;常见优化方案为“转化为两个uint64整数存储”或者“折半存储”,但折半后不能保证唯一性

取当前毫秒数

优点:

  • 本地生成,不需要进行远程调用,时延低
  • 生成的主键趋势递增
  • 生成的主键是整数,建立索引后查询效率高

缺点:

  • 如果并发量超过1000,会生成重复的主键;改用微秒可以降低冲突概率,但每秒最多只能生成100万个主键,再多的话就一定会冲突了,所以使用微秒并不从根本上解决问题。

使用 Redis 自增

优点:

  • 不依赖数据库,灵活方便,且性能优于数据库
  • 天然排序,对分页或者需要排序的结果很有帮助

缺点:

  • 如果系统中没有Redis,还需要引入新的组件,增加系统复杂度
  • 需要编码和配置的工作量比较大

Twitter 开源的 Snowflake 算法

详情见这里