高并发情况下分布式全局Id生成4种方案

本文介绍了四种在高并发场景下生成全局唯一ID的策略:1) 利用UUID作为订单号,简单但存储空间较大;2) 数据库自增ID,需设置步长避免冲突,但扩展性有限;3) Redis的原子操作INCR和INCRBY,性能优于数据库但需额外组件;4) Twitter的Snowflake算法,结合时间戳确保趋势递增。
摘要由CSDN通过智能技术生成

1.利用全球唯一UUID生成订单号

UUID是一个字符串而且没有顺序,所以不适合做主键,可以 做 token 使用。

利用全球唯一UUID生成订单号 UUID基本概念: UUID是指在一台机器上生成的数字,它保证对在同一时空中的所有机器都是唯一的。

UUID组成部分:当前日期和时间+时钟序列+随机数+全局唯一的IEEE机器识别号 全局唯一的IEEE机器识别号:如果有网卡,从网卡MAC地址获得,没有网卡以其他方式获得。

 

优点: 简单,代码方便 生成ID性能非常好,基本不会有性能问题 全球唯一,在遇见数据迁移,系统数据合并,或者数据库变更等情况下,可以从容应对

缺点: 没有排序,无法保证趋势递增 UUID往往是使用字符串存储,查询的效率比较低 存储空间比较大,如果是海量数据库,就需要考虑存储量的问题。 传输数据量大

一般UUID在生成Token领域使用比较多

2.利用数据库自增

如果使用数据库id自增生成订单号的话,如果数据库是集群的话 则有可能生成相同的订单号。

所以如果我们使用数据库id 自增做为全局 id 的话我们需要设置步长,步长表示每次自动增长的数量。

举栗子:

假如现在有 3 台 MySql 数据库做集群,mysql1,mysql2,mysql3。

设置mysql1数据库id初始值为0,mysql数据库id初始值为1,mysql3数据库id初始值为2。我们这时候需要设置步长为3,

mysql1每次自增结果为  0,3,6,9,12,15

mysql2每次自动结果为  1,4,7,10,13,16

mysql3每次自动结果为  2,5,8,11,14,17

........

这就是最后产生自增的结果,但是这种方法还有一个缺点,就是如果后期增加数据库服务器集群数量的话,mysql 步长无法扩展。所以使用这种方法生成全局id,需要前期确定好mysql数据库集群的数量,不然那到后期扩展集群数量会导致生成步长规则发生改变,可能会产生重复的id。

在数据库集群环境下,默认自增方式存在问题,因为都是从1开始自增,可能会存在重复,应该设置每台节点自增步长不同。

查询自增的步长

SHOW VARIABLES LIKE 'auto_increment%'

修改自增的步长

SET @@auto_increment_increment=10;

修改起始值

SET @@auto_increment_offset=5;

3. 基于redis生成全局id策略
 

因为Redis是单线的,天生保证原子性,可以使用Redis的原子操作 INCR和INCRBY来实现

优点: 不依赖于数据库,灵活方便,且性能优于数据库。 数字ID天然排序,对分页或者需要排序的结果很有帮助。

缺点: 如果系统中没有Redis,还需要引入新的组件,增加系统复杂度。 需要编码和配置的工作量比较大。

注意:在Redis集群情况下,同样和Redis一样需要设置不同的增长步长,同时key一定要设置有效期 可以使用Redis集群来获取更高的吞吐量。

假如一个集群中有5台Redis。可以初始化每台Redis的值分别是1,2,3,4,5,然后步长都是5。

各个Redis生成的ID为:

A:1,6,11,16,21

B:2,7,12,17,22</

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值