恕我直言,我怀疑你并不会“分库分表”

随着互联网的迅速发展,会导致产生海量的数据,在数据量还比较小的时候,传统的处理方式是将数据存储在关系或者非关系型数据库中,但是随着数据量逐渐增加,单个数据库的表已经很难容纳所有数据,所以业界出现了分库分表的概念 。利用分为知之的思想,完美的将数据进行了拆分,但是也带来了许多比较棘手的问题,比如引入了分布式事务、扩容等 。
数据库使用演变史我们在应用中使用数据库主要经历以下三个阶段

恕我直言,我怀疑你并不会“分库分表”

文章插图
 
  • 单库单表,应用初始阶段,此阶段由于数据量小于数据库承受阈值,对应用性能上基本没有影响 。
  • 单库分表,由于数据库中的某张表数据库量过大,对应用的性能有了一定的影响,比如查询等,对某个表会分为table_1,table_2,table_N,将一张表拆分N张小表 。注意此阶段磁盘容量充足 。但是更多的是使用的数据库的分区,分区原理和分表原理很相似,比如MySQL hash的分区
CREATE TABLE `test_user_hash` (`user_id` bigint(19) NOT NULL,`user_name` varchar(50) NOT NULL,`ext_int` int(2) NOT NULL,`ts` bigint(19) NOT NULL,PRIMARY KEY (`user_id`,`ext_int`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;//Mysql 分区ALTER TABLE `test_user_hash` PARTITION BY HASH(ext_int) PARTITIONS 3 ;复制代码mysql数据库中存储形式,由于上述是按3hash求余,所以会分三个存储文件
恕我直言,我怀疑你并不会“分库分表”

文章插图
 
  • 分库分表,上述两种都无法解决时,出现分库分表方案,即将单数据库数据分散在多个数据库中 。
什么情况下需要分库分表? 原则上能不分库尽量不分库,无法避免时或者已经有趋势显示需要分库分表,则使用分库分表 。
  • 数据库的吞吐量达到瓶颈,需要扩多个数据库实例来提高;
  • 数据表的数据达到一定的量级,对应用查询等性能有了明显的影响,可以通过分库分表来提升性能,有资料显示Mysql数据库单表数据量超过5000w后对查询性能有影响
  • 为了避免后期复杂的扩容,提前根据数据增长的趋势预估N年后的数据量 count,count / 单库容量 =所需 数据库实例,属于提前规划,防范于未然 。
常见拆分方案常见拆分方案有两种:垂直拆分和水平拆分,分库分表则是一种对数据库拆分的常见解决方案 。
  • 垂直拆分
垂直拆分是根据业务特点,将某些有关系的表集中存储在的某个DB中,并且这些表的数据量一般不会过大 。比如电商系统中有用户模块、订单模块
恕我直言,我怀疑你并不会“分库分表”

文章插图
 
  • 水平拆分
每个db中存在相同的表结构,根据一定的规则将数据分散在多个DB中
恕我直言,我怀疑你并不会“分库分表”

文章插图
 
分库分表实现方案主要有以下三种实现方案
  • 客户端分片
  • 代理实现分片
  • 分布式数据库
客户端分片客户端分片一般有两种实现方式,一种是应用层直接实现,应用层内包含分片逻辑以及分片算法等,与业务代码紧耦合
恕我直言,我怀疑你并不会“分库分表”

文章插图
 
应用层实现了所有逻辑,业务人员需要参与 。
另外一种是实现标准的JDBC协议,对应用提供包装过的JDBC,对应用使用无感,实现逻辑作为jar,嵌入在应用中,应用可以灵活的切换
恕我直言,我怀疑你并不会“分库分表”

文章插图
 
这种方式是实现标准的JDBC接口,对应用使用原生JDBC无影响,二者遵循统一规范,相比于第一种方式好处是与业务代码解耦 。提高灵活性 。
代理分片代理方式实现的方式是在应用和数据库中间增加代理层,独立部署,代理充当数据的角色,对应用来说使用代理就等价于数据库,原则上使用代理与直接使用数据库是无区别,但是代理毕竟不是真实的数据库,代理层只是解决如何充分的利用数据库资源,代理层实现了所有分库分表逻辑,包括分片规则等,业务人员无需关注,可以将更多的时间投入到业务实现逻辑中 。
恕我直言,我怀疑你并不会“分库分表”

文章插图
 
一般会在代理层外添加一层负载 。
这种方式可以让业务人员更专注于业务,但是复杂度相比第一种要高很多,增加了通讯链路,涉及到协议转换,所以会对性能相比于第一种方案有明显的损耗,同时对人员的要求也比较高,需要技术大牛来支持,否则一旦出现问题很难处理 。比较耳熟的有Mycat,由于本人基于Mycat做过深度二次开发,对源码有一定的了解,缺陷真的很 。。。。,希望使用者仔细斟酌,题外话o( ̄︶ ̄)o


推荐阅读