常见生成方式

UUID

  • 标准型式包含 32 个 16 进制数字,以连字号分为五段,形式为 8-4-4-4-12 的 36 个字符
  • 性能非常高,本地生成,没有网络消耗
  • UUID.randomUUID().toString()

为什么无序的 UUID 会导致入库性能变差

  • 分布式 ID 一般会作为主键,MySQL推荐主键尽量越短越好,所以不是很推荐。同时UUID生成为无序的,不能生成递增有序的数字
  • 由于 MYSQL 的索引通过 B+ 树实现的,每一次新的 UUID 数据的插入,为了查询的优化都会对索引底层的 B+ 树进行修改,因为 UUID 无序所以每一次插入都会对主键的 B+ 树进行很大的修改,可能会导致一些中间节点产生分裂,也会创造很多不饱和节点,降低了数据库插入的性能


数据库主键自增

  • 自增 ID 机制的主要原理是:数据库自增 ID 和 MySQL 数据库的replace into 实现
  • replace into 的含义是 插入一条记录,如果表中唯一索引的值遇到冲突,则替换老数据

缺点

  • 系统水平拓展比较困难,需要定义步长和初始值来实现,配置麻烦,利用率低
  • 数据库压力大,每次获取 ID都得读写一次数据库,非常影响性能,不符合分布式 ID 里面的低延迟和高 QPS 要求


基于 Redis 生成全局 ID

  • 与 MySQL 类似,好处是可以获取更高的吞吐量,同时也需要设置步长和增长,key一定要设置有效期


雪花算法

  • 官网
  • Twitter 的分布式自增 ID 算法 snowflake
  • 集群高并发情况下保证分布式唯一全局 ID 生成,生成的 ID 能过按照时间有序生成,结果是一个 64 bit 大小的整数,为一个 Long 性;分布式系统内不会产生 ID 碰撞(由 datacenter 和 workerID 区分)并且效率较高
  • 41 bit 用来记录时间戳,毫秒级;12 bit 用来记录同毫秒内产生的不同 ID
  • 10 bit 工作进程位,用来记录工作机器ID, 一般分为 5 datacenter 和 5 workerID alt

分布式全局 ID 要求

  1. 全局唯一
  2. 趋势递增
  3. 单调递增
  4. 信息安全
  5. 含时间戳

优势与劣势

  1. 毫秒数在高位,自增序列在低位,整个 ID 都是趋势递增的
  2. 不依赖数据库等第三方系统,以服务的方式部署,稳定性、生成 ID 的性能高
  3. 可以根据自身业务特性分配 bit 位,相对灵活
  4. 依赖机器时钟,如果机器时钟回拨会导致重复 ID 生成

拓展

  • 百度开源的分布式唯一 ID 生成器 UidGenerator
  • 美团点评分布式 ID 生成系统 Leaf