**一、 什么是读写分离 **
读写分离,从字面理解就是将对数据库的读操作与写操作分离的一种优化手段。通俗来说,是将事务性的增删改(INSERT、DELETE、UPDATE)这些“写”类操作放到主库上处理,而备库处理“读”(SELECT)请求。
**二、为什么要读写分离?
**
**什么情况需要采用读写分离技术?
**
首先,我们采用这项优化技术的使用场景一般是目前(或可预见的未来)随着业务数据规模的上升,数据库的性能压力大,数据库的“写”和“读”效率低下,呈现一种竞争有限的数据库资源而互相影响性能的情况。
从关系型数据库(如MySQL、Oracle、MS
SQLServer等)即数据服务端来说:数据库的“读”操作一般比较快,以Oracle数据库为例,读10000条数据可能只需要5秒钟或更少。但是同等复杂度数据的“写”操作,写10000条数据可能要3分钟或更多。
这是因为读操作不需要修改数据,只需要从数据库中读取数据即可,而写操作需要修改数据库中的数据,这会涉及到磁盘IO、锁等操作,因此会比读操作慢一些。现在的数据库系统为了数据的高可用,通常采用多副本技术冗余保护数据,但其备用副本如无法提供业务访问,将是一种资源浪费,而读写分离可有效利用只读副本,从而提升整体资源利用率,以提供更大的负载能力。
从实际业务应用程序即数据客户端来说:如果实际业务需求上,程序对读写性能要求较高且数据规模增长快。这时选择将读取与写入操作分离,不仅能满足性能要求,还能有效规避由于异常情况带来的风险,常见情况如一个大查询语句,因访问数据规模巨大占用大量CPU资源。通过数据服务端的分离,可避免影响更为重要的写入操作。
**三、 技术实现 **
1\. 服务端(即数据库)
常用的方案为数据库层面采取主从模式的数据库架构,利用数据库产品自带的主从复制功能同步数据。
也有的数据库产品本身集成了读写分离功能,即在数据库层面就能判断读写操作,分发到相应实例进行处理,并保证事务上的正确性。常见的本身支持读写分离的数据产品有阿里云-
RDS数据库、OceanBase、KunlunBase等。
2\. 客户端(即应用程序)
常见的思路一是客户端程序做读写分离适配,即应用自主实现读写分离逻辑。
第二个思路是引入成熟的读写分离中间件,应用程序无需关心读写分离逻辑,就像连接单机数据库一样去连接这些中间件提供的地址即可。常见的中间件有MySQL-
Proxy、Apache ShardingSphere、MyCAT等。
**四、实践举例
**
1\. 背景描述:
某项目采用HAP外挂EBS(DB共库)的系统架构,EBS系统数据库为Oracle数据库。
已有的EBS系统对EBS数据库(主)进行读写操作,EBS主库通过数据库主从同步机制将数据同步到备库。在此基础上引入HAP做系统外挂实现部分业务功能,为了减轻对EBS主库的读写压力,充分利用数据库资源,评估HAP需采取读写分离方案,以提高整个系统的效率。
2\. HAP读写分离技术实现:
采取上文客户端的思路一:HAP程序做读写分离适配,即应用自主实现读写分离逻辑。利用spring
自带的AbstractRoutingDataSource,mybatis的拦截器,DataSourceTransactionManager扩展等,能实现如下读写分离效果:
1) 有事务控制的走主库;
2) 没有事务控制的,查询类走备库,其余走主库。
HAP和EBS数据库交互示意图
3\. HAP具体实现:
・ 数据源(dataSource)配置:
要点说明:
DynamicDataSource类扩展spring框架AbstractRoutingDataSource类,以根据当前数据源标志(READ或WRITE)动态确定走哪个库(读库还是写库)。
对应核心代码片段:
・ 事务管理器(transactionManager)配置:
要点说明
DynamicDataSourceTransactionManager类扩展spring框架DataSourceTransactionManager类,主要判断当前事务如为只读事务则走读库,否则走写库。
对应核心代码片段:
・ Mybatis拦截器(Mybatis Interceptor)配置:
要点说明
DynamicPlugin类实现Mybaits框架的Interceptor接口,主要是针对不被spring事务管理(一般用@Transactional注解)的sql拦截,如为INSERT、DELETE、UPDATE等“写”操作,则走写库(主库),如为SELECT操作,则走读库(备库)。
对应核心代码片段:
**五、 结束语 **
以上仅为作者个人对“读写分离”这个技术命题的浅薄理解,实践举例的实现方式也是相对简易的一种方案,有兴趣的读者可以查询相关资料,做更深入的研究。最重要的是,要结合项目的实际情况去评估。
** -END- **
作者丨晏绪圣
审核丨邓金边
编辑丨王 锐