MySQL 分表后,真的就万事大吉了吗?

扫描下方海报二维码,试听课程:
面试

(课程详细大纲,请参见文末)数据库

文章转自公众号:crossoverJie架构

前言

本篇是上一篇《一次分表踩坑实践的探讨》,因此还没看过的朋友建议先看上文。并发

仍是先来简单回顾下上次提到了哪些内容:运维

  • 分表策略:哈希、时间归档等。分布式

  • 分表字段的选择。性能

  • 数据迁移方案。3d

而本篇文章的背景是在咱们上线这段时间遇到的一些问题并尝试解决的方案。code

问题产生

以前提到在分表应用上线前咱们须要将原有表的数据迁移到新表中,这样才能保证业务不受影响。orm

以下图所示:

因此咱们单独写了一个迁移应用,它负责将大表中的数据迁移到 64 张分表,而再迁移过程当中产生的数据毕竟是少数,最后在上线当晚再次迁移过去便可。

一切想的很美好,当这个应用上线后却发现没这么简单。

数据库负载升高

首先第一个问题是数据库本身就顶不住了,在咱们上这个迁移程序以前数据库的压力自己就比较大,这个应用一上去就成了最后一根稻草。

最后致使的结果是:全部链接了数据库的程序大部分的操做都出现超时,获取不到数据库链接等一系列的异常。

最后没办法咱们只能把这个应用放到凌晨执行,但其实后面观察发现依然不行。

虽然说凌晨的业务量降低,但依然有少部分的请求过来,也会出现各类数据库异常。

再一个是迁移程序的效率也很是低下,按照这样是速度,咱们预估了一下迁移时间,大约须要 10 几天才能把三张最大的表(三、4亿的数据)迁移到分表中。

因而咱们换了一个方案,将这个迁移程序在从库中运行,最后再用运维的方法将分表直接导入进主库。

由于从库的压力要比主库小不少,对业务的影响很小,同时迁移的效率也要快不少。

即使是这样也花了一夜+一个白天的时间才将一张 1亿的数据迁移完成,可是业务上的压力愈来愈大,数据量再不断新增,这个效率依然不够。

兼容方案

最终没办法只有想一个不迁移数据的方案,可是新产生的数据仍是往分表里写,至少保证大表的数据再也不新增。

但这样对于之前的数据咋办呢?总不能不让看了吧。

其实对于数据的操做无非就分为 增删改查,就这四种操做来看看如何兼容。

新增

新增最简单,全部的数据根据分表规则直接写入新表,这样能够保证老表的数据再也不新增。

删除

删除就要比新增稍微复杂一些,好比用户想要删除他我的产生的一条信息(好比说是订单数据),有可能这个数据在新表也可能在老表。

因此删除时优先删除新表(毕竟新产生的数据访问的频次越高),若是删除失败再从老表删除一次。

修改

而修改同理,一样的会不肯定数据存在于哪里,因此先要修改新表,失败后再次修改老表。

查询

查询相对就要复杂一些了,由于这些大表的数据大部分都是存放一个用户产生的多条记录(好比一个用户的订单信息)。

这时在页面上一般都会有分页,而且按照时间进行排序。

麻烦的地方就出在这里:既然是要分页那就有可能出现要查询一部分分表数据和原来的大表数据作组合。

因此这里的查询其实分为三种状况,来看下面的图:

  • 首先查询的时候要计算这个用户所在分表中的数据能够分为几页。

  • 第一步首先判断当前页是否能够在分表中所有获取,若是能够则直接从分表中取出数据返回(假设分页中总共能够查询 2 页数据,当前为第 1 页,那就所有取分表数据)。

  • 若是不能够就要判断当前页数在分表中是否取不到任何一条数据,若是是则直接取老表数据(好比如今要取第 5 页的数据,分表中一共才只有 2 页数据,因此第 5 页数据只能所有从老表中获取)。


  • 但若是分表和老表都存在一部分数据时,则须要同时取两张表而后作一个汇总再返回。

这种逻辑只适用于根据分表字段进行查询分页的前提下

我想确定会有朋友提出这样是否会有性能问题?

同时若是在计算分表分页数量时出现并发写入的状况,致使分页数量不许从而对后续的查询出现影响该怎么处理?

首先第一个性能问题:

其实这个要看怎么取舍,为了这样的兼容目的其实会比常规查询多出几个步骤:

  • 判断当前页是否能够在分表中查询。

  • 当新老表中都有数据时候须要额外多查询一张大表。

第一个判断逻辑实际上是在内存中计算,这个损耗我以为彻底能够忽略不计。

至于第二步确实会有损耗,毕竟多查了一张表。

但在分表以前全部的数据都是从老表中获取的,当时的业务也没有出现问题;如今多的只是查询分表而已,但分表的数据量确定要比大表小的多,并且有索引,因此这个效率也不会慢多少。

并且根据局部性原理及用户的使用习惯来看,老表中的数据不多会去查询,随着时间的推移全部的数据确定都会从分表中获取,逐渐老表就会成为历史表。

而第二个并发带来的问题我以为影响也不大,必定要这个分页准的前提确定得是加锁了,但为了这样一个不痒的小问题却带来性能的降低,我以为是不划算的。

并且后续咱们也能够慢慢的将老表的数据迁移到新表,这样就能够彻底去掉这个兼容逻辑了,全部的数据都从分表中获取。

总结

仍是以前那句话,这里的各类操做、方法不适合全部人,毕竟脱离场景都是耍牛氓。

好比分表搞的早,业务上容许必定的时间将数据迁移到分表那就不会有此次的兼容处理。

甚至一开始业务规划合理、团队架构师看的长远,一来就将关键数据分表存储那根本就不会有数据迁移这个流程(大厂有经验的团队可能,小公司小做坊都得靠本身摸索)。

这段期间也被数据库折腾惨了,数据库是最后一根稻草果真也不是瞎说的。



END


《21天互联网Java进阶面试训练营(分布式篇)》详细目录,扫描图片末尾的二维码,试听课程

相关文章
相关标签/搜索