`

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

 
阅读更多

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

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

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

413f52c7a08ddc586135b60a2c1c3993.png

 

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

数据库自增ID

原理:

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

c3a43d012cf90106d6d1a63eae8b8f62.png

 

这种方式的优缺点如下

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

本文由凯哥Java(GZ#H:kaigejava),个人博客:www#kaigejava#com 发布于ITeye.

缺点:

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。也欢迎大家有事没事就来和凯哥聊聊~~~

 


 

 

分享到:
评论

相关推荐

    50_一个关键的问题!分库分表之后全局id咋生成?.zip

    总的来说,分库分表后的全局ID生成是一个复杂但至关重要的问题,Java开发者需要理解并掌握如Snowflake算法等解决方案。这些技术不仅需要保证ID的全局唯一性,还要考虑生成效率、可扩展性和容错性等因素。通过深入...

    10-发号器:如何保证分库分表后ID的全局唯一性?_For_group_share1

    在分布式数据库环境中,确保分库分表后的ID全局唯一性是一项关键挑战。传统的自增ID在单库单表中能够很好地工作,但在分布式系统中,由于数据分散在多个数据库或表中,简单的自增策略无法满足全局唯一性的需求。在...

    MySQL分库分表技术

    3. **ID生成**:如何生成全局唯一且分散的ID成为问题,可使用雪花算法或分布式ID生成服务(如Twitter的Snowflake、百度的UidGenerator)。 4. **运维复杂性**:数据库数量增多,运维工作量增加,需要自动化工具进行...

    Python+MySQL分表分库实战

    Snowflake是一种流行的全局ID生成策略,它能够生成64位的唯一ID,其中包含时间戳、机器ID和序列号等信息,保证了分布式环境下的ID唯一性。 数据迁移是分库分表过程中必不可少的一个环节。数据迁移通常需要考虑数据...

    sharding + mybatis-plus 分库分表

    总的来说,“Sharding + Mybatis-Plus 分库分表”是一种有效的解决大数据量场景下的数据库扩展策略,它通过Java的中间件技术,实现了数据库层面的水平扩展,结合Mybatis-Plus的便利性,降低了开发复杂度,提升了系统...

    MySQL 分库分表的实现原理及演示案例.zip

    分库分表是数据库水平扩展的一种常见策略,它通过将数据分散到多个数据库或表中,来减轻单个数据库的压力,提高系统的并发处理能力和整体性能。 **分库** 是将一个大数据库拆分成多个小数据库,每个数据库负责一...

    Mybatis分库分表扩展插件

    4. **分布式ID生成**:为了保证全局唯一性,需要使用分布式ID生成策略,如Snowflake算法。 总的来说,Mybatis分库分表插件是应对大数据量场景的重要工具,通过合理的插件设计和配置,可以有效地提升系统的扩展性和...

    第五节课交易分库分表详解一1

    - **全局ID生成**:结合美团的方案,使用业务ID加上区间自增ID,以确保全局唯一性。 综上所述,应对超大表和数据库压力,需要综合运用各种策略,包括硬件升级、数据库系统更换、分库分表技术以及优化业务流程。在...

    第六节课交易分库分表详解二1

    本节主要讨论了在进行数据库分库分表时遇到的挑战以及相应的分布式唯一ID解决方案。分库分表是为了应对高并发、大数据量场景下的性能瓶颈,但是它带来了如分布式事务、分布式主键、跨库查询以及数据迁移等问题。 ...

    对分库分表的一些想法

    7. ID生成策略:分库分表后,自增ID可能会冲突,需要设计全局唯一ID生成策略,例如雪花算法、UUID等。 8. 数据迁移与备份:分库分表后,数据迁移和备份也需要考虑各个库表之间的关系,确保数据完整性。 9. 监控与...

    SpringCobar分库分表

    在现代企业级应用程序开发中,随着数据量的不断增长,单个数据库往往难以承载庞大的业务数据,这使得分库分表成为一种必要的解决方案。本文将深入探讨“SpringCobar分库分表”这一主题,结合SpringMVC、Cobar、...

    分库分表入门级-lzg

    **四、分库分表策略选择** 1. **时间区间**:适用于时间序列数据,如日志记录,易于线性扩容,但非时间维度查询较复杂。 2. **取模**:简单快速,但可能产生热点,不适用于高并发场景下的均匀分布。 3. **区间+取模...

    Mycat数据库分库分表

    2. 表结构设计:在分库分表后,表的主键需要调整,通常采用全局唯一ID生成器生成分布式主键,保证数据的唯一性。 3. SQL改写:由于分片的存在,SQL不能再直接操作全量数据,需要对SQL进行改写,Mycat会自动完成这个...

    incubator-shardingsphere-example-dev_currenthfw_分库分表_源码

    分库分表是解决大数据量数据库性能问题的一种常见策略。它将单一的大表拆分为多个小表,分散存储在不同的数据库实例上,以降低单表的数据量,提高查询效率。ShardingSphere 提供了灵活的分库分表规则配置,可以根据...

    Mysql分库分表实例-Sub-LibriryTable.zip

    分库分表是数据库水平扩展的一种常见手段,它将一个大表拆分成多个小表,分别存储在不同的数据库或同一数据库的不同表中,以此提高查询效率和系统的可扩展性。下面我们将详细探讨这一实例——"Mysql分库分表实例-Sub...

    分库分表数据看板项目实战

    因此,“分库分表”技术应运而生,这是一种有效的数据库水平扩展策略。本项目实战“分库分表数据看板”将深入探讨如何在实际操作中实施这一技术,以提升系统的处理能力和数据管理效率。 分库分表,顾名思义,就是将...

    49_好啊!那如何设计可以动态扩容缩容的分库分表方案?.zip

    6. 全局序列号:如何生成全局唯一ID,避免主键冲突。 7. 跨库查询:如何设计合适的接口或中间件,支持跨库查询和聚合操作。 "01_分库分表扩容方案.png"可能是一张图表,清晰地展示了分库分表的架构和扩容缩容的流程...

Global site tag (gtag.js) - Google Analytics