分库分表概念
读写分离的基本概念学习后了解到可以通过该方法进行系统读能力的扩展。但随后会想到如果是大量写的场景如何扩展?这是就用到分库分表,可以对写能力进行扩展。
当业务规模不断壮大,数据暴增,可能会出现设置了索引也没法改善数据库性能的问题。这时可以通过水平分区来解决。即将一张数据表存储的大量数据,拆分为多个子表来维护。
进行划分主要有三种方式,分表、分库及分库分表。

- 仅分表:在一个库中将一张表拆分为多个表。原有库中的表变为表1与表2。
- 仅分库:分多个库,每个库只有一个表。每个表维护原表中的部分数据。
- 分库分表:化分多个库,每个库维护多个表。例如库1维护表1与表2。库2维护表2与表3。
经过分库分表后有如下的好处。
- 分库写入压力分摊:写入操作不再集中于一个库上,而是分散开,这样降低了单库的写入压力。
- 分表提高表维护效率:当对表写入数据,会出现重建索引的情况,单表数据量减少,那么索引维护的开销也会下降。此外单表数据量减少,查询效率也会增高。此外锁操作压力也会降低。
分库分表带来的问题
有分库分表的结构可只,在分布式环境下需要考虑下列问题:
- 增删改查:在分布式环境下对哪些库表执行这些操作。
- 分布式id:在分布式环境下生成的id应该全局唯一。
- 分布式事务:如何实现或进行等价操作。
- 分布式动态扩容:分布式环境下如何增加或减少机器。
增删改查操作
显然在分布式环境下需要考虑一个sql语句到底在哪个库表执行。因此需要数据库及数据表路由的功能。当得到一条sql语句时我们需要执行下列操作:
解析与转发:在分库分表环境下,例如执行一组插入语句,
insert into xx(p1,p2) values (a,b),(c,d)
我们要确定好这些值都插到哪些库的哪些表中。因此需要对语句中的参数提取,并通过这些参数决定,这些值都插入到哪些库或表中。
修改:由于数据最终插入到不同的库不同的表中,因此需要将插入语句拆分为多条语句。这样才能产生一致的结果。
insert into xx(p1) values (c,d)
insert into xx(p2) values (c,d)
运行:改写语句后,拆分为多条语句,需要考虑如何发送到目标库表上执行。
获取结果: 改写的情况下,会产生多条语句,获得多个结果,因此要考虑最终如何合并多个结果生成最终的一个结果。
分布式ID
分布式环境下使用ID,要考虑全局环境下不重复。因此要选择合适的分布式ID生成器。
分布式事务
分布式环境下使用事务情况就变得很复杂,当然有也有很多方案选择。例如mysql支持的XA事务、TCC两阶段提交等。但都很复杂,需要根据实际情况选择。
容量变化
使用分库分表后,当容量不足时需要考虑扩容。我们访问每个库或表时,要经过路径来选择。那么扩容后就要保证依然能路由到正确的目标上。同理缩容也是。
数据迁移
当我们开发一套新系统,提前分好库表,开发业务即可。同样存在很多老系统,这是就需要考虑如何将老系统数据迁移到库表中。
总结
学习基本概念,同时了解可能产生的问题,这样才能更好的帮助我们选择所需要的工具。
本文探讨了分库分表的概念,以及在系统读写负载增加时如何通过该策略进行扩展。介绍了分库分表的三种方式及其优势,同时也讨论了在分布式环境下可能遇到的问题,如增删改查操作、分布式ID、事务处理、动态扩容和数据迁移等。
436

被折叠的 条评论
为什么被折叠?



