首页 > 其他分享 >分库分表后全局唯一ID的四种生成策略对比

分库分表后全局唯一ID的四种生成策略对比

时间:2023-02-02 09:11:34浏览次数:53  
标签:分库 数据库 毫秒 算法 分表 ID

分库分表之后,ID主键如何处理?

当业务量大的时候,数据库中数据量过大,就要进行分库分表了,那么分库分表之后,必然将面临一个问题,那就是ID怎么生成?因为要分成多个表之后,如果还是使用每个表的自增长ID,意味着每个表都是从1开始累加的,这样肯定是不对的。需要一个全局唯一的ID来支持。所以这也是你实际生产环境中必须考虑的一个问题。全局ID生成器,一般需要满足下列几个特性:

唯一性、高可用、递增性、安全性、高可用性

413f52c7a08ddc586135b60a2c1c3993.png

 

常用的主键ID生成策略有以下几种:

数据库自增ID

原理:

如果使用这种方式,那么这就意味着,你的系统里每次得到一个ID,都需要往一个库中的一个表中插入一条没有什么业务含义的数据,然后获取一个数据库自增的id.拿到这个ID之后,再往对应的分库分表里写。

c3a43d012cf90106d6d1a63eae8b8f62.png

 

这种方式的优缺点如下:

优点:非常简单,有序递增,方便分页和排序。

缺点:

a.分库分表之后,数据表的自增ID容易重复,无法直接使用(虽然可以设置步长,但是局限性明显);

b.性能吞吐量整个比较低。如果设计一个单独的数据库来实现分布式应用的数据唯一性,即使使用预先生成方案,也会因为事务问题,在高并发场景下容易出现单点的瓶颈问题。

使用场景:单数据库实例的表ID(包含主从同步场景);部分按天计数的流水号等

在分不分表场景、全局唯一性ID场景下不使用。

Redis生产全局ID

原理:

通过Redis的INCR/INCRBY自增原子操作命令,能保证生产的ID肯定是唯一的序列号,本质上实现方式与数据库一致的。

2ba2ef16c94fd5c1c78e127cf65642dc.png

使用Redis生产全局ID的优缺点:

本文由凯哥Java(公众号:kaigejava),个人博客:www.kaigejava.com 发布于博客园.

 

凯哥自己开发的,领取外卖、打车、咖啡、买菜、各大电商的优惠券的公¥众¥号。如下图:

527c8a82983e56a30f4299fc76e1956a.png

优点:整体吞吐量比数据库要高。因为Redis的吞吐量性能高于数据库

缺点:Redis实例或者集群宕机后,找回最新的ID值比较麻烦。但是可以在生产唯一ID的算法上进行优化,避免这种情况。

使用场景:比较适合计算场景。比如用户访问量、订单流水号(日期+流水号)等。

凯哥推荐文章:Redis实战9-全局唯一ID

UUID、GUID生成ID

 

优缺点:

优点:性能非常高。在本地生成,没有网络消耗;

缺点:UUID太长了,占用空间大,作为主键性能太差了;

由于UUI不具有有序性,会导致B+树索引在写的时候有过多的随机写操作。

使用场景:如果你要随机生成一个什么文件名称、编号之类的,可以考虑使用UUID,但是如果是作为数据库的主键,不建议使用UUID的。

雪花算法(snowflake)

雪花算法来源于Twitter,使用Scala语言实现,雪花算法的特性是有序、唯一且要求性能高,低延迟(每台集群每秒至少生成10K条数据,并且响应时间在2MS内),要在分布式环境(多集群、跨机房)下使用。因此雪花算法得到的ID是分段组成的。

a.与指定日期时间差(时间差到毫秒级)的,41位数字,可以使用69年;

b.机器ID+集群ID,10位,最多支持1024台机器;

c.序列号,12位。每台机器每毫秒内最多生产4096个序列号.

雪花算法的核心思想是:

分布式ID固定是一个long类型的数字,一个long类型占用8个字节,也就是8*8=64个bit位。所以,雪花算法的格式如下图:

42e2b28690ba0bf1dabb5bdf96898e62.png

雪花算法分段,每段含义:

第一段:也就是最高1位是符号位。固定值,就是0,标识全部ID都是正整数。

第二段:接下来的41位,标识的是时间戳。单位是毫秒。41bits标识的数字对应的是2^41次方-1.也就是可以标识2的41次方-1个毫秒值。换算成年就是标识69年的时间;

