写在前面
随着业务的发展和数据量的增加,需要对数据库架构进行调整,目前我们所使用的是一台单点的数据库,考虑到项目对外部提供服务之后业务会大量的增长,现在需要将数据库更改为主从的架构.
数据库架构介绍
通过对数据库数据进行拆分,来提高数据的访问频率,以及扩展数据库的存储量.
什么是主从架构
通过Mysql的binlog进行数据拷贝,将主库的增删改操作复制到从库中,已达到主从同步的目的.
什么是读写分离
将数据库拆分为主库和从库,主库负责处理事务性的增删改查,从库负责处理查询操作,能够有效的提高数据库的吞吐量.
读写分离要做的就是对一条SQL该选择那个数据库去执行,至于谁做这件事,要么中间件帮我们做,要么程序自己做.
读写分离的优势
- 大大的提高了读的能力,通过数据库主从复制,可以对外部提供单的只读服务器,在业务上也降低了主库的压力;
- 增加数据安全性,由于配置了主从备份,主库与从库的数据可以达到近乎实时的效果,一旦某台数据库出现问题,其他的库还可以顶上;
读写分离的负面影响
- 读写分离的数据同步会出现延时的问题;
- 因为mysql的主从同步是通过binlog进行实现的,由于binlog默认是异步的所以主从节点之间数据存储存在延迟.
- 增加开发的复杂性,对系统带来更大的挑战.
目标
数据库读写分离实现
上文中提到,数据库读写分离可以通过主从数据库拷贝的方式实现数据库同步,之后用编码的方式决定读库和写库的操作,但是在实际生产中并不止这一种对数据库读写分离的方式.
中间件
使用Mysql中间件实现,如Mycat,TDDL等数据库中间件来实现,对于项目本身来说,只有一个数据源,就是连接到Mycat,再由Mycat根据规则去选择那个数据库.
Mycat
Mycat是一个开源的,面向企业应用的大规模数据库集群管理中间件,可以很好的支持数据事务,以及提供了很多分布式的解决方案:
- 支持分布式事务
- 支持主从切换
- 支持跨库join
- 可以搭建高可用集群
- …
结合现有情况分析
Mycat是一个综合能力很强的中间件,其强大的功能,足以满足现有甚至是未来的需求,但是其架构的复杂程度是非常高的,需要的学习成本也是非常大的.结合项目组目前情况分析,没有多余的人手可以负责这套架构.
NewSQL-新型数据库
随着互联网的高速发展,业务量可能在非常短的时间内爆发式的增长,对应的数据量可能从几百GB暴涨到几百TB.新型数据库营运而生,
TiDB
TiDB是基于GoogleSpanner/F1论文进行实现的分布式NewSQL该数据库具备以下特点:
- SQL支持;
- 水平弹性扩展;
- 分布式事务;
- 跨数据中心强一致性;
- 支持100%OLTP和80%OLAP.
最重要的一点TiDB对业务没有任何侵入性,能够优雅的替换传统数据库中间件,数据库分库分表等Sharding方案,让开发人员不需要关心数据库的细节问题,可以更加专注于业务开发,极大的提升研发的生产力.
结合现有情况分析
TiDB总体而言是一套非常好的解决方案,他对于目前和未来的需求也基本上都可以满足,但是TiDB作为NewSQL而言他的还是有些年轻,处于发展阶段版本的高速迭代和不稳定性,会给我们开发带来很大的阻力以及不可不可预见性.
还有一点,TiDB底层作为KV存储,为了达到高性能以及多数据源join等操作,对硬件要求以及网络情况的要求非常的极端,需要大量的SSD存储设备以及万兆网卡的支持,这点对于我们目前的情况而言也是过于苛刻.
代码配置
代码中配置多数据源,通过代码控制使用那个数据源对数据库进行读写操作.
手动编码实现
vegas基于spring-boot:1.5开发的后台框架,可以在项目中添加多个数据源,在需要使用主库的时候进行手动切换即可完成读写分离
代码结构
将数据源交给DynamicDataSource进行托管,并且制定Primary-DataSource,在使用的时候通过自定义注解完成数据源切换.
Sharding-jdbc
Sharding-jdbc定位为轻量级的Java框架,在Java的JDBC层提供额外的服务.它使用客户端直接连接数据库,以jar包的形式提供服务,无序额外部署和依赖.
所具备的优点
- 数据分片
-
数据读写分离
- 对代码侵入性小
- 使用成本极低
- …
结合现有情况分析
目前我们所要解决的问题是对数据库的读写进行拆分,通过这套架构也可以帮助我们完成,而且对开发人员比较友好不需要我们提供大量的学习成本.
面对未来的需求
目前我们基本解决了数据库读写分离事情,但是随着业务量的发展,可能还会有数据库进行分库分表、数据源down机自动自动抛弃等需求,在这个开发方案中,预留了很多可以提高和拓展的地方,已经为将来的变动做好了准备。
实现方案
最终的实现方案是创建两个数据源一个为主数据源(管理主库连接),一个味Sharding数据源(管理主库和从库连接),正常情况下默认使用Sharding数据源,如有特殊需要可以通过@MasterDataSource进行数据源切换.