mysql 分表后如何扩展_MySQL横向扩展-分库分表解决方案总结

随着业务发展,MySQL的读写压力可能成为系统瓶颈。通过读写分离、垂直分库和水平分表来缓解。垂直分库适合业务逻辑清晰、耦合度低的情况,水平分表则用于单表数据量大、查询性能下降的场景。然而,分库分表会引入跨库Join、排序合并、迁移扩容和分布式事务等问题,需要权衡解决方案和业务需求。
摘要由CSDN通过智能技术生成

a4da3ab9149a15f0d36ad72a154d0190.png从业务场景看分库分表

互联网行业中,业务场景通常写少读多的情况居多,在MySQL的使用前期,读性能大多可以通过SQL优化来解决,但随着业务的持续发展,单纯依靠SQL的查询优化会越来越难以达到业务服务要求。

因此,量级较大的业务场景,MySQL的读压力往往会首先成为系统瓶颈所在。

此时,在数据库层面,DBA通常会建议通过横向扩展备库节点的方式,采用读写分离技术来提升业务系统的读性能、读并发能力。

以上是典型的互联网读写分离需求。

除了这种多见的读瓶颈问题,在大型网站和海量数据的业务场景,数据库常见的性能瓶颈下面的两地问题会更加突出:

一是大量的并发读写操作,导致单库出现负载压力过大;

二是单表存储数据量过大,导致查询效率低下。

该种情况,由于业务的读写请求较高,MySQL在主从之间的数据同步容易引发主从延迟问题。改进的做法是,我们可能会架构设计上,需要敦促业务在写入主库之前最好将同一份数据落到缓存,以避免高并发场景下从从库中获取不到指定数据的情况发生。

如果写压力进一步扩大,并且数据量急剧快速增长,DB写节点即主库就会成为整个系统的瓶颈。在MySQL的日常运营中,如果DB中表和表之间的数据很多是没有关系的,或者根本不需要表关联Join操作,我们可以考虑按照业务把不同的数据放到不同的服务器中,即垂直分库或叫垂直切分。

不过需要注意的是,垂直分库无法解决单表数据量过大的问题,由于单一业务的数据信息仍然落盘在单表中,如果单表数据量太大,就会极大地影响SQL执行的性能。

由此,在MySQL应用领域,水平分表也是互联网场景应对高并发、单表数据量过大的解决方案之一。

分表在本质上可以概括为业务表在逻辑上公用一个路由结构,物理上分散存储。这就是常说的Sharding分片或者分区。

比如以用户ID字段user_id按照一定策略(hash、range等),将表中数据拆分到多个子表中(分片或分区),以确保子表中数据量在读写性能可接受的范围内。每个子表的结构都一样,每个表的数据都不一样,没有交集,所有表的并集是全量数据。

水平分表主要用于业务架构无法继续垂直细分、数据库中单张表数据量太大、查询性能下降的场景。

应该使用哪一种方式来实施数据库分库分表,需要从数据库的瓶颈所在和项目的业务角度进行综合考虑。如果数据库是因为表太多而造成海量数据,并且项目的各项业务逻辑划分清晰、耦合度较低,建议优先使用垂直切分。

如果数据库中的表并不多,但单表的数据量很大且数据热度很高,这种情况之下就应该选择水平切分。

在现实项目中,往往是这两种情况兼而有之,综合使用了垂直与水平切分,我们首先对数据库进行垂直切分,然后针对一部分表进行水平切分。

但是,采用分库分表也会引入新的问题。

a4da3ab9149a15f0d36ad72a154d0190.png分库分表存在的问题及注意点

l跨库Join问题

分库分表后,表之间的关联操作将受到限制,无法join位于不同分库的表,也无法join分表粒度不同的表,结果导致原本一次查询能够完成的业务可能需要多次查询才能完成。

因此,分库分表的设计,需要结合业务数据的关联场景,适当考虑数据的冗余和拆分策略。比如:根据之前表之间的关系,将相关表以相同的拆分策略,确保关联数据存放到一个分片上。或者使用表级冗余将基础数据在所有库都写一份。使用字段冗余:把需要join的字段冗余在各个表中,这样有些字段就不用join去查询了。再者就是在应用逻辑层进行数据组装:将原来的请求分两次查询,在第一次查询的结果集中找出关联数据id,然后根据id发起第二次请求得到关联数据,最后将获得到的数据进行字段拼装。

l 排序合并问题

由于数据的分库、分片导致的分散存储,原来的业务请求会引发结果集合并、排序问题。尤其是当排序字段不是分片字段的似乎,问题会变得比更加复杂。

需要先在不同的分片节点中将数据进行排序并返回,然后将不同分片返回的结果集进行汇总和再次排序,最终返回给用户。

因此,分库分表,还需要考虑业务具体的排序场景,尽量保障排序字段和分布键一致,确保请求通过分片规则就比较容易定位到指定的分片。

l 迁移和扩容问题

迁移和扩容,属于DB日常运营中常规场景。分库分表后,如果数据采用的是数值范围range分片,那么我们只需要添加节点就可以进行扩容;但如果采用的是数值hash取模分片,由于扩容涉及数据重分布过程,扩容相对比较麻烦。

所以,分库分表,需要根据业务当前、预期的数据量、QPS来进行容量规划,推算

出大概需要多少分片,尽量减少后续扩容及迁移的发生。

l分布式事务问题

由于分库分表之后,业务需要跨库跨分片进行SQL请求,类似分布式事务的问题就会出现。为了确保事务的原子性,事务的提交需要协调多个节点,加大事务的执行时间及复杂性。

因此,对于性能要求很高,但对一致性要求不高的系统,在分库分表设计的实时候可能需要采用事务补偿的方式,将实时一致性转化为最终一致性,结合业务系统比如对数据进行对账检查、基于日志进行对比等进行事后补偿。

a4da3ab9149a15f0d36ad72a154d0190.png总 结

分库分表作为一种横向扩展的解决方案,问题还是比较明显的:

从运维侧来看:会极大的加大系统的复杂度、运维成本相对较高;

从业务侧来看:会极大增加开发编码工作量,并使业务逻辑复杂化。

所以,如果无需分片,则尽量避免分库分表;如果确实到了需要分库分表的情况,相对分库分表的通用方案,如果采用分布式中间件或原生分布式数据库,业务侧无需花大量的工作来处理如何分片和分片后的问题,有更多的时间原本该是专注于业务的应用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值