分库分表要注意选型和流程

本文探讨了数据库分库分表在MySQL和Java项目中的五个层次:编码层、框架层、驱动层、代理层和实现层。重点比较了驱动层和代理层的优缺点,推荐关注MyCat和ShardingJDBC,并强调了数据均衡、避免深分页和特殊函数等问题。
摘要由CSDN通过智能技术生成

数据库到了需要分库分表的时候,那么公司的数据也是发展到了一定的量了,需要考虑高可用了。
但是分库分表需要考虑哪些因素,拆分过程是复杂的,提前计划,不要等真正开工,各种意外的工作接踵而至,以至失控。

本文介绍数据库中间件的广度而不是深度。
切入层次,一下范围限定在mysql和java中,我们先说下分库分表切入的层次

在这里插入图片描述

分库分表切入的层次

1.编码层
在同一个项目中创建多个数据源,采用if else的方式,直接根据条件在代码中路由。Spring中有动态切换数据源的抽象类,具体参见
AbstractRoutingDataSource。
如果项目不是很庞大,使用这种方式能够快速的进行分库。但缺点也是显而易见的,需要编写大量的代码,照顾到每个分支。当涉及跨库查询、聚合,需要循环计算结果并合并的场景,工作量巨大。
如果项目裂变,此类代码大多不能共用,大多通过拷贝共享。长此以往,码将不码。

2.框架层
这种情况适合公司ORM框架统一的情况,但在很多情况下不太现实。主要是修改或增强现有ORM框架的功能,在SQL中增加一些自定义原语或者hint来实现。通过实现一些拦截器(比如Mybatis的Interceptor接口),增加一些自定义解析来控制数据的流向,效果虽然较好,但会改变一些现有的编程经验。
很多情况要修改框架源码,不推荐。

3.驱动层
基于在编码层和框架层切入的各种缺点,真正的数据库中间件起码要从驱动层开始。什么意思呢?其实就是重新编写了一个JDBC的驱动,在内存中维护一个路由列表,然后将请求转发到真正的数据库连接中。
像TDDL、ShardingJDBC等,都是在此层切入。
也是直接在驱动上进行修改。
请求流向一般是这样的:

在这里插入图片描述
4.代理层
代理层的数据库中间件,将自己伪装成一个数据库,接受业务端的链接。然后负载业务的请求,解析或转发到真正的数据库中。
像Mysql Router, Mycat都是在此层切入。

在这里插入图片描述
5.实现层
SQL特殊版本支持,如Mysql cluster本身就支持各种特性,mariadb galera cluster支持对等双主,Greenplum支持分片等。
需要换存储,一般是解决方案,就不在讨论之列了。

驱动层和代理层对比

通过以上层次对比,很明显,我们选择和开发中间件,就集中在驱动层和代理层。这两层可以对数据库链接进行更细致的管理和更强的控制,但他们的区别也是明显的。

驱动层中间件仅支持java一种开发语言,但是支持的后段数据库有很多,如MySQL、PostgreSQL、SQLServer、Oracle,如果开发语言固定,后段数据源类型丰富,推荐使用此方案。
在这里插入图片描述
1.占用较多的数据库连接
驱动层中间件要维护很多数据库连接。比如一个分了10个 库 的表,每个java中的Connection要维护10个数据库连接。如果项目过多,则会出现连接爆炸(我们算一下,如果每个项目6个实例,连接池中minIdle等于5,3个项目的连接总数是 1065*3 = 900 个)。像Postgres这种每个连接对应一个进程的数据库,压力会很大。
数据聚合在业务实例执行
数据聚合,比如count sum等,是通过多次查询,然后在业务实例的内存中进行聚合。
路由表存在于业务方实例内存中,通过轮询或者被动通知的途径更新路由表即可。

2.集中式管理
所有集群的配置管理都集中在一个地方,运维负担小,DBA即可完成相关操作。
典型配置:
在这里插入图片描述
代理层特点:
异构支持,db支持。
支持多种开发语言:JAVA,GO,python
支持多种db:MySQL、SQL Server、Oracle、DB2、PostgreSQL
在这里插入图片描述
运维负担大
代理层需要维护数据库连接数量有限(MySQL Router那种粘性连接除外)。但作为一个独立的服务,既要考虑单独部署,又要考虑高可用,会增加很多额外节点,更别提用了影子节点的公司了。
另外,代理层是请求唯一的入口,稳定性要求极高,一旦有高耗内存的聚合查询把节点搞崩溃了,都是灾难性的事故。

在这里插入图片描述

共同点
篇幅有限,不做过多讨论。访问各中间件宣传页面,能够看到长长的Feature列表,也就是白名单;也能看到长长的限制列表,也就是黑名单。限定了你怎么玩,在增强了分布式能力后,分库分表本身就是一个阉割的数据库。
使用限制
确保数据均衡 拆分数据库的数据尽量均匀,比如按省份分user库不均匀,按userid取模会比较均匀
不用深分页 不带切分键的深分页,会取出所有库所取页数之前的所有数据在内存排序计算。容易造成内存溢出。
减少子查询 子查询会造成SQL解析紊乱,解析错误的情况,尽量减少SQL的子查询。
事务最小原则 尽量缩小单机事务涉及的库范围,即尽可能减少夸库操作,将同类操作的库/表分在一起
数据均衡原则 拆分数据库的数据尽量均匀,比如按省份分user库不均匀,按userid取模会比较均匀
特殊函数 distinct、having、union、in、or等,一般不被支持。或者被支持,使用之后会增加风险,需要改造。
产品
建议聚焦在MyCat和ShardingJDBC上。另外,还有大量其他的中间件,不熟悉建议不要妄动。
数据库中间件不好维护,你会发现大量半死不活的项目。

参考:https://zhuanlan.zhihu.com/p/93952564

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值