随着互联网的迅速发展,会导致产生海量的数据,在数据量还比较小的时候,传统的处理方式是将数据存储在关系或者非关系型数据库中,但是随着数据量逐渐增加,单个数据库的表已经很难容纳所有数据,所以业界出现了分库分表的概念。利用分为知之的思想,完美的将数据进行了拆分,但是也带来了许多比较棘手的问题,比如引入了分布式事务、扩容等。
我们在应用中使用数据库主要经历以下三个阶段
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求余,所以会分三个存储文件
原则上能不分库尽量不分库,无法避免时或者已经有趋势显示需要分库分表,则使用分库分表。
常见拆分方案有两种:垂直拆分和水平拆分,分库分表则是一种对数据库拆分的常见解决方案。
垂直拆分是根据业务特点,将某些有关系的表集中存储在的某个DB中,并且这些表的数据量一般不会过大。比如电商系统中有用户模块、订单模块
每个db中存在相同的表结构,根据一定的规则将数据分散在多个DB中
主要有以下三种实现方案
客户端分片一般有两种实现方式,一种是应用层直接实现,应用层内包含分片逻辑以及分片算法等,与业务代码紧耦合
应用层实现了所有逻辑,业务人员需要参与。
另外一种是实现标准的JDBC协议,对应用提供包装过的JDBC,对应用使用无感,实现逻辑作为jar,嵌入在应用中,应用可以灵活的切换
这种方式是实现标准的JDBC接口,对应用使用原生JDBC无影响,二者遵循统一规范,相比于第一种方式好处是与业务代码解耦。提高灵活性。
代理方式实现的方式是在应用和数据库中间增加代理层,独立部署,代理充当数据的角色,对应用来说使用代理就等价于数据库,原则上使用代理与直接使用数据库是无区别,但是代理毕竟不是真实的数据库,代理层只是解决如何充分的利用数据库资源,代理层实现了所有分库分表逻辑,包括分片规则等,业务人员无需关注,可以将更多的时间投入到业务实现逻辑中。
一般会在代理层外添加一层负载。
这种方式可以让业务人员更专注于业务,但是复杂度相比第一种要高很多,增加了通讯链路,涉及到协议转换,所以会对性能相比于第一种方案有明显的损耗,同时对人员的要求也比较高,需要技术大牛来支持,否则一旦出现问题很难处理。比较耳熟的有Mycat,由于本人基于Mycat做过深度二次开发,对源码有一定的了解,缺陷真的很。。。。,希望使用者仔细斟酌,题外话o( ̄︶ ̄)o
耳熟的有TiDB,对外提供可伸缩的架构体系,提供一定的分布式事务,可伸缩和分布式事务在内部实现中包装,对用者无需直接控制这些特性,比如TiDB提供了JDBC接口,应用层使用TiDB和直连MySQL数据库使用方式没什么区别
后续文章会分析为了解决分库分表带来的问题,业界中有哪些比较成熟的解决方案,敬请期待...
作者:掘金小勇士
链接:
https://juejin.im/post/5edb0d1c6fb9a047ed240e36