作者:微信小助手
发布时间:2023-03-17T09:42:41
在复杂的分布式系统中,往往需要对大量的数据进行唯一标识,比如在对一个订单表进行了分库分表操作,这时候数据库的自增ID显然不能作为某个订单的唯一标识。除此之外还有其他分布式场景对分布式ID的一些要求: 就不同的场景及要求,市面诞生了很多分布式ID解决方案。本文针对多个分布式ID解决方案进行介绍,包括其优缺点、使用场景及代码示例。 基于 Spring Boot + MyBatis Plus + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能 UUID( JDK提供了UUID生成工具,代码如下: 输出如下 b0378f6a-eeb7-4779-bffe-2a9f3bc76380 UUID完全可以满足分布式唯一标识,但是在实际应用过程中一般不采用,有如下几个原因: 基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能 利用Mysql的特性ID自增,可以达到数据唯一标识,但是分库分表后只能保证一个表中的ID的唯一,而不能保证整体的ID唯一。为了避免这种情况,我们有以下两种方式解决该问题。 通过单独创建主键表维护唯一标识,作为ID的输出源可以保证整体ID的唯一。举个例子: 创建一个主键表 业务通过更新操作来获取ID信息,然后添加到某个分表中。 我们可以设置Mysql主键自增步长,让分布在不同实例的表数据ID做到不重复,保证整体的唯一。 如下,可以设置Mysql实例1步长为1,实例1步长为2。 查看主键自增的属性 显然,这种方式在并发量比较高的情况下,如何保证扩展性其实会是一个问题。 号段模式是当下分布式ID生成器的主流实现方式之一。其原理如下:
背景
1、UUID
Universally Unique Identifier
)是基于当前时间、计数器(counter)和硬件标识(通常为无线网卡的MAC地址)等数据计算生成的。包含32个16进制数字,以连字号分为五段,形式为8-4-4-4-12的36个字符,可以生成全球唯一的编码并且性能高效。import java.util.UUID;
public class Test {
public static void main(String[] args) {
System.out.println(UUID.randomUUID());
}
}
2、数据库自增ID
2.1、主键表
CREATE TABLE `unique_id` (
`id` bigint NOT NULL AUTO_INCREMENT,
`biz` char(1) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `biz` (`biz`)
) ENGINE = InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET =utf8;BEGIN;
REPLACE INTO unique_id (biz) values ('o') ;
SELECT LAST_INSERT_ID();
COMMIT;
2.2、ID自增步长设置
show variables like '%increment%'
3、号段模式
max_id
,
max_id +step
]。