美文网首页凯哥Java-工作总结从零学Java笔录
分库分表后全局唯一ID的四种生成策略对比

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

作者: 凯哥Java | 来源:发表于2023-02-01 09:10 被阅读0次

分库分表之后,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的优缺点:

优点:整体吞吐量比数据库要高。因为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的四种生成策略对比

    分库分表之后,ID主键如何处理? 当业务量大的时候,数据库中数据量过大,就要进行分库分表了,那么分库分表之后,必然...

  • 设计分布式唯一id生成

    1. 生成全局唯一id 什么时候需要生成全局唯一id db不帮你自动生成的时候。比如: db做了分库分表,没帮你自...

  • 如何生成全局唯一id

    为什么需要全局唯一id 在分布式架构下,经常有需求需要生成全局唯一id,比如优惠券等券码,或者分库分表,每个表都用...

  • 如何设计一款“高可用高性能”的发号器?

    背景 在分布式场景中,很多地方需要生成全局唯一的id,如数据库分库分表后需要用唯一id代替单机版本的自增id。发号...

  • 高并发分布式系统中生成全局唯一Id汇总

    数据在分片时,典型的是分库分表,就有一个全局ID生成的问题。 单纯的生成全局ID并不是什么难题,但是生成的ID通常...

  • 全局唯一ID生成策略

    Entrance 数据在分片时,典型的是分库分表,就有一个全局ID生成的问题。 单纯的生成全局ID并不是什么难题,...

  • 如何保证 ID 的全局唯一性?

    如何保证 ID 的全局唯一性? 分库分表之后如何生成全局唯一的数据库主键呢? 数据库中的主键如何选择? 数据库中的...

  • 生成分布式序列ID

    生成分布式序列ID 介绍 在很多分布式系统中,需要生成唯一的id。如在分库分表的情况下,给某个逻辑表生成唯一id。...

  • Redis-全局唯一ID

    零、本文纲要 一、全局唯一ID 二、Redis生成全局唯一ID1、snowflake算法全局唯一ID策略2、Red...

  • snowflake升级版全局id生成

    1. 背景 分布式系统或者微服务架构基本都采用了分库分表的设计,全局唯一id生成的需求变得很迫切。传统的单体应用,...

网友评论

    本文标题:分库分表后全局唯一ID的四种生成策略对比

    本文链接:https://www.haomeiwen.com/subject/yqcihdtx.html