加入收藏 | 设为首页 | 会员中心 | 我要投稿 西安站长网 (https://www.029zz.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 建站 > 正文

MySQL分库分表会带来哪些问题?

发布时间:2019-08-01 07:04:35 所属栏目:建站 来源:码帮联盟
导读:副标题#e# 分库分表能有效的环节单机和单库带来的性能瓶颈和压力,突破网络IO、硬件资源、连接数的瓶颈,同时也带来了一些问题。下面将描述这些技术挑战以及对应的解决思路。 1、事务一致性问题 分布式事务 当更新内容同时分布在不同库中,不可避免会带来跨

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

  1. REPLACE INTO sequence (stub) VALUES ('a');  
  2. 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的生成散列到各个数据库上。如下图所示:

Mysql数据库-分库分表都带来的哪些问题?

由两个数据库服务器生成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号段,用完之后再去数据库获取,可以大大减轻数据库的压力。如下图所示:

Mysql数据库-分库分表都带来的哪些问题?

还是使用两台DB保证可用性,数据库中只存储当前的最大ID。ID生成服务每次批量拉取6个ID,先将max_id修改为5,当应用访问ID生成服务时,就不需要访问数据库,从号段缓存中依次派发0~5的ID。当这些ID发完后,再将max_id修改为11,下次就能派发6~11的ID。于是,数据库的压力降低为原来的1/6。

3)Snowflake分布式自增ID算法

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

  • 第一位未使用
  • 接下来41位是毫秒级时间,41位的长度可以表示69年的时间
  • 5位datacenterId,5位workerId。10位的长度最多支持部署1024个节点
  • 最后12位是毫秒内的计数,12位的计数顺序号支持每个节点每毫秒产生4096个ID序列
Mysql数据库-分库分表都带来的哪些问题?

这样的好处是:毫秒数在高位,生成的ID整体上按时间趋势递增;不依赖第三方系统,稳定性和效率较高,理论上QPS约为409.6w/s(1000*2^12),并且整个分布式系统内不会产生ID碰撞;可根据自身业务灵活分配bit位。

不足就在于:强依赖机器时钟,如果时钟回拨,则可能导致生成ID重复。

综上

结合数据库和snowflake的唯一ID方案,可以参考业界较为成熟的解法:Leaf——美团点评分布式ID生成系统,并考虑到了高可用、容灾、分布式下时钟等问题。

5、数据迁移、扩容问题

(编辑:西安站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读