今天和大家聊一聊分库分表的逻辑和评估方法,俗话说授人以鱼不如授人以渔,干货是总结,是技巧。底层逻辑是认知和思维。今天通过分析底层逻辑的方式,通过多个视角和大家分享下如何评估MySQL是否要分库分表。
分库分表的逻辑和原因
分库分表的基本逻辑是就将一个数据库拆分成多个数据库,一个数据表拆分成多个数据表,将数据分布到不同的服务器上面,从而降低了单表的数据量和数据容量。
那么为什么要降低单表的数据量和容量大小呢,其根本原因是因为有些时候单表无法满足业务性能要求,同时单个数据库太大可能会受到单台服务器磁盘容量限制,另外大表的运维变更可能存在风险。
总结一下需要降低单表容量的原因有三个:
- 单表过大可能会增大运维变更风险
- 单表过大可能会带来查询性能问题
- 单表过大可能造成磁盘容量成为瓶颈
如何评估分库分表
我们知道了考虑分库分表的逻辑和原因,那么问题来了,数据表容量大真的就需要去做分库分表吗,当然不是的,下面就通过上面的三个原因,和大家梳理一下如何去判断是否需要做分库分表。
第一个是运维的考虑,大表变更会带来哪些运维问题呢,首先是大表变更存在可能影响线上业务的风险,其次是变更时间比较久,可能引起线上数据库延迟,我们知道在MySQL5.6之后类似添加索引和加字段等高频DDL变更都可以支持Online DDL,也就是理论上允许并发DML业务正常读写,不会影响业务,但是不意味着Online DDL没有任何影响,因为Online DDL变更时MySQL内部会进行大量的数据重组来解决锁的问题,会使得MySQL服务能力有一定程度的下降,在低峰期或者业务不繁忙的情况下变更是没有问题的,假如是业务高峰期做Online DDL变更,可能会引起数据库hang住的问题,另外大表变更可能会引起备库延迟。那么这个问题能作为分库分表的决策条件吗,我这里不建议,因为现在有很多方式可以让DDL变更更加平滑,比如使用OSC和gh-ost工具,比如主备切换变更,比如升级到8.0后加字段和扩容长度都是秒级操作,比如在低峰期变更降低风险等等,都可以降低变更带来的运维风险。相反如果使用分库分表,本来的一个数据库变更N个数据库,本来的一张数据表变成N*M张数据表,如果自动化变更工具不完善,后期运维管理成本会指数级上升。
第二个是性能考虑,SQL性能是评估分库分表是比较困难的一个因素,因为需要DBA去和开发同学梳理业务场景和查询SQL语句,引起SQL性能问题的变量非常多,比如数据表记录行数、索引扫描、SQL写法是否规范、业务场景等等。那么这么多变量,如何判断是需要分库分表呢,这里建议先不要看数据量,先从业务场景考虑,首先确认数据表的数据是什么数据,如果存储的是类似日志等非重要业务数据,那么就不要去考虑做分库分表了。如果是业务数据,再进行评估未来数据量的规模。评估数据量未来1-3年数据量,数据量少于1亿的那么也不要去考虑分库分表了。据我了解有些公司数据单表上千万或上百万就去做分库分表,造成大量的数据库做了分库分表,另外基于分库分表的自动化变更工具又不成熟,造成后期大量的DBA因为分库分表增加了大量的运维成本,当然小于1个亿不做分库分表是我和部分DBA的建议值,也不是绝对的,需要结合SQL查询性能一起评估,每个公司都自己的想法,几千万就分库分表也不能说完全就是错的。
第三个是磁盘容量的评估,单表过大磁盘容量会有瓶颈,分库分表也要结合表占用的磁盘空间一起评估,我们先看看导致磁盘容量非常大的原因是有哪些,总结下来主要有3个原因:
- 字段使用不合理,比如业务方字符类型本来可以使用varchar字段就可以满足需求,却使用了大量的text字段,导致同样的数据量产生的磁盘空间占用翻了几十倍甚至几百倍。(这种建表的时候让开发改掉就可以了,不能因为这个原因导致数据表容量太大而分库分表)。
- 业务写入不合理,比如把不重要的日志数据存储到数据库中,导致单表占用磁盘空间大。(原则就是非业务的表不作分库分表)。
- 正常业务写入,数据量很大可能会导致磁盘容量产生瓶颈,只有这个才是我们可以作为分库分表的条件。那么正常业务写入很大,未来可能造成存储瓶颈就必须分库分表吗,也不一定的,业务数据如果可归档,可以通过归档方式将表的数据保持在一个稳定的水平,如果查询条件都是比较好,没有性能问题也可以不用去分库分表。如果是非常核心的数据,比如用户数据,财务交易数据确实无法归档,这个时候是要考虑分库分表了。
概括总结
上面从三个方面带大家理解了分库分表的逻辑和判断方法,如果有些同学觉得理解比较困难,教大家一个通过几个问题快速评估是否需要分库分表的方法。
- 业务场景是什么?需要分表的大表存储的是什么数据?(非重要业务数据不做分库分表)
- 每天大概多少TPS,数据怎么读写的?(评估读写性能,SQL是否随着数据量增长查询性能会急剧下降)
- 数据量未来大概多少数据量?(考虑业务增长趋势下评估数据量,小于1亿的表不做库分表,这里1亿是个参考值,不是标准,需要结合查询SQL性能一起评估)
- 数据查询场景和逻辑是什么,历史是否可以归档?(数据可以归档的表考虑不分库分表)
- 是核心业务表、数据上亿、数据每年持续增长、无法归档、业务性能要求高,那就考虑分库分表吧。
关注公众号学习更多数据库、大数据、架构干货技术。