第三段:再接下来的10位标识的是机器ID。如果有异地部署,多集群的也可以配置,需要在线下提前规划好各地机房,各个集群,实例ID的编号。其中包括5位的机器id和5位的集群id.最多可以部署2^10台机器。也就是1024台。

第四段:最后12位是序列号。用于记录同一毫秒内产生的不同ID.12个比特位可以代表的最大正整数是2^12-1=4096.也就是说,可以用这12个bits代表数字来区分同一毫秒内4096个不同的ID.

此算法的优缺点如下:

雪花算法的优缺点:

优点:毫秒数在高位,自增序列在低位,所以整个ID都呈现出递增趋势;

不依赖数据库等三方系统,以服务部署方式,稳定性更高,生成ID的性能也是非常高的;

可以根据自身业务特性来分配bit位,非常灵活。

缺点:

太依赖集群的时钟,如果机器时钟回拨了,可能会导致重复或者服务处于不可用。

 

结束语

大家好,我是凯哥Java(kaigejava),乐于分享技术文章,欢迎大家关注“凯哥Java”,及时了解更多。让我们一起学Java。也欢迎大家有事没事就来和凯哥聊聊~~~

 



 

标签:分库,数据库,毫秒,算法,分表,ID
From: https://www.cnblogs.com/kaigejava/p/17084799.html

相关文章

  • IntelliJ IDEA如何整理代码格式
    方法一选择文件,右键选择ReformatCode即可。方法二按快捷键Ctrl+Alt+L键即可快速对代码进行格式化。重新设置快捷键如果出现热键冲突或者想自定义快捷键,也可以在系统......
  • AT3883 [ARC090C] Avoiding Collision
    AT3883[ARC090C]AvoidingCollisionTJ题意:给定一个$N$个点$M$条边的无向图,每条边附加有正整数边权(时间),给出两个点$S$和$T$,询问分别从两个点出发,走最短......
  • 大数据实时多维OLAP分析数据库Apache Druid入门分享-下
    @目录架构核心架构外部依赖核心内容roll-up预聚合列式存储Datasource和Segments位图索引数据摄取查询集群部署部署规划前置条件MySQL配置HDFS配置Zookeeper配置启动集群导......
  • 关于STM32CubeIDE无法正常启动GDB服务端的解决办法
    关于STM32CubeIDE无法正常启动GDB服务端的解决办法有时,可能STM32CubeIDE会报错,如下图FailedtostartGDBserver。而且点击Details也只能得知“ST-LINK初始化失败”......
  • PostgreSQL:标识符( Identifier)构成规则探究
    PostgreSQL14.0--- 疑问数据库、schema、table、字段、视图等的名称有什么规范呢?使用过程中,可以用字母开头,还可以有下划线,更准确的规则是什么呢?这些名称的长度有......
  • CentOS7安装NVIDIA显卡驱动
    CentOS7安装NVIDIA显卡驱动安装依赖项:yuminstall-ygccgcc-c++kernel-devel检查内核版本和内核版本是否一致,否则安装会报错:查看内核版本ls/boot|grepvmlinu查看源码......
  • Qt | QListWidgetItem返回错误的背景颜色(始终返回颜色值为0)问题解决
    Qt|QListWidgetItem返回错误的背景颜色(始终返回颜色值为0)问题解决使用场景:程序使用QListWidget显示一个列表,这个列表具有点击选择和再次点击取消选择的功能,点击之后需要更......
  • jdbc+Druid工具类
    本文主要讲述使用druid连接池,将jdbc封装成工具类一.连接池  二.使用druid连接池在jdbc工具类的基础上,使用druid连接池,增加连接数量。hsp老师写的方式:/......
  • 数据库分库分表-水平分片与垂直分片
    水平分片与垂直分片垂直分片:​ 按照业务维度将表拆到不同的数据库中,专库专用,分担数据库压力​ 缺点:单表数据量大时,无法解决数据库访问慢的问题水平分片:​ 按照某种规......
  • 【嵌入式】ChipON IDE编程格式
    C文件头模板/***@file:KeyFunction.c*@copyright:Copyright2020-2021SGMW.Co.Ltd.AllRightsReserved.*@brief:按键模块*@detail:涉及按键识别,以及按键按下......