分布式ID方案有哪些以及各自的优势

 1.    背景

在分布式系统中,经常需要对大量的数据、消息、http请求等进行唯一标识。例如:在分布式系统之间http请求需要唯一标识,调用链路分析的时候需要使用这个唯一标识。这个时候数据自增主键已经不能满足需求,需要一个能够生成全局唯一ID的系统,这个系统需要满足两个需求:

----全局唯一:不能出现重复ID

----高可用:ID生成系统是基础系统,被许多关键系统调用,一旦宕机,会造成严重影响

2.    经典方案介绍

1).    UUID

UUID是Universally Unique Identifier的缩写,它是在一定的范围内唯一的机器生成的标识符,UUID是16字节128位长的数字,通常以36字节的字符串表示,比如:3F2504E0-4F89-11D3-9A0C-0305E82C3301。

UUID通过一定的算法机器生成,为了保证UUID的唯一性,规范定义了包括网卡MAC地址、时间戳、名字空间、随机或者伪随机数、时序等元素,以及这些元素生成UUID的算法。UUID的复杂特性保证了其唯一性。

优点:本地生成ID,不需要进行远程调用,时延低,性能高。

缺点:

1))    UUID过长,很多场景不适用,比如用UUID做数据库索引字段。

2))    没有排序,无法保证趋势递增

2).    Flicker方案

只要思路采用了MySQL自增长ID的机制,

#数据表
CREATE TABLE Tickets64(
id bigint(20) unsigned NOT NULL auto_increment,
stub char(1) NOT NULL default '',
PRIMARY KEY(id),
UNIQUE KEY stub(stub)
)ENGINE=MyISAM;


#使用下列SQL读写得到ID号
REPLACE INTO Tickets64 (stub) VALUES('a');
SELECT LAST_INSERT_ID();

 replace into 跟 insert 功能类似,不同点在于:replace into 首先尝试插入数据到表中,如果发现表中已经有此行数据(根据主键或者唯-索引判断)则先删除此行数据,然后插入新的数据, 否则直接插入新数据。

优点:充分借助数据库的自增ID机制,可靠性高,生成有序的ID

缺点:

----ID生成性能依赖单台数据库读写性能

----依赖数据库,当数据库异常时整个系统不可用

3).    类snowflake方案

这种方案生成一个64bit的数字,64bit被划分成多个阶段,分别表示时间戳、机器编码、序号。

 

ID为64bit的long数字,由三部分组成:

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

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

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

优点:

----时间戳在高位,自增序列在低位,整个ID是趋势递增的,按照时间有序

----性能高,每秒可生成几百万ID

----可以根据自身业务需求灵活调整bit位划分,满足不同需求

缺点:

----依赖机器时钟,如果机器时钟回拨,会导致重复ID生成。

----在单机上是递增的,但是由于涉及到分布式环境,每台机器上的时钟不可能完全同步,有时候会出现不时全局递增的情况

4).    TDDL序列生成方式

 TDDL是阿里的分裤分表中间件,它里面包含了全局数据库ID的生成方式,只要思路:

----使用数据库同步ID信息

----每次批量取一定数量的可用ID在内存中,使用完后,再请求数据库重新获取下一批可用ID,每次获取的可用ID数量由步长控制,实际业务中可根据使用速度进行匹配。

----每个业务可以给自己的序列起个唯一的名字,隔离各个业务系统的ID。

优点

----相比flicker方案,大大降低数据库写压力,数据库不再是性能瓶颈。

----相比flicker方案,生成ID性能大幅度提高,因为获取一个可用号段后在内存中直接分配,相对于每次读取数据库性能提高了几个量级

----不同业务不同的ID需求可用seqName字段区分,每个seqName的ID相互隔离,互不影响。

缺点:

----强依赖数据库,当数据库异常时整个系统不可用。

学习并转载自:https://blog.csdn.net/hl_java/article/details/78462283

原文地址:https://www.cnblogs.com/baxianhua/p/9888433.html