设为首页 - 加入收藏 ASP站长网(Aspzz.Cn)- 科技、建站、经验、云计算、5G、大数据,站长网!
热搜: 创业者 数据 手机
当前位置: 首页 > 站长学院 > MySql教程 > 正文

别再问“分库分表”了,再问就崩溃了!(4)

发布时间:2019-12-20 09:47 所属栏目:115 来源:站长网
导读:`stub`char(1)NOTNULLdefault'', PRIMARYKEY(`id`), UNIQUEKEY`stub`(`stub`) )ENGINE=MyISAM; stub 字段设置为唯一索引,同一 stub 值在 sequence 表中只有一条记录,可以同时为多张表生成全局 ID。 sequence 表的

  `stub` char(1) NOT NULL default '',   

  PRIMARY KEY  (`id`),   

  UNIQUE KEY `stub` (`stub`)   

) ENGINE=MyISAM; 

stub 字段设置为唯一索引,同一 stub 值在 sequence 表中只有一条记录,可以同时为多张表生成全局 ID。

sequence 表的内容,如下所示:

+-------------------+------+   

| id                | stub |   

+-------------------+------+   

| 72157623227190423 |    a |   

+-------------------+------+   

使用 MyISAM 存储引擎而不是 InnoDB,以获取更高的性能。MyISAM 使用的是表级别的锁,对表的读写是串行的,所以不用担心在并发时两次读取同一个 ID 值。

当需要全局唯一的 64 位 ID 时,执行:

REPLACE INTO sequence (stub) VALUES ('a');   

SELECT LAST_INSERT_ID();   

这两条语句是 Connection 级别的,select last_insert_id() 必须与 replace into 在同一数据库连接下才能得到刚刚插入的新 ID。

使用 replace into 代替 insert into 好处是避免了表行数过大,不需要另外定期清理。

此方案较为简单,但缺点也明显:存在单点问题,强依赖 DB,当 DB 异常时,整个系统都不可用。

配置主从可以增加可用性,但当主库挂了,主从切换时,数据一致性在特殊情况下难以保证。另外性能瓶颈限制在单台 MySQL 的读写性能。

flickr 团队使用的一种主键生成策略,与上面的 sequence 表方案类似,但更好的解决了单点和性能瓶颈的问题。

这一方案的整体思想是:建立 2 个以上的全局 ID 生成的服务器,每个服务器上只部署一个数据库,每个库有一张 sequence 表用于记录当前全局 ID。

表中 ID 增长的步长是库的数量,起始值依次错开,这样能将 ID 的生成散列到各个数据库上。

如下图所示:

别再问“分库分表”了,再问就崩溃了!

由两个数据库服务器生成 ID,设置不同的 auto_increment 值。第一台 sequence 的起始值为 1,每次步长增长 2,另一台的 sequence 起始值为 2,每次步长增长也是 2。

结果第一台生成的 ID 都是奇数(1, 3, 5, 7 ...),第二台生成的 ID 都是偶数(2, 4, 6, 8 ...)。

这种方案将生成 ID 的压力均匀分布在两台机器上。同时提供了系统容错,第一台出现了错误,可以自动切换到第二台机器上获取 ID。

但有以下几个缺点:系统添加机器,水平扩展时较复杂;每次获取 ID 都要读写一次 DB,DB 的压力还是很大,只能靠堆机器来提升性能。

可以基于 flickr 的方案继续优化,使用批量的方式降低数据库的写压力,每次获取一段区间的 ID 号段,用完之后再去数据库获取,可以大大减轻数据库的压力。

如下图所示:

别再问“分库分表”了,再问就崩溃了!

还是使用两台 DB 保证可用性,数据库中只存储当前的最大 ID。ID 生成服务每次批量拉取 6 个 ID,先将 max_id 修改为 5,当应用访问 ID 生成服务时,就不需要访问数据库,从号段缓存中依次派发 0~5 的 ID。

当这些 ID 发完后,再将 max_id 修改为 11,下次就能派发 6~11 的 ID。于是,数据库的压力降低为原来的 1/6。

③Snowflake 分布式自增 ID 算法

Twitter 的 Snowflake 算法解决了分布式系统生成全局 ID 的需求,生成 64 位的 Long 型数字。

组成部分:

第一位未使用。

接下来 41 位是毫秒级时间,41 位的长度可以表示 69 年的时间。

5 位 datacenterId,5 位 workerId。10 位的长度最多支持部署 1024 个节点。

最后 12 位是毫秒内的计数,12 位的计数顺序号支持每个节点每毫秒产生 4096 个 ID 序列。

(编辑:ASP站长网)

网友评论
推荐文章
    热点阅读