分布式全局唯一ID生成方案

admin / 开发 / ... / Reads: 2047

分布式架构下,唯一序列号生成是我们在设计一个系统,尤其是数据库使用分库分表的时候常常会遇见的问题。当数据分成若干个sharding表后,如何能够快速拿到一个唯一序列号,是我们需要解决的问题。

一、唯一ID特性需求

  1. 全局唯一;

  2. 支持高并发;

  3. 高可靠,容错单点故障;

  4. 高性能;

二、业内方案

生成ID的方法有很多,来适应不同的场景、需求以及性能要求。

业内常见解决方案有:

1、利用数据库id递增

优点:简单易用,实现过程简单。

缺点:单库单表,数据库压力大。

2、UUID唯一识别码(Universally Unique Identifier)

生成的是length=32的16进制格式的字符串。标准的UUID格式为:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx (8-4-4-4-12),以连字号分为五段形式的36个字符。

优点:不依赖于数据库,实现简单。Java标准类库中已经提供了UUID的API。

缺点:UUID的缺陷在于生成的结果串会比较长,占用过多DB存储空间,不方便业务使用,排序也比较费时。

abc

3、twitter开源的全局唯一ID生成算法Snowflake

(1) 41位的时间序列(精确到毫秒,41位的长度可以使用69年)。

(2)10位的机器标识(10位的长度最多支持部署1024个节点)。

(3)12位的计数顺序号(12位的计数顺序号支持每个节点每毫秒产生4096个ID序号)

(4)最高位是符号位,始终为0(正数)。

优点:高性能,低延迟;独立的应用;按时间有序。

缺点:需要独立的开发和部署。

4、利用Redis生成ID

当使用数据库来生成ID性能不够要求的时候,我们可以尝试使用Redis来生成ID。这主要依赖于Redis是单线程的,所以也可以用生成全局唯一的ID。可以用Redis的原子操作INCR和INCRBY来实现。

可以使用Redis集群来获取更高的吞吐量。假如一个集群中有5台Redis。可以初始化每台Redis的值分别是1,2,3,4,5,然后步长都是5。各个Redis生成的ID为:

A:1,6,11,16,21

B:2,7,12,17,22

C:3,8,13,18,23

D:4,9,14,19,24

E:5,10,15,20,25

比较适合使用Redis来生成每天从0开始的流水号。比如订单号=日期+当日自增长号。可以每天在Redis中生成一个Key,使用INCR进行累加。

优点:

不依赖于数据库,灵活方便,且性能优于数据库。

数字ID天然排序,对分页或者需要排序的结果很有帮助。

使用Redis集群也可以防止单点故障的问题。

缺点:

如果系统中没有Redis,还需要引入新的组件,增加系统复杂度。

需要编码和配置的工作量比较大,多环境运维很麻烦。

5、百度开源的UidGenerator

UidGenerator是Java实现的,基于Snowflake算法的唯一ID生成器。UidGenerator以组件形式工作在应用项目中, 支持自定义workerId位数和初始化策略, 从而适用于docker等虚拟化环境下实例自动重启、漂移等场景。

在实现上,UidGenerator通过借用未来时间来解决sequence天然存在的并发限制; 采用RingBuffer来缓存已生成的UID, 并行化UID的生产和消费, 同时对CacheLine补齐,避免了由RingBuffer带来的硬件级「伪共享」问题。最终单机QPS可达600万。

依赖版本:Java8及以上版本, MySQL(内置WorkerID分配器, 启动阶段通过DB进行分配; 如自定义实现, 则DB非必选依赖)

伪共享False Sharing可以理解为:缓存系统中是以缓存行(cache line)为单位存储的,当多线程修改互相独立的变量时,如果这些变量共享同一个缓存行,就会无意中影响彼此的性能,这就是伪共享。

关于作者

王硕,十年软件开发经验,业余产品经理,精通Java/Python/Go等,喜欢研究技术,著有《PyQt 5 快速开发与实战》《Python 3.* 全栈开发》,多个业余开源项目托管在GitHub上,欢迎微博交流:

Comments

Make a comment

Author: admin

Publish at: ...

关于作者

王硕,网名信平,十多年软件开发经验,业余架构师,熟悉 Java/Python/Go 等,喜欢读书,音乐和宅在家里。
专注于研究互联网产品和技术,提供中文精品教程。 本网站与其它任何公司及/或商标无任何形式关联或合作。
Email: xujieiata@163.com

www.ultrapower.com ,王硕的博客,专注于研究互联网产品和技术,提供中文精品教程。 本网站与其它任何公司及/或商标无任何形式关联或合作。