在大型互联网应用中,随着用户数的增加,为了提高应用的性能,我们经常需要对数据库进行分库分表操作。在单表时代,我们可以完全依赖于数据库的自增ID来唯一标识一个用户或数据对象。但是当我们对数据库进行了分库分表后,就不能依赖于每个表的自增ID来全局唯一标识这些数据了。因此,我们需要提供一个全局唯一的ID号生成策略来支持分库分表的环境。下面来介绍两种非常优秀的解决方案:

1. 数据库自增ID——来自Flicker的解决方案

因为MySQL本身支持auto_increment操作,很自然地,我们会想到借助这个特性来实现这个功能。Flicker在解决全局ID生成方案里就采用了MySQL自增长ID的机制(auto_increment + replace into + MyISAM)。一个生成64位ID方案具体就是这样的:

先创建单独的数据库(eg:ticket),然后创建一个表:

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。

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

最后,在客户端只需要通过轮询方式取ID就可以了。

  • 优点:充分借助数据库的自增ID机制,提供高可靠性,生成的ID有序。
  • 缺点:占用两个独立的MySQL实例,有些浪费资源,成本较高。

参考:http://code.flickr.net/2010/02/08/ticket-servers-distributed-unique-primary-keys-on-the-cheap/

2. 独立的应用程序——来自Twitter的解决方案

Twitter在把存储系统从MySQL迁移到Cassandra的过程中由于Cassandra没有顺序ID生成机制,于是自己开发了一套全局唯一ID生成服务:Snowflake。GitHub地址:https://github.com/twitter/snowflake。根据twitter的业务需求,snowflake系统生成64位的ID。由3部分组成:

41位的时间序列(精确到毫秒,41位的长度可以使用69年)
10位的机器标识(10位的长度最多支持部署1024个节点)
12位的计数顺序号(12位的计数顺序号支持每个节点每毫秒产生4096个ID序号)

最高位是符号位,始终为0。

  • 优点:高性能,低延迟;独立的应用;按时间有序。
  • 缺点:需要独立的开发和部署。

3 :MongoDB深究之ObjectId

MySQL分库分表环境下全局ID生成方案 转的更多相关文章

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

    在大型互联网应用中,随着用户数的增加,为了提高应用的性能,我们经常需要对数据库进行分库分表操作.在单表时代,我们可以完全依赖于数据库的自增ID来唯一标识一个用户或数据对象.但是当我们对数据库进行了分库 ...

  2. 【转】MySQL分库分表环境下全局ID生成方案

    转载一篇博客,里面有很多的知识和思想值得我们去思考. —————————————————————————————————————————————————————————————————————— 在大 ...

  3. 高并发环境下全局id生成策略

    解决方案: 基于Redis的全局id生成策略:(推荐此方法) 基于雪花算法的全局id生成: https://www.cnblogs.com/kobe-qi/p/8761690.html 基于zooke ...

  4. mysql分库分表(二)

    mysql分库分表 参考: https://www.cnblogs.com/dongruiha/p/6727783.html https://www.cnblogs.com/oldUncle/p/64 ...

  5. 【转】mysql分库分表,数据库分库分表思路

    原文:https://www.cnblogs.com/butterfly100/p/9034281.html 同类参考:[转]数据库的分库分表基本思想 数据库分库分表思路   一. 数据切分 关系型数 ...

  6. mysql分库分表那些事

    为什么使用分库分表? 如下内容,引用自 Sharding Sphere 的文档,写的很大气. <ShardingSphere > 概念 & 功能 > 数据分片> 传统的 ...

  7. 【分库、分表】MySQL分库分表方案

    一.Mysql分库分表方案 1.为什么要分表: 当一张表的数据达到几千万时,你查询一次所花的时间会变多,如果有联合查询的话,我想有可能会死在那儿了.分表的目的就在于此,减小数据库的负担,缩短查询时间. ...

  8. Java互联网架构-Mysql分库分表订单生成系统实战分析

    概述 分库分表的必要性 首先我们来了解一下为什么要做分库分表.在我们的业务(web应用)中,关系型数据库本身比较容易成为系统性能瓶颈,单机存储容量.连接数.处理能力等都很有限,数据库本身的“有状态性” ...

  9. 高可用Mysql架构_Mysql主从复制、Mysql双主热备、Mysql双主双从、Mysql读写分离(Mycat中间件)、Mysql分库分表架构(Mycat中间件)的演变

    [Mysql主从复制]解决的问题数据分布:比如一共150台机器,分别往电信.网通.移动各放50台,这样无论在哪个网络访问都很快.其次按照地域,比如国内国外,北方南方,这样地域性访问解决了.负载均衡:M ...

随机推荐

  1. iOS传值方式:属性,代理,block,单例,通知

    正向传值均可,反向传值除属性传值不可,其余均可.下面简单介绍: (一)属性传值 第二个界面中的lable显示第一个界面textField中的文本 首先我们建立一个RootViewControllers ...

  2. 锋利的jquery学习笔记

    1.$("#tt")获取的永远都是一个jquery对象,所以要判断页面上是否存在某个对象不能像js中 if($("#tt")){ } 而是通过: ){ } ps ...

  3. Tranparent/cutout/diffuse

    Shader "Tranparent/cutout/diffuse" { Properties {   //  _Color ("Main Color", Co ...

  4. Magento给新产品页面添加分页

    本文介绍如何让magento创建一个带分页功能的新到产品页面,方便我们在首页或者其它CMS Page调用和展示新到产品. 在Magento我们经常有的做法是建立一个可以调用新产品的block,然后通过 ...

  5. You must install 'hg' on your build machine

    /***************************************************************************************** * You mus ...

  6. TNF-mutithread 编译过程记录

    地址 https://github.com/msng4t/TNF-mutithread 地址 https://github.com/msng4t/TNF 目的:想要寻找一套性能,可读性相对较好的Soc ...

  7. hdu4642 Fliping game ——博弈

    link:http://acm.hdu.edu.cn/showproblem.php?pid=4642 refer to: http://www.cnblogs.com/jackge/archive/ ...

  8. makefile--统一目标输出目录 (六)

    原创博文,转载请标明出处--周学伟http://www.cnblogs.com/zxouxuewei/ 上一节我们把规则单独提取出来,方便了Makefile的维护,每个模块只需要给出关于自己的一些变量 ...

  9. activiti 任务授权,把流程中当前任务授权个其他用户代为办理

    / * 授权代办 * @param serDoc / @Transactional(readOnly = false) public void authAgent(SerDoc serDoc) { S ...

  10. 工作中遇到的问题--实现CustomerSetting的实时更新

    首先在项目运行时就初始化CustomerSettings的值,采用@Bean,默认是singtone模式,只会加载一次. @Configuration@Order(3)@EnableWebMvcSec ...