分表场景全局唯一ID怎么破?

1、在分表场景下,单表的数据量一般建议不超过多少?
2、全局唯一ID怎么生成和保证?怎么创建唯一索引?

参与11

3同行回答

匿名用户匿名用户
全局唯一ID建议使用分布方式生成,这样避免有性能瓶颈点,最好还取消对当前时间的限制,因为数据库分布之后,节点只能只用NTP尽量保持时间同步http://www.cnblogs.com/baiwa/p/5318432.html显示全部

全局唯一ID建议使用分布方式生成,这样避免有性能瓶颈点,最好还取消对当前时间的限制,因为数据库分布之后,节点只能只用NTP尽量保持时间同步
http://www.cnblogs.com/baiwa/p/5318432.html

收起
银行 · 2017-07-07
浏览1591
y18511664518y18511664518技术总监长城超云
MYSQL分库分表的 全局ID解决方案,供参考。数据库自增ID——来自Flicker的解决方案因为MySQL本身支持auto_increment操作,很自然地,我们会想到借助这个特性来实现这个功能。Flicker在解决全局ID生成方 案里就采用了MySQL自增长ID的机制(auto_increment + replace into + MyISA...显示全部

MYSQL分库分表的 全局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,查询结果就是这样的:

idstub
72157623227190423a

在我们的应用端需要做下面这两个操作,在一个事务会话里提交:

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/

  1. 独立的应用程序——来自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。

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

注:last_insert_id()的值是由MySQL server来维护的,而且是为每条连接维护独立的值,也即,某条连接调用last_insert_id()获取到的值是这条连接最近一次insert操作执行后的自增值,该值不会被其它连接的sql语句所影响。这个行为保证了不同的连接能正确地获取到它最近一次insert sql执行所插入的行的自增值,也就是说,last_insert_id()的值不需要通过加锁或事务机制来保证其在多连接场景下的正确性

收起
金融其它 · 2017-08-10
浏览1540
renou2012renou2012数据库管理员KE
1 单表的数据量很难有个标准的建议,因为这个说白了不是单一的按照数据量来评估的,主要还是根据业务的,通过你的优化,只要能满足业务的响应时间,不建议分,不要为了分而分。当然还有个人建议值1000w+,具体如何,你还需要看业务。2 全局唯一ID,确保唯一的手段有很多,这个问题需要确定你...显示全部

1 单表的数据量很难有个标准的建议,因为这个说白了不是单一的按照数据量来评估的,主要还是根据业务的,通过你的优化,只要能满足业务的响应时间,不建议分,不要为了分而分。
当然还有个人建议值1000w+,具体如何,你还需要看业务。
2 全局唯一ID,确保唯一的手段有很多,这个问题需要确定你的业务场景,有业务层自己实现比如时间戳+机器id+序列号,
UUID,数据库的自增序列或者自增序列+业务键1+业务键2等

收起
金融其它 · 2017-07-07
浏览1704

提问者

hanzhenhua
数据库管理员饿了么

问题来自

相关资料

问题状态

  • 发布时间:2017-07-06
  • 关注会员:4 人
  • 问题浏览:4702
  • 最近回答:2017-08-10
  • X社区推广