数据库的架构演进

    关系型数据库本身比较容易成为系统瓶颈,单机存储容量、连接数、处理能力都有限。当单表的数据量增加以后,由于查询维度较多,即升级硬件、升级网络、优化SQL索引,做很多操作时性能仍下降严重。此时需要考虑调整数据库的架构了。

1、主从复制,读写分离

2、分区

3、分表

4、常见分区分表的规则策略

5、分库

6、分库/分表后面临的问题

7、什么时候考虑切分


1、主从复制,读写分离

    MySQL的主从复制解决了数据库的读写分离,并很好的提升了读的性能。

           

    

    但是,主从复制也带来其他一系列性能瓶颈问题:写入无法扩展、写入无法缓存、复制延时、锁表率上升、表变大,缓存率下降等,此时需要考虑进行数据库分区了。

2、分区

    分区就是把一张表的数据分成N个区块,在逻辑上看最终只是一张表,但底层是由N个物理区块组成的。数据分区是一种物理数据库的设计技术,它的目的是为了在特定的SQL操作中减少数据读写的总量以缩减响应时间。分区并不是生成新的数据表,而是将表的数据均衡分摊到不同的硬盘,系统或是不同服务器存储介子中,实际上还是一张表。另外,分区可以做到将表的数据均衡到不同的地方,提高数据检索的效率,降低数据库的频繁IO压力值。

1.1 什么时候考虑分区

  • 一张表的查询速度已经慢到影响使用

  • sql经过优化

  • 已经添加主从复制

  • 数据量大

  • 表中的数据是分段的

  • 对数据的操作往往只涉及一部分数据,而不是所有的数据

1.2 水平分区

    这种形式分区是对表的行进行分区,通过这样的方式不同分组里面的物理列分割的数据集得以组合,从而进行个体分割(单分区)或集体分割(1个或多个分区)。所有在表中定义的列在每个数据集中都能找到,所以表的特性依然得以保持。

1.3 垂直分区

    这种分区方式一般来说是通过对表的垂直划分来减少目标表的宽度,使某些特定的列被划分到特定的分区,每个分区都包含了其中的列所对应的行。

3、分表

    分表就是把一张表按一定的规则分解成N个具有独立存储空间的实体表。系统读写时需要根据定义好的规则得到对应的字表明,然后操作它。

3.1 垂直分表

    垂直分表是基于数据库中的"列"进行,某个表字段较多,可以新建一张扩展表,将不经常用或字段长度较大的字段拆分出去到扩展表中。在字段很多的情况下(例 如一个大表有100多个字段),通过"大表拆小表",更便于开发与维护,也能避免跨页问题,MySQL底层是通过数据页存储的,一条记录占用空间过大会导 致跨页,造成额外的性能开销。另外数据库以行为单位将数据加载到内存中,这样表中字段长度较短且访问频率较高,内存能加载更多的数据,命中率更高,减少了 磁盘IO,从而提升了数据库性能。    

3.2 水平分表

    当一个应用难以再细粒度的垂直切分,或切分后数据量行数巨大,存在单库读写、存储性能瓶颈,这时候就需要进行水平切分了。水平分表根据表内数据内在的逻辑关系,将同一个表按不同的条件分散到多个多个表中,每个表中只包含一部分数据,从而使得单个表的数据量变小。

4、常见分区分表的规则策略

  • Range(范围)
  • Hash(哈希)
  • 按照时间拆分
  • Hash之后按照分表个数取模
  • 在认证库中保存数据库配置,就是建立一个DB,这个DB单独保存user_id到DB的映射关系

5、分库

    随着数据量增加也许单台DB的存储空间不够,随着查询量的增加单台数据库服务器已经没办法支撑。这个时候可以再对数据库进行水平区分。

4.1 垂直分库

    垂直分库就是根据业务耦合性,将关联度低的不同表存储在不同的数据库。做法与大系统拆分为多个小系统类似,按业务分类进行独立划分。与"微服务治理"的做法相似,每个微服务使用单独的一个数据库。

4.2 分库分表

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

6、分库/分表后面临的问题

(1)事务的支持,分库分表,就变成了分布式事务,分布式事务处理复杂;

(2)join时跨库,跨表的问题,只能通过接口聚合方式解决,提升了开发的复杂度;

(3)分库分表,读写分离使用了分布式,分布式为了保证强一致性,必然带来延迟,导致性能降低,系统的复杂度变高;

7、什么时候考虑切分

(1)能不切分尽量不要切分

    并不是所有表都需要进行切分,主要还是看数据的增长速度。切分后会在某种程度上提升业务的复杂度,数据库除了承载数据的存储和查询外,协助业务更好的实现需求也是其重要工作之一。不到万不得已不用轻易使用分库分表这个大招,避免"过度设计"和"过早优化"。分库分表之前,不要为分而分,先尽力去做力所能及的事情,例如:升级硬件、升级网络、读写分离、索引优化等等。当数据量达到单表的瓶颈时候,再考虑分库分表。

(2)数据量过大,正常运维影响业务访问

    这里说的运维,指:

  • 对数据库备份,如果单表太大,备份时需要大量的磁盘IO和网络IO。例如1T的数据,网络传输占50MB时候,需要20000秒才能传输完毕,整个过程的风险都是比较高的
  • 对一个很大的表进行DDL修改时,MySQL会锁住全表,这个时间会很长,这段时间业务不能访问此表,影响很大。如果使用pt- online-schema-change,使用过程中会创建触发器和影子表,也需要很长的时间。在此操作过程中,都算为风险时间。将数据表拆分,总量减 少,有助于降低这个风险。
  • 大表会经常访问与更新,就更有可能出现锁等待。将数据切分,用空间换时间,变相降低访问压力

(3)随着业务发展,需要对某些字段垂直拆分

(4)数据量快速增长

    随着业务的快速发展,单表中的数据量会持续增长,当性能接近瓶颈时,就需要考虑水平切分,做分库分表了。此时一定要选择合适的切分规则,提前预估好数据容量。

(5)安全性和可用性

    鸡蛋不要放在一个篮子里。在业务层面上垂直切分,将不相关的业务的数据库分隔,因为每个业务的数据量、访问量都不同,不能因为一个业务把数据库搞挂而牵连到其他业务。利用水平切分,当一个数据库出现问题时,不会影响到100%的用户,每个库只承担业务的一部分数据,这样整体的可用性就能提高。

猜你喜欢

转载自blog.csdn.net/MOU_IT/article/details/113828140