技术文章第一时间送达!
数据库分库分表的三种解决方案
数据库拆分的方式有两种,前面文中已经聊过,即就是垂直拆分和水平拆分,分库分表是对数据库拆分的一种解决方案。根据分库分表方案中实施切片逻辑的层次不同,我们可以将数据库分库分表的实现方案分为三大类
- 客户端分片
- 代理分片
- 支持事务的分布式数据库
客户端分片
就是使用分库分表的数据库的应用层直接操作分片的逻辑,分片规则需要在同一个应用的多个节点之间进行同步,每个应用层都嵌入一个操作切片的逻辑实现(分片规则),这个一般通过依赖jar包来实现。
具体的实现方案有可以分成三种:
- 在应用层直接实现
- 通过定制JDBC协议实现
- 通过定制ORM框架实现
在应用层直接实现
这是一种非常通用并且简单的解决方案,直接在应用层读取分片规则,然后解析分片规则,然后根据分片规则来实现具体切分的路由逻辑。从应用层直接决定每次操作应该使用哪个数据库实例、数据库及哪个数据库的表等等。
下面是一般公司内部会将这些逻辑封装,打成jar包,供公司其他项目使用。
通过定制JDBC协议来实现
在应用层直接实现或多或少是切片逻辑嵌入到业务代码里了,并且对开发的小朋友们的能力要求还是蛮高的,开发的小伙伴们既需要实现业务逻辑,还要实现框架需求。为了让开发小伙伴们把更多精力放在业务逻辑的实现上,我们可以通过定制JDBC协议来实现,也就是针对业务逻辑提供与JDBC协议一致的接口,让开发小伙伴们不必关心分库分表的实现,让分库分表在JDBC的内部实现类,对业务保持透明。这种解决方案对业务透明,不嵌入到业务代码里去,让开发的小伙伴们和分库分表的配置人员在一定程度上可以分离开了,可以让开发小伙伴们更大限度地投入到业务逻辑的实现中去,但是开发的小伙伴还是得理解JDBC协议才能实现分库分表逻辑。
比如:当前比较流行的客户端分库分表框架Sharding-JDBC,就是采用了这种方案。
通过定制ORM框架实现
由于关系型数据库与面向对象语言之间的差异,ORM框架得到了广泛的发展和应用,因此就有了通过定制ORM框架实现的分库分表方案,也就是把分片规则实现到了ORM框架中或者通过ORM框架支持的扩展机制来完成分库分表的逻辑。
在很多公司里是通过在Mybatis配置文件的SQL中增加表索引的参数来实现分片的。
demo代码如下:
代码语言:javascript复制<select id="getUser" parameter="java.util.Map" resultType="User">
SELECT user_id,user_name FROM USER_#{index} WHERE user_id=#{userId}
<>
代理分片
就是在应用层和数据库层之间加一层代理层,把分片的路由规则配置在代理层,代理层对外提供与JDBC相兼容的接口给应用层,应用层的开发小伙伴们就不用关心分片规则了,只需要关心业务代码的实现,等业务代码实现完了以后,在代理层配置一个路由规则就搞定了。
优缺点:
优点:让应用层的开发小伙伴们更多去关注业务代码的实现,把分库分表的配置留给代理层做。
缺点:增加了代理层,增大了成本。
尽管代理层是轻量级的转发协议,但是毕竟要实现JDBC协议的解析,并且还有通过分片的路由规则来路由请求,对每个数据库操作都增加一个网络传输,这对新性能是很有影响的,需要维护增加的代理层,也有硬件成本,最主要的是需要有大牛在,大牛专门解决代理层出现的bug,哈哈,所以嘛,成本相对高不少。
比如:当前流行的分库分表使用代理分片实现的框架有Cobar、Mycat等。
支持事务的分布式数据库
现在有很多产品,比如:OceanBase、TiDB等对外提供可伸缩的体系架构,并提供一定的分布式事务支持,将可伸缩的特点和分布式事务的实现包装到分布式数据库内部实现,对其使用者透明,使用者不需要直接控制这些特性,例如:TiDB对外提供JDBC的接口,让应用层想使用Mysql等传统数据库依赖来使用TiDB,而不需要关注其内部是如何实现伸缩、分片以及处理分布式事务的。
大家都知道在金融行业,最重要的就是钱,什么金额,余额等。所以金融行业在技术方便还是比较保守的,毕竟是在于钱打交道,每天的交易流水上亿都是很正常的。在各种交易系统中,我么通常采用对事务支持良好的关系型数据库,很少有使用其他类型的数据库,而这些分布式数据库更适合实现非交易系统,比如说:大数据日志系统、统计系统、查询系统、报表系统、社交系统等等。