分布式ID解决方案
2023-08-27 00:32:30 0 举报
AI智能生成
分布式ID解决方案分布式ID解决方案分布式ID解决方案分布式ID解决方案
作者其他创作
大纲/内容
参考自
https://mp.weixin.qq.com/s/0RBeWV-any_Rb9JbVPvcfw
UUID
实现
String uuid = UUID.randomUUID().toString().replaceAll("-","");
优点
生成足够简单,本地生成无网络消耗,具有唯一性
缺点
不适用于实际的业务需求。
像用作订单号UUID这样的字符串没有丝毫的意义,看不出和订单相关的有用信息;
而对于数据库来说用作业务主键ID,它不仅是太长还是字符串,存储性能差查询也很耗时
而对于数据库来说用作业务主键ID,它不仅是太长还是字符串,存储性能差查询也很耗时
基于数据库自增ID
实现
基于数据库的auto_increment自增ID。(需要一个单独的MySQL实例用来生成ID)
当我们需要一个ID的时候,向表中插入一条记录返回主键ID,
但这种方式有一个比较致命的缺点,访问量激增时MySQL本身就是系统的瓶颈,
用它来实现分布式服务风险比较大,不推荐!
但这种方式有一个比较致命的缺点,访问量激增时MySQL本身就是系统的瓶颈,
用它来实现分布式服务风险比较大,不推荐!
优点
实现简单,ID单调自增,数值类型查询速度快
缺点
DB单点存在宕机风险,无法扛住高并发场景
基于数据库集群模式
实现
将前面的基于数据库自增方案,从单节点换成主从模式集群甚至可以双主模式
设置起始值和自增步长
库1
offset = 1; -- 起始值
increment = 2; -- 步长
库2
offset = 2; -- 起始值
increment = 2; -- 步长
如果仍扛不住高并发则使用水平扩展实例
优点
解决DB单点问题
缺点
不利于后续扩容,而且实际上单个数据库自身压力还是大,依旧无法满足高并发场景。
基于数据库的号段模式
实现
号段模式可以理解为从数据库批量的获取自增ID,每次从数据库取出一个号段范围,
例如 (1,1000] 代表1000个ID,具体的业务服务将本号段,生成1~1000的自增ID并加载到内存。
例如 (1,1000] 代表1000个ID,具体的业务服务将本号段,生成1~1000的自增ID并加载到内存。
表结构
CREATE TABLE id_generator (
id int(10) NOT NULL,
max_id bigint(20) NOT NULL COMMENT '当前最大id',
step int(20) NOT NULL COMMENT '号段的布长',
biz_type int(20) NOT NULL COMMENT '业务类型',
version int(20) NOT NULL COMMENT '版本号',
PRIMARY KEY (`id`)
)
id int(10) NOT NULL,
max_id bigint(20) NOT NULL COMMENT '当前最大id',
step int(20) NOT NULL COMMENT '号段的布长',
biz_type int(20) NOT NULL COMMENT '业务类型',
version int(20) NOT NULL COMMENT '版本号',
PRIMARY KEY (`id`)
)
等这批号段ID用完,再次向数据库申请新号段,对max_id字段做一次update操作,
update max_id= max_id + step,update成功则说明新号段获取成功,
新的号段范围是(max_id ,max_id +step]。
update max_id= max_id + step,update成功则说明新号段获取成功,
新的号段范围是(max_id ,max_id +step]。
优点
由于多业务端可能同时操作,所以采用版本号version乐观锁方式更新,这种分布式ID生成方式不强依赖于数据库,
不会频繁的访问数据库,对数据库的压力小很多。目前比较主流
不会频繁的访问数据库,对数据库的压力小很多。目前比较主流
基于Redis模式
实现
利用redis的incr命令实现ID的原子性自增。
缺点
RDB会定时打一个快照进行持久化,假如连续自增但redis没及时持久化,而这会Redis挂掉了,重启Redis后会出现ID重复的情况。
AOF会对每条写命令进行持久化,即使Redis挂掉了也不会出现ID重复的情况,但由于incr命令的特殊性,会导致Redis重启恢复的数据时间过长。
基于雪花算法(Snowflake)模式
实现
百度(uid-generator)
实现
基于雪花算法实现。
uid-generator需要与数据库配合使用,需要新增一个WORKER_NODE表。当应用启动时会向数据库表中去插入一条数据,插入成功后返回的自增ID就是该机器的workId数据由host,port组成。
同一应用每次重启就会消费一个workId
美团(Leaf)
实现
号段模式。(需要使用数据库并建立一张号段表)
雪花模式
依赖于ZooKeeper,不同于原始snowflake算法也主要是在workId的生成上,Leaf中workId是基于ZooKeeper的顺序Id来生成的,每个应用在使用Leaf-snowflake时,启动时都会都在Zookeeper中生成一个顺序Id,相当于一台机器对应一个顺序节点,也就是一个workId。
滴滴(Tinyid)
实现
基于号段模式原理实现的与Leaf如出一辙
0 条评论
下一页