栏目分类:
子分类:
返回
文库吧用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
文库吧 > IT > 软件开发 > 后端开发 > 架构设计

mysql — 分库分表常用方案以及痛点问题

架构设计 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

mysql — 分库分表常用方案以及痛点问题

为什么要进行分库分表?
当数据库的数据量过大,大到一定的程度,我们就可以进行分库分表。那么基于什么原则,什么方法进行拆分,这就是本篇所要讲的。
分库分表就是为了解决由于数据量过大而导致数据库性能降低的问题,将原来独立的数据库拆分成若干数据库组成 ,将数据大表拆分成若干数据表组成,使得单一数据库、单一数据表的数据量变小,从而达到提升数据库性能的目的。

分库分表是什么?
随着公司的业务快速发展,数据库中的数据量猛增,访问性能也变慢了,优化迫在眉睫。
分析下问题出现哪里呢?关系型数据本身就比较容易形成系统瓶颈,单机存储容量,连接数,处理能力都有限。当单表的数据量达到1000W或100G以后,由于查询维度较多,即使添加从库,优化索引,做很多操作时性能还是下降严重。

1、垂直分表

垂直分表在日常开发和设计中比较常见,通俗的说法叫做“大表拆小表”,拆分是基于关系型数据库中的“列”(字段)进行的。通常情况,某个表中的字段比较多,可以新建立一张“扩展表”,将不经常使用或者长度较大的字段拆分出去放到“扩展表”中,以商品列表为例,将访问频次低的商品描述信息单独存放在一张表中,访问频次较高的商品基本信息单独放在一张表中:

在字段很多的情况下,拆分开确实更便于开发和维护。某种意义上也能避免“跨页”的问题(MySQL、MSSQL底层都是通过“数据页”来存储的,“跨页”问题可能会造成额外的性能开销,这里不展开,感兴趣的朋友可以自行查阅相关资料进行研究)。
拆分字段的操作建议在数据库设计阶段就做好。如果是在发展过程中拆分,则需要改写以前的查询语句,会额外带来一定的成本和风险,建议谨慎。

2、垂直分库

垂直分库在“微服务”盛行的今天已经非常普及了。基本的思路就是按照业务模块来划分出不同的数据库,而不是像早期一样将所有的数据表都放到同一个数据库中。如下图:

垂直分库是指按照业务将表进行分类,分布到不同的数据库上面,每个库可以放在不同的服务器上,它的核心理念是专库专用。
它带来的提升是:

  • 解决业务层面的耦合,业务清晰
  • 能对不同业务的数据进行分级管理、维护、监控、扩展等
  • 高并发场景下,垂直分库一定程度的提升IO、数据库连接数、降低单机硬件资源的瓶颈

垂直分库通过将表按业务分类,然后分布在不同数据库,并且可以将这些数据库部署在不同服务器上,从而达到多个服务器共同分摊压力的效果,但是依然没有解决单表数据量过大的问题。
然后,很多人并没有从根本上搞清楚为什么要拆分,也没有掌握拆分的原则和技巧,只是一味的模仿大厂的做法。导致拆分后遇到很多问题(例如:跨库join,分布式事务等)。

3、水平分表

水平分表也称为横向分表,比较容易理解,就是将表中不同的数据行按照一定规律分布到不同的数据库表中(这些表保存在同一个数据库中),这样来降低单表数据量,优化查询性能。最常见的方式就是通过主键或者时间等字段进行Hash和取模后拆分。如下图所示:

水平分表是在同一个数据库内,把同一个表的数据按一定规则拆到多个表中。
它带来的提升是:

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

水平分表,能够降低单表的数据量,一定程度上可以缓解查询性能瓶颈。但本质上这些表还保存在同一个库中,所以库级别还是会有IO瓶颈。所以,一般不建议采用这种做法。

4、水平分库分表

水平分库分表与上面讲到的水平分表的思想相同,唯一不同的就是将这些拆分出来的表保存在不同的数据库中。这也是很多大型互联网公司所选择的做法。水平分库是把同一个表的数据按一定规则拆到不同的数据库中,每个库可以放在不同的服务器上。 如下图:

在HASH分布的情况下,通过如下方式决定一条记录的存储节点:

DN = Hash(row) % nofdn

它带来的提升是:

  • 解决了单库大数据,高并发的性能瓶颈。
  • 提高了系统的稳定性及可用性。

某种意义上来讲,有些系统中使用的“冷热数据分离”(将一些使用较少的历史数据迁移到其他的数据库中。而在业务功能上,通常默认只提供热点数据的查询),也是类似的实践。在高并发和海量数据的场景下,分库分表能够有效缓解单机和单库的性能瓶颈和压力,突破IO、连接数、硬件资源的瓶颈。当然,投入的硬件成本也会更高。同时,这也会带来一些复杂的技术问题和挑战(例如:跨分片的复杂查询,跨分片事务等)

比如,通过对分布列计算hash值,然后使用这个值对集群中的节点个数取模来决定记录去哪个节点。这里有一个问题,扩容后节点数会变多,数据分布的计算逻辑就会导致已经存在的数据无法正常访问。为了解决这个问题,就必须把业务停掉,把所有数据导出,扩容后重新导入,在数据量较多时,这个过程会持续几天,这对一个每天几千万笔交易的系统来说显然是不能接受的。

分库分表的难点 垂直分库带来的问题和解决思路:
  • 跨库join的问题
    在拆分之前,系统中很多列表和详情页所需的数据是可以通过sql join来完成的。而拆分后,数据库可能是分布式在不同实例和不同的主机上,join将变得非常麻烦。而且基于架构规范,性能,安全性等方面考虑,一般是禁止跨库join的。

  • 事务一致性问题
    由于分库分表把数据分布在不同的库甚至不同服务器,不可避免的带来分布式事务问题。
    比如一个请求要先请求数据库A,再请求数据库B,这两个属于同一个事务,多个库会导致分布式事务问题。

  • 跨节点关联查询
    在没有分库前,我们可以很简单的进行两表的关联查询,但是分库后,如果两个表不在同一个数据库,甚至不在同一台服务器上,无法进行关联查询。
    可以将原关联查询分为两次查询,第一个查询的结果找出关联数据id,然后根据id发起第二次请求得到关联数据,最后将获得的数据进行拼装。

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

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

  • 公共表
    实际应用场景中,参数表,数据字典表等都是数据量较小,变动少,而且属于高频联合查询的依赖表,但是其又没有必要分库分表,比如地理区域表也属于此类型。
    可以将这类表在每个数据库都保存一份,所有对公共表的更新操作都同时发送到搜的分库执行。

转载请注明:文章转载自 www.wk8.com.cn
本文地址:https://www.wk8.com.cn/it/912851.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 wk8.com.cn

ICP备案号:晋ICP备2021003244-6号