MySQL分库分表环境下全局ID生成方案

MySQL分库分表环境下全局ID生成方案
 
在大型互联网应用中,随着用户数的增加,为了提高应用的性能,我们经常需要对 数据库进行分库分表操作。在单表时代,我们可以完全依赖于数据库的自增ID来唯一标识一个用户或数据对象。但是当我们对数据库进行了分库分表后,就不能依赖于每个表的自增ID来全局唯一标识这些数据了。因此,我们需要提供一个全局唯一的ID号生成策略来支持分库分表的环境。下面来介绍两种非常优秀的解决方案:
 
1. 数据库自增ID——来自Flicker的解决方案
 
因为MySQL本身支持auto_increment操作,很自然地,我们会想到借助这个特性来实现这个功能。Flicker在解决全局ID生成方案里就采用了MySQL自增长ID的机制(auto_increment + replace into + MyISAM)。一个生成64位ID方案具体就是这样的:
先创建单独的数据库(eg:ticket),然后创建一个表:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

CREATE TABLE Tickets64 (
             id bigint (20) unsigned NOT NULL auto_increment,
             stub char (1) NOT NULL default '' ,
             PRIMARY KEY  (id),
             UNIQUE KEY stub (stub)
     ) ENGINE=MyISAM
当我们插入记录后,执行 SELECT * from Tickets64,查询结果就是这样的:
 
+ -------------------+------+
| id                | stub |
+ -------------------+------+
| 72157623227190423 |    a |
+ -------------------+------+
在我们的应用端需要做下面这两个操作,在一个事务会话(其实应该是一个会话)里提交:
 
REPLACE INTO Tickets64 (stub) VALUES ( 'a' );
SELECT LAST_INSERT_ID();
这样我们就能拿到不断增长且不重复的ID了。
到上面为止,我们只是在单台数据库上生成ID,从高可用角度考虑,接下来就要解决单点故障问题:Flicker启用了两台数据库服务器来生成ID,通过区分auto_increment的起始值和步长来生成奇偶数的ID。
 
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14

TicketServer1:
auto-increment-increment = 2
auto-increment-offset = 1

TicketServer2:
auto-increment-increment = 2
auto-increment-offset = 2  
最后,在客户端只需要通过轮询方式取ID就可以了。
 
优点:充分借助数据库的自增ID机制,提供高可靠性,生成的ID有序。
缺点:占用两个独立的MySQL实例,有些浪费资源,成本较高。
( 转载者PS: 这里表为myisam 开始有点奇怪,感觉innodb也可以的,但是后来测试发现innodb确实可以但是如果replace into 和select 在一个
事务中执行比较慢(或尚未提交或可能因为一些意想不到的原因)的时候会阻塞其他会话获取自增id,另外如果replace事务失败虽然获取的id不会
有问题(因为 LAST_INSERT_ID()获取的是自增长字段第一次生成的id值,即使事务回滚但是自增长值无法回滚),只不过表id字段不能真实反映
出真正用于目标表的最大id值,而myisam表则不存在这个问题。纯属个人理解)
2. 独立的应用程序——来自Twitter的解决方案

Twitter在把存储 系统从MySQL迁移到Cassandra的过程中由于Cassandra没有顺序ID生成机制,于是自己开发了一套全局唯一ID生成服务:Snowflake。根据twitter的业务需求,snowflake系统生成64位的ID。由3部分组成:
41位的时间序列(精确到毫秒,41位的长度可以使用69年)
10位的机器标识(10位的长度最多支持部署1024个节点)
12位的计数顺序号(12位的计数顺序号支持每个节点每毫秒产生4096个ID序号)
优点:高性能,低延迟;独立的应用;按时间有序。
缺点:需要独立的开发和部署。
另外附上: LAST_INSERT_ID()  官方解释
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值