MySQL分库和表架构,问题总结
公司最近在处理服务分离和数据切分的问题,因为一张包表数据量太大,每天还在60W的量增长下运行。之前学过数据库的子数据库和子表,也看了几篇博文,但只知道一个模糊的概念,现在想起来,一切都是模糊的。
花了一个下午的时间看数据库分表,看了很多文章。现在我将它们进行总结和“摘录”。 (不过很期待后面的实际操作)我会从以下几个方面入手:
第1部分:我们在实际的Web开发过程中遇到的问题。
第二部分:垂直和水平的分割方法有哪些不同、差异和适用方面。
第三部分:目前市场上的一些开源产品和技术以及它们的优缺点是什么。
第四部分:可能是最重要的,为什么不建议水平拆分数据库和表! ?这可以让您在规划的早期阶段谨慎处理,避免分割带来的问题。
术语解释
Library:数据库;表:表;分库分表:分片
数据库架构的发展
最初我们只使用单机数据库,后来遇到越来越多的问题需求,我们将数据库的写操作和读操作分开,使用多副本从库(Slaver Replication)负责读取,而使用主数据库(Master)负责写入。从库与主库同步更新数据,保持数据一致。从架构上来说,这就是主从数据库同步。从库可以水平扩展,因此多个读请求不是问题。
但是当用户级别提高,写请求越来越多时,我们该怎么办?增加一个master并不能解决问题,因为数据必须一致,而且写操作需要两个master之间同步,相当于重复,比较复杂。
此时就需要使用分片来拆分写操作。
分库分表前的问题
任何问题都太大或太小。我们这里面临的问题是数据量太大。
用户请求量太大
因为一台TPS服务器,内存和IO有限。解决方案:将请求分发到多台服务器;事实上,用户请求和SQL查询执行本质上是一样的。两者都需要资源,但用户请求还要经过网关、路由、http服务器等。
一个数据库太大
一个数据库处理能力有限;单个数据库所在服务器磁盘空间不足;解决一个数据库运行的IO瓶颈:拆分成多个较小的数据库
一张表太大
CRUD是个问题;索引扩展、查询超时解决方案:拆分为多个数据集和更小的表。
分库分表方式
一般为垂直分片和水平分片。这就是结果集中描述的分割方法,是物理空间上的分割。我们从面临的问题入手解决,阐述一下:第一,用户请求量太大,所以我们囤机器来处理(这不是本文的主题)。
那么单个数据库就太大了。此时我们需要判断是因为表太多,还是因为一张表的数据太多,导致数据太多。如果表很多,数据很多,可以采用垂直切分的方式,按照业务拆分到不同的库中。
如果一张表的数据量太大,就需要采用水平切分,即将表数据按照一定的规则分为多个表,甚至多个数据库上的多个表。 数据库和表分区的顺序应该是先垂直后水平。 因为垂直划分更容易,也更符合我们解决现实问题的方式。
垂直分区
- 垂直表分区就是根据列字段“将大表拆分成小表”。一般情况下,一张表的字段较多,而那些不常用、数据量大且较长的(如文本类型字段)则被划分为“扩展表”。一般针对数百列的大表,同时也避免了导致查询数据过多的“页间问题”。
- 垂直分库 垂直分库重点对系统中的各个业务进行划分,如用户数据库、产品数据库、订单数据库等。拆分后应该放在多台服务器上,而不是一台服务器上。为什么?我们想象一下,一个购物网站对外提供服务,对用户、产品、订单等都有CRUD。在拆分之前,一切都落入单个数据库中,这会成为数据库处理单个数据库的能力的瓶颈。数据库垂直分区后,如果仍然位于数据库服务器上,随着用户数量的增加,一台数据库的计算能力将成为瓶颈,一台服务器的磁盘空间、内存、TPS等会很紧。因此,我们需要将其拆分为多台服务器,这样上述问题就得到解决,以后就不会再面临单机资源问题了。
数据库业务级别的划分类似于服务的“管理”和“降级”机制。还可以独立管理、维护、监控、扩展等各个企业的数据。数据库往往最容易成为应用系统的瓶颈,而数据库本身是“有状态的”。相比Web和应用服务器,实现“水平扩展”难度更大。数据库连接资源宝贵,单台计算机的处理能力有限。在高并发场景下,垂直分库可以在一定程度上打破单机IO、连接数和硬件资源的瓶颈。
水平分区
- 水平表分区针对一张数据量较大的表(如订单表),按照一定的规则(RANGE、HASH模块等)将其划分为多个表。但这些表仍然在同一个数据库中,因此数据库级别的数据库操作仍然存在IO瓶颈。不建议。
- 库分表水平分片,将一张表的数据划分到多台服务器上。每个服务器都有相应的库和表,但表中数据的集合有所不同。水平分库分表可以有效缓解单机、单库的性能瓶颈和压力,突破IO、连接数、硬件资源等瓶颈。
- 水平分库分表规则
- RANGE 一张表为 0 到 10 000,一张表为 10,001 到 20,000;
- HASH有商城模型。一般情况下,将用户和订单作为主表,然后作为附件,以避免跨库事务等问题。获取用户ID,然后取出hash模块,分发到不同的数据库。
- 华东、华南、华北等地理区域划分业务,七牛云应该也是这样。
- 时间分割是指将6个月前甚至一年前的数据放到另一个表中,因为随着时间的推移,查询这些表中数据的概率会降低,所以不需要将其与“热门数据”关联起来,这也是一个“冷热数据分离”的问题。
分库分表后的问题
事务支持
分库分表后成为分布式事务。如果依赖数据库本身的分布式事务管理特性来执行事务,那么你会为性能付出高昂的代价;如果应用程序辅助驱动,形成程序逻辑事务,也会造成程序开销。 ?数据库中的表不能与不同表粒度的表进行联接。因此,一项查询可以完成的业务可能需要多次查询才能完成。粗略的解决方案: 全局表:基础数据,所有库都有一份。字段冗余:这样某些字段就不需要通过join来查询。系统层构建:单独查询所有内容,然后构建,比较复杂。
分库分表解决方案产品
市面上分库分表的中间件比较多,包括基于代理方式的如MySQL Proxy、Amoeba,基于Hibernate框架的有Hibernate Shards等基于jdbc的包括当当sharding-jdbc,一个基于mybatis的Maven插件,类似于蘑菇街的蘑菇街TSharding,Cobar Client,通过重写Spring中的ibatis模板类。
还有一些大公司的开源产品:
版权声明
本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。