1. 全局自增ID啥用?

  1. MQ有序消费
  2. MVCC实现
  3. 分表分库场景
  4. more...

2. 生产全局唯一ID方法

2.1 数据库自增ID

当服务使用的数据库只有单库单表时,可以利用数据库的auto_increment来生成全局唯一递增ID.

优势:

  1. 简单,无需程序任何附加操作
  2. 保持定长的增量
  3. 在单表中能保持唯一性

劣势:

  1. 高并发下性能不佳,主键产生的性能上限是数据库服务器单机的上限。
  2. 水平扩展困难,在分布式数据库环境下,无法保证唯一性。

2.2 UUID

一般的语言中会自带UUID的实现,比如Java中UUID方式UUID.randomUUID().toString(),可以通过服务程序本地产生,ID的生成不依赖数据库的实现。

优势:

  1. 本地生成ID,不需要进行远程调用。
  2. 全局唯一不重复。
  3. 水平扩展能力非常好。

劣势:

  1. ID有128 bits,占用的空间较大,需要存成字符串类型,索引效率极低。
  2. 生成的ID中没有带Timestamp,无法保证趋势递增

2.5 Zookeeper

zookeeper主要通过其znode数据版本来生成序列号,可以生成32位和64位的数据版本号,客户端可以使用这个版本号来作为唯一的序列号。
很少会使用zookeeper来生成唯一ID。主要是由于需要依赖zookeeper,并且是多步调用API,如果在竞争较大的情况下,需要考虑使用分布式锁。因此,性能在高并发的分布式环境下,也不甚理想。

因此有了后面的snowflake

2.5 twitter Snowflake

Snowflake是twitter开源的分布式ID生成算法,其核心思想是:产生一个long型的ID,使用其中41bit作为毫秒数,10bit作为机器编号,12bit作为毫秒内序列号。这个算法单机每秒内理论上最多可以生成1000*(2^12)个,也就是大约400W的ID,完全能满足业务的需求。

优点:可用性强,速度快
缺点:需要引入zookeeper 和独立的snowflake专用服务器

PS: 之所以性能好是因为使用了micro-batch。其实现上生成分布式唯一ID也依赖了ZK的功能。

参考资料:

  1. 分布式系统唯一ID生成方案汇总
  2. 全局唯一ID设计
  3. 全局唯一ID生成方案对比