九、分库分表

九、分库分表

    1、分库分表背景

        分库分表就是为了解决由于数据量过大而导致数据库性能降低的问题,将原来独立的数据库拆分成若干数据库组成,将数据大表拆分成若干数据表组成,使得单一数据库、单一数据表的数据量变小,从而达到提升数据库性能的目的。

        分库分表包括分库和分表两个部分,在生产中通常包括:垂直分库、水平分库、垂直分表、水平分表四种方式。

    2、垂直分表

        例:商品信息表拆分为:商品基础信息表(产地、名称、规格、价格等)、商品描述信息表(描述、备注等)。商品基础信息表存放的字段都是操作频率较高的字段,商品描述信息表存放的字段都是操作频率较低的字段。

        (1)、定义:将一个表按照字段分成多表,每个表存储其中一部分字段。

        (2)、优点

            ①、避免了IO争抢并减少锁表的几率,查看描述信息的用户与查看商品基础信息的用户互不影响。

            ②、充分发挥热门数据的操作效率,商品基础信息操作的高效率不会被商品描述信息的低效率所拖累。

            注:大字段IO效率低的原因:

                a、由于数据量本身大,需要更长的读取时间;

                b、跨页,页是数据库存储单位,很多查找及定位操作都是以页为单位,单页内的数据行越多,数据的整体性能越好,而大字段占用空间大,单页存储行数少,因为IO效率低。

                c、数据库以行为单位将数据加载到内存中,这样表中字段长度较短且访问频率较高,内存能加载更多数据,命中率更高,减少了磁盘的IO,从而提升了数据库性能。

        (3)、拆分原则

            ①、将表字段分开,热门字段、冷门字段放在不同的表中。

            ②、把text、blob等大字段拆分出来,放到附表中。

            ③、经常组合查询的列放在一张表中。

    3、垂直分库

        通过垂直分表性能得到一定程度提升,但是还没有达到要求,并且磁盘空间也有限。因为数据还是始终限制在一台服务器,库内垂直分表只解决了单一表数据量过大的问题,但是没有将表分不到不同的服务器上,因此每个表还是竞争同一个物理机的CPU、内存、网络IO、磁盘。

        例:把Service相关信息整理到Service库,把医嘱相关信息整理到医嘱库。医嘱库放医嘱表和费用表,因为医嘱表和费用表耦合度较高,因此被放在一起。

        (1)、定义:按照业务将表进行分类,分不到不同的数据库上面,每个库也可以放在不同的服务器上,它的核心理念是专库专用。

        (2)、优点

            ①、解决业务层面的耦合,使业务更加清晰。

            ②、能对不同的业务数据进行分级管理、维护、监控、扩展等。

            ③、高并发场景下,垂直分库一定程度的提升IO、数据库连接数、降低单机硬件资源的瓶颈。

    4、水平分库

        经过垂直分库后,数据库性能问题得到一定程度的解决,但是随着业务量的增长,切分后数据量行数巨大。由于单库存储数据已经超出预估,存在单库读写、存储性能瓶颈,单台服务器无法支撑,并且从业务角度分析已经无法再次垂直分库,就需要进行水平分库。

        (1)、定义:水平分库是把同一个表的数据按一定的规则拆到不同的数据库中,每个库可以放在不同的服务器上。

        (2)、优点

            ①、解决了单库大数据,高并发的性能瓶颈。

            ②、提高了系统的稳定性及可用性。稳定性体现在IO冲突减少,锁定减少,可用性是指某个数据库出问题,部分可用。

        (3)、缺点

            由于同一个表被分配在不同的数据库,需要额外进行数据库的路由工作,因此大大提升了系统复杂度。

        (4)、操作示例

            ①、先分析这条数据所属ID

            ②、如果ID为双数,将操作映射到A库;如果ID为单数,将操作映射到B库。

    5、水平分表

        (1)、定义:在同一个数据库内,把同一个表的数据按一定规则拆到多个表中。水平分表是对数据行的拆分,不影响表结构。

        (2)、优点

            ①、优化单一表数据量过大而产生的性能问题。

            ②、避免IO争抢并减少锁表的几率。解决了单一表数据量过大的问题,分出来的小标中只包含一部分数据,从而使得单个表的数据量变小,提高检索性能。

    6、分库分表总结

        (1)、垂直分表

            可以把一个宽表的字段,按照访问的频次、是否是大字段等原则拆分为多个表,这样既能使业务清洗,还能提升部分性能。拆分后,尽量从业务角度避免联查,否则性能方面将得不偿失。

        (2)、垂直分库

            可以把多个表按业务耦合松紧归类,分别放在不同的库,这些库可以分布在不同的服务器,从而使访问压力呗多服务器负载,大大提升性能。同时能提高整体架构的业务清晰度,不同的业务库可根据自身情况定制优化方案,但是它需要解决跨库带来的所有复杂的问题。

        (3)、水平分库

            可以把一个表的数据按数据行分到不同的库,每个库只有这个表的部分数据。这些库可以分布在不同的服务器,从而是访问压力被多服务器负载,大大提升性能。它不仅需要解决跨库带来的所有复杂问题,还要解决数据路由的问题。

        (4)、水平分表

            可以把一个表的数据按数据行分到多个同一数据库的多张表中,每个表只有这个表的部分数据,这样做能小幅提升性能,它仅仅作为水平分库的一个补充优化。

        (5)、对比

            ①、水平分库是在库的层面对数据行进行拆分,不影响表结构。

            ②、垂直分库是对表根据业务进行分类拆分。

            ③、水平分表是在表的层面对数据行进行拆分,不影响表结构。

            ④、垂直分表是对表字段根据使用频率进行拆分,改变表结构。 

            一般来说,在系统设计阶段就应该根据业务耦合松紧来确定垂直分库、垂直分表方案。在数据量及访问压力不是特别大的情况,首先考虑缓存、读写分离、索引技术等方案。若数据量极大,且持续增长,再考虑水平分库、水平分表方案。

    7、分库分表的问题

        分库分表能有效的缓解了单机和单库带来的性能瓶颈和压力,突破网络IO、硬件资源、连接数瓶颈,同时也带来了一些问题。

        (1)、事务一致性问题

            由于分库分表把数据分布在不同库甚至不同服务器,不可避免会带来分布式事务问题。这个问题可以通过其他中间件解决,比如Seata。

        (2)、 跨节点关联查询

            在没有分库之前,我们检索商品可以通过正常SQL进行表关联查询,但是垂直分库后,有的表不在同一个数据库,甚至是不在同一台服务器,无法进行关联查询。

            可以将原关联查询分为两次查询,第一次查询的结果集中找出关联数据ID,然后根据ID发起第二次请求得到关联数据,最后将获得的数据进行拼装。

        (3)、跨节点分页、排序、函数

            跨节点多库进行查询时,limit分页、order by排序等问题,就变得比较复杂了。需要现在不同的分片节点中将数据进行排序并返回,然后将不同分片返回的结果集进行汇总和再次排序。

            由于表数据分布在各个数据库可能是随机的,如果是取第N页,需要将所有节点前N页数据都取出来合并,再进行整体的排序,操作效率可想而知。所以请求也属越大,系统的性能越差。

            在使用max、min、sum、count之类的函数进行计算的时候,与排序分页同理。需要现在每个分片上执行相应的函数,然后将各个分片的结果集进行汇总和再次计算,最终将结果返回。

        (4)、主键避重

            在分库分表环境中,由于表中数据同时存在不同数据库中,主键值平时使用的自增长将不再适用。某个分区数据库生成的ID无法保证全局唯一。因为需要单独设计全局主键,以避免主键重复问题。

        (5)、 公共表

            实际的应用场景中,参数表、数据字典表等都是数据量较小,变动少,而且属于高频联合查询的依赖表。可以将这类表在每个数据库都保存一份,所有对公共表的更新操作都同时发送到所有分库执行。

            由于分库分表之后,数据被分散在不同的数据库、服务器。因此,对数据库的操作也就是无法通过常规方式完成,并且它还带来了一些列的问题。这些问题需要通过一些中间件来解决。例:Sharding—JDBC。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值