mysql 分布式唯一id_分布式系统中的唯一id(1)

一、背景

分布式系统中数据库中会用到唯一ID

这个唯一ID的需要满足以下特点:

1. 整个系统ID唯一

2. ID是数字类型,而且是趋势递增的

3. ID简短,查询效率快

什么是递增?

如:第一次生成的ID为12,下一次生成的ID是13,再下一次生成的ID是14(或者是第一次ID=12,下一次ID=15,再下一次是20,这叫趋势递增)

二、分布式ID的几种生成方案

2.1、UUID

优点:

1. 代码实现简单。

2. 本机生成,没有性能问题

3. 因为是全球唯一的ID,所以迁移数据容易

缺点:

1. 每次生成的ID是无序的,无法保证趋势递增

2. UUID的字符串存储,查询效率慢

3. 存储空间大

4. ID本事无业务含义,不可读

应用场景:

1. 类似生成token令牌的场景

2. 不适用一些要求有趋势递增的ID场景

2.2、MySQL主键自增

利用MySQL的主键自增auto_increment,默认每次ID加1(步增可配置)。

优点:

1. 数字化,id递增

2. 查询效率高

缺点:

1. 存在单点和高可用高稳定问题,如果mysql挂了,系统就挂了

2. 数据库压力大,高并发抗不住

2.3、MySQL多实例主键自增

这个方案解决mysql了的单点问题,在auto_increment基本上面,设置step步长

每台的初始值分别为1,2,3...N,步长为N(这个案例步长为4)

优点:

解决了单点问题

缺点:

1. 一旦把步长定好后,就无法扩容;

2. 单个数据库的压力大,数据库自身性能无法满足高并发

应用场景:

数据不需要扩容的场景

2.4、雪花snowflake算法

雪花算法生成64位的二进制正整数,然后转换成10进制的数。64位二进制数由如下部分组成:

1. 1位标识符:始终是0

2. 41位时间戳:41位时间截不是存储当前时间的时间截,而是存储时间截的差值(当前时间截 - 开始时间截 )得到的值,这里的的开始时间截,一般是我们的id生成器开始使用的时间,由我们程序来指定的

3. 10位机器标识码:可以部署在1024个节点,如果机器分机房(IDC)部署,这10位可以由 5位机房ID + 5位机器ID 组成

4. 12位序列:毫秒内的计数,12位的计数顺序号支持每个节点每毫秒(同一机器,同一时间截)产生4096个ID序号

优点:

1. 此方案每秒能够产生409.6万个ID,性能快

2. 时间戳在高位,自增序列在低位,整个ID是趋势递增的,按照时间有序递增

3. 灵活度高,可以根据业务需求,调整bit位的划分,满足不同的需求

缺点:

依赖机器的时钟,如果服务器时钟回拨,会导致重复ID生成

在分布式场景中,服务器时钟回拨会经常遇到,一般存在10ms之间的回拨

2.5、Redis生成方案

利用redis的incr原子性操作自增,一般算法为:

年份 + 当天距当年第多少天 + 天数 + 小时 + redis自增

优点:

有序递增,可读性强

缺点:

占用带宽,每次要向redis进行请求

整体测试了这个性能如下:

需求:同时10万个请求获取ID

1、并发执行完耗时:9s左右

2、单任务平均耗时:74ms

3、单线程最小耗时:不到1ms

4、单线程最大耗时:4.1s

性能还可以,如果对性能要求不是太高的话,这个方案基本符合要求。但不完全符合业务希望id从 1 开始趋势递增。(当然算法可以调整为 就一个 redis自增,不需要什么年份,多少天等)。

知行研发-刘学千

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值