分布式ID解决方案(一)数据库号段方式

news/2025/2/22 1:56:54/

一、前言
在一些简单系统中,我们可以直接使用数据库ID自增方式来标识和保存数据,但是随着系统的逐渐复杂,数据量的日益增多,我们可能需要对数据表、数据库实现分库分表。单纯的使用数据库的ID自增无法满足业务场景了,所以我们必须找到一种方式来生成一个全局唯一的ID。我们可以先想一下,这个生成的ID的系统需要满足什么条件呢?
1.必须是全局唯一的:如果在一个订单系统中,订单号是重复的那将是灾难的。
2.高性能:生成ID,可以说是一个业务逻辑实现非常小的环节,如果在这个环节浪费很多时间,那么势必会对业务逻辑造成影响,也是不可取的。
3.高可用:让系统99.9%是可用的
4.简单:简单是我们设计一个功能应该是一直追求的。

二、实现原理
数据库号段:顾名思义就是一个数据的一个范围,例如(100,200],这个100到200就可以称为一个号段。我们可以一次向数据库申请一个号段,然后加载到内存中,然后用自增的方式生成这个ID,如果这个号段用完了,再向数据库申请另一个新的号段。
1、数据表的设计:

idbiz_typemax_idtepversion
1000110020000

biz_type::业务标识,不同业务使用不同的号段
max_id:当前最大的可用ID
tep:每次生成ID的范围长度
version:版本号,乐观锁,每次更新加上版本号,保证并发更新的准确性

2、使用步骤:

  1. 查询当前的max_id信息:select id, biz_type, max_id, step, version from tiny_id_info where biz_type=‘0001’;
  2. 计算新的max_id: new_max_id = max_id + step
  3. 更新DB中的max_id:update tiny_id_info set max_id=#{new_max_id} , verison=version+1 where id=#{id} and max_id=#{max_id} and version=#{version}
  4. 如果更新成功,则可用号段获取成功,新的可用号段为(max_id, new_max_id]
  5. 如果更新失败,则号段可能被其他线程获取,回到步骤a,进行重试。

三、高可用架构
在这里插入图片描述
ID生成系统对外提供http服务,请求经过负载均衡选择一个server,从事先加载好的号段中生成一个ID,如果没有号段或者号段已经用完,再向DB按照上边的步骤获取一个新的号段,多个server通过version乐观锁保证生成的号段不会重复。

四、问题与优化

  1. 假如某一个server重启或者宕机
    那么这个server生成的号段就作废了,而且只是浪费一部分号段,对这个ID生成系统没影响。
  2. DB挂了怎么办
    DB挂了,我们依然可以通过缓存加载的号段对外提供服务,不过这个时间是有限的,如果缓存的号段都用完了,那么就无法对外提供服务了。我们想要彻底解决这个问题,DB就不能是单机的。
  3. DB不是单机的,怎么保证不会生成重复ID呢?
    其实这个解决方案还是挺简单的,我们只需要在上边设计的数据表里新增字段。假如有A、B两个DB,那么我们就设定一个标识字段,让A生成偶数号段,B生成奇数号段即可。

http://www.ppmy.cn/news/76397.html

相关文章

Microsoft Project Online部署方案

目录 一、前言 二、Microsoft Project Online简介 三、Microsoft Project Online的优势 1、云端部署 2、多设备支持

Java设计模式总结

这里总结了23种设计模式的结构图及定义,样例代码在 Github:studeyang/design-pattern。 一、创建型模式 1.1 简单工厂模式 1.2 工厂方法模式 工厂方法模式,定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。 1.3 抽象工厂模…

【Games101】-> 计算机图形学

[toc] 【Games101】-> 计算机图形学 !!!为什么计算机图形学和计算机视觉不一样?有何区别?!!! 模型(Model) -> 图像(Image): 计算机图形学(渲染 3D -> 2D) 图像(Image) -…

2023/5/23总结

这俩天在把html全部复习了,然后学习了css部分内容: CSS 文字样式 text-indent:缩进,px像素单位,em相对文字大小 text-decoration:uderline下划线,none取消下划线。 line-height:设置行间的距离 Emmet…

Oracle数据库环境变量配置修改数据库密码

1.设置环境变量: 必须设置环境变量才可以用CMD命令访问Oracle数据库 1.1.首先找到你Oracle安装位置路径 C:\app\Administrator\product\11.2.0\dbhome_1 1.2.设置环境变量 1.2.1 设置Adimistrator变量 变量名: ORACLE_HOME 变量值:C:\app…

【链接】深入理解PLT表和GOT表

系列综述: 💞目的:本系列是个人整理为了秋招面试的,整理期间苛求每个知识点,平衡理解简易度与深入程度。 🥰来源:材料主要源于多处理器编程的艺术进行的,每个知识点的修正和深入主要…

maven的常用命令clean/package/install/deploy

如标题,下面放图: 這就是一个pom对应的maven操作命令, 那这些命令中,最常用的打包项目的命令是什么? 两种最常用打包方法: 1.先 clean,然后 package2.先 clean,然后install 下面…

SpringBoot小结

SpringBoot:Spring的诞生是为了简化 java程序开发的,SpringBoot 是 Spring 的脚手架 SpringBoot 优点 1.快速集成框架: 快速集成添加外部框架(快速引入依赖,且在SpringBoot中 SpringBoot会根据当前项目版本,引入对应依赖的版本)2.内置运行容器:内置 Web 框架 无需配置 Tomcat…