分库分表

Posted 平平无奇一码农

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了分库分表相关的知识,希望对你有一定的参考价值。

关系型数据库的分库分表方案。



关系型数据库

关系型数据库,是指采用了关系模型来组织数据的数据库,其以行和列的形式存储数据,以便于用户理解,关系型数据库这一系列的行和列被称为表,一组表组成了数据库。用户通过查询来检索数据库中的数据,而查询是一个用于限定数据库中某些区域的执行代码。关系模型可以简单理解为二维表格模型,而一个关系型数据库就是由二维表及其之间的关系组成的一个数据组织。

百度百科

关系型数据库的特点:结构化存储,数据表以表格形式持久化,每个数据表必须定义字段方可存储数据;支持联表操作;事务强调ACID,要求强一致性。结构化存储保证数据的可靠性和稳定,但是修改表结构十分困难。支持联表,强事务性,强一致性的特点限制关系型数据库只适合单机存储架构,为了保障强一致性,降低读写性能来保证,尤其在高并发读写时性能下降明显。

    

关系型数据库切分方式

传统关系型数据库是单机存储系统,单机的存储容量、连接数、处理能力都有限,关系型数据库本身容易形成性能瓶颈。当单表数据量达到1000W或100G(可能不太客观),即便添加从库、优化索引,很多操作性能仍然下降严重。此时就要考虑对其进行切分了,切分的目的就在于减少单机的负担,缩短查询时间。


数据库分布式的内容就是数据切分、数据定位、数据整合

数据切分就是将数据分散存储,降低单点压力。数据切分根据其切分类型,可以分为两种方式:垂直(纵向)切分和水平(横向)切分


 垂直切分 

垂直切分分为垂直分库垂直分表

垂直分库的做法类似微服务治理,将数据表根据业务关联切分到不同数据库,缓解单机压力。


垂直分表是基于列来拆分的,思想是“大表拆小表”,创建扩展表来存储不常用字段或大字段。如:机构表可拆分为机构基础信息表和机构详细信息表,甚至可以根据业务实际需求扩展更多机构扩展表。提供分表,可以将热点列集中,减少跨页(数据库存储数据是以数据页为单位的),这样内存就能一次加载更多有效数据,减少磁盘IO,从而提示数据库性能。


优点:

    降低业务耦合,方便业务扩展,缓解单机压力。

缺点:

    分布式事务处理复杂。

    未解决数据量大带来的性能问题,读写压力依旧很大(需要水平切分)。


 水平切分 

当一个应用难以再细粒度的垂直切分,或切分后数据量行数巨大,存在单库读写、存储性能瓶颈,这时候就需要进行水平切分了。


水平切分分为库内分表分库分表,是根据表内数据内在的逻辑关系,将同一个表按不同的条件分散到多个数据表或多个数据库中,每个数据表中只包含一部分数据,数据表之间的数据各不相同,从而使得单个表的数据量变小,达到分布式的效果。


库内分表只解决了单一表数据量过大的问题,但没有将表分布到不同机器的库上,因此对于减轻单机数据库来说效果有限,客户端仍然竞争同一个物理机的CPU、内存、网络IO,水平切分最好通过分库分表来解决。


优点:

    缓解单机压力。

    业务改动较小。

缺点:

    跨库的事务一致性难以保证。

    跨库join查询、排序、分页等操作性能较差。

    数据扩展难度和维护量较大。


补充:数据分片常用规则

  • 根据数值范围

        优点:简单,易扩展,能有效规避跨分片查询。

        缺点:容易形成热点数据。

  • 根据数值取模

        优点:数据均匀分布,压力分担,避免热点数据。

        缺点:后期不易扩展,跨分片查询。


什么时候考虑切分

首先,能不切分则不切分。切分会增加业务的复杂度,不到万不得已不要轻易进行分库分表,避免"过度设计"和"过早优化"。切分之前尽可能做其他方面的优化,如:升级硬件、升级网络、读写分离、索引优化等。当数据量达到单表的瓶颈时候,再考虑分库分表。

  • 增加业务间的安全性和可用性,对业务进行垂直切分,不同业务的数据表放到不同数据库内。

  • 采取必要的热点数据和非热点数据的垂直分表。

  • 数据量过大或者数据增长迅速接近单机性能瓶颈则考虑水平切分。水平切分要考虑适当的分片规则,尽可能避免跨分片join、排序、分页等操作。


分库分表带来的问题

  • 分布式ID

    同一数据表的不同分片应该保证主键的唯一性,即分布式ID,详细内容移步:

  • 分布式事务

    分布式事务的常见解决方案是两阶段提交,将事务分为两个阶段:prepare 和 commit。如图:

    两阶段提交协议在准备阶段锁定资源,是一个重量级的操作,并能保证强一致性,而且存在阻塞、单点故障、脑裂等问题。三阶段提交是分布式事务的另一解决方案,是在两阶段基础上通过超时机制解决了阻塞问题,并增加了询问阶段。

  • 跨分片join

    最常见的方案是业务聚合,当然也可以通过字段冗余、全局表等方式避免join。

  • 跨分片函数、排序、分页等操作

  • 跨分片函数需要多不同分片函数结果进行汇总计算。

    最复杂的是跨分片排序和分页。如果是库内分表可以通过UNION聚合处理,如果分库分表则显得更复杂,如LIMIT 10000,10,每个分片都需要加载10010条数据到内存中排序,甚至可能出现内存装载不下的情况。

  • 扩容问题和数据迁移

    分片规则如果是数值范围则添加节点即可,如果是数值取模则需要对旧的数据重新取模,迁移。


结束

关于分布式事务将在分布式存储系统中做详细介绍。

以上是关于分库分表的主要内容,如果未能解决你的问题,请参考以下文章

分库分表 ---SpringBoot + ShardingSphere 实现分表

.netcore分库分表的问题

分库分表--- SpringBoot+ShardingSphere实现分表+ 读写分离

分库分表最佳实践

[精选]彻底搞清分库分表(垂直分库,垂直分表,水平分库,水平分表)

分库分表 ---SpringBoot + ShardingSphere 实现分表