当前位置:主页 > 技术方案 >

AOP技术实现数据库读写分离

发布时间:2021-01-07 15:44   浏览次数:次   作者:admin
前言。
最近我们APP的在线用户越来越多,界面的响应速度越来越慢。通过运维检查发现,由于并发查询数量过多,数据库压力很大。通过调研,架构师给出了数据库读写分离的解决方案。为了更快地解决问题,最终采用AOP技术实现数据库读写分离。
目录。
什么是数据库读写分离,为什么要读写分离?
本文分析了数据库读写分离的实现方式和优缺点。
基于AOP的数据库读写分离方案。
概述。
什么是数据库读写分离,为什么要读写分离?
顾名思义,数据库读写分离就是数据库读写操作分离。
在传统的项目架构中,所有操作都是在同一个数据库上执行的,在并发较少的情况下不会造成任何问题,但是在并发较多的情况下,单个数据库会造成性能问题。
假设一个数据库的QPS是1000,数据库的同位素是2000,那么狼比肉多的时候界面响应速度慢就不足为奇了。
为了解决这个问题,出现了数据库读写分离方案。
采用数据库读写分离方案后,共有四个数据库,包括一个主从数据库和三个从数据库。binlog文件用于主机和从机之间的数据同步。主数据库负责处理所有写操作,并异步同步数据库中的数据;平均而言,所有读取操作都分散在三个数据库中。
主数据库分离后,数据库读写,多个数据库组成一个集群,共同提供查询服务。将原来大量的并发查询操作平均分成三个数据库,降低了每个数据库的并发性,提高了查询效率;同时,数据的冗余备份提高了系统的抗风险能力。
本文分析了数据库读写分离的实现方式和优缺点。
根据级别的不同,主要有三种方法可以将数据库读写分开。
第一,应用层面。
实现方法是在应用层增加一个数据源路由层,将查询操作路由到从库,将写操作路由到主库。
优点:方案轻巧易实现,路由策略可自由控制,可扩展性强。
缺点:功能有限,个人很难实现一个完整的方案,方案与代码强耦合,跨语言不通用。
第二,中间件层数。
在应用程序和数据库之间添加了一个代理层,代理转发操作请求。比如阿里的MyCAT,360的Atlas,美团的DBProxy等。,都是这样的实现方案。
优点:解决方案与应用层代码分离,通用性更强。
缺点:应用和数据库之间增加了代理层,直接连接到代理的连接转换导致性能下降。
3.数据库驱动层。
其实现方法是提供支持数据库读写分离的驱动。比如Mysql自带的ReplicationDriver驱动,当当的开源Sharding-JDBC,淘宝的开源TDDL,这些解决方案都是在数据库驱动层实现的。
优点:功能丰富,集成更简单,应用层改动更少。
缺点:需要使用特定的数据库驱动,不容易扩展。
基于AOP的数据库读写分离方案。
采用这种方案是因为它足够轻,不需要额外添加任何东西。其次,AOP技术门槛低,实现速度快。
首先,介绍了本项目的技术背景。该项目是使用SpringBoot框架和Mybatis作为ORM层开发的。请求的调用链通常是控制器调用服务和服务调用映射器。
规划框架的组成:
基本原则:
一般来说,我们遵循一些命名方法的规范,例如,插入方法以插入或保存等关键字开始,更新方法以更新或编辑等关键字开始,查询方法以选择或查找等关键字开始。这种命名约定很好的实现了代码的自解释,让人一眼就能看到文言文。
有了这个特性,我们就可以从定义一个AOP节切入到所有Service实现类中的所有方法,并根据方法开头的关键字切换不同的数据源,最终达到将写操作路由到主数据库,将查询操作路由到三个从库的目的。
实施步骤:
定义和配置主数据库以及数据库中的数据源信息。
将Mybatis使用的默认数据源改为我们定制的RoutingDataSource,实现动态切换。
在路由数据源中,我们在地图中的关键字和数据源之间有一对一的对应关系,以及键值对应关系:
写出->写出数据源。
Read0->read1数据源。
Read1->read2数据源。
read2->read3数据源.
再次,继承Spring框架的AbstractRoutingDataSource抽象类可以定制RoutingDataSource类,实现determineCurrentLookupKey方法,这是实现数据源切换的关键。
在determineCurrentLookupKey方法中,我们从数据源中获取相应的键值。
4.检查数据源的(DataSourceContext)内部逻辑:
线程本地变量在数据源文本中定义,用于存储线程使用的数据源信息。此外,还提供了两种数据源切换方法:switchToReadDatasource和switchToWriteDatasource。
最后,让我们看看AOP部分的类:
在执行该方法之前,我们使用@Before注释来定义两个切入点,以增强切换数据源。
截取以select、get、find等关键字开头的读取方法时,我们将其转换为读取数据源,截取以insert、update、delete等关键字开头的写入方法时,我们将其转换为写入数据源。
写一个测试类来测试:
先插入一个数据条,然后读取数据条,然后查看执行结果:
您可以看到,insert运算符自动切换到write数据源,而select运算符随机切换到read2数据源。
概述。
一般来说,大多数项目读得多,写得少。数据量和数据到数据到数据到数据到数据到数据到数据到数据到数据到数据到数据到数据到数据到数据到数据到数据到数据到数据到数据到数据到数据到数据到数据到数据到数据到数据到数据到数据到数据到数据到数据到数据到数据到数据到数据到数据到数据到数据到数据到数据到数据到数据到数据到数据到数据到数据到数据到数据到数据到数据到数据
读写分离增加了数据库的读取能力,而多个数据库共享读取可以显著提高系统的并发性。
每种方案各有利弊,读写分离也不例外。读写分离需要改变数据库的主从结构,增加了系统的复杂性。同时主从之间的数据同步也会造成延迟,可能不适合要求数据查询准确的企业。
对于轻量级企业,如果需要快速实现数据库读写分离,可以使用AOP自己实现;如果有足够的人力和技术从系统层面改革项目,个人倾向于采用分片-JDBC和其他驱动层的开源解决方案。