如何使用两台服务器实现主从同步与数据读写分离

Posted 我好困啊

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何使用两台服务器实现主从同步与数据读写分离相关的知识,希望对你有一定的参考价值。


        主从同步实现读写分离,快速运用到实际开发项目中去,上一次的主从同步,主要是关于如何在服务器上进行主从同步的配置,实现两台服务器上的数据跟踪,相当于配置好了环境。


        那么有这么好的环境,怎么浪费呢,所以今天我就简单的介绍一下如何将配置好的主从同步的环境利用起来,快速运用到我们的实际开发项目中。


     实现思路:主从同步,主要是实现数据的读写分离,即用户的读(查询)操作,使用master服务器的数据库,写(添加,更新,删除)操作使用slave服务器。所以要实现多数据源,就要在Dao操作层之前,进行拦截判断,设置不同的数据源,从而实现数据库的读写分离,所以接下来的操作主要是配置Dao的多数据源。


那我们开始吧,首先展示一下我要进行演示代码的基本信息和主数据库的基本信息


注:这里笔者用的语言为java,框架为SSM框架(ps:springboot等其他框架原理一样,只要能看懂这个,其他框架也能快速运用)


master上的主数据库,有数据库mengxinshop,里面有一张表tb_shop,里面有三条数据,如图:



对应的area实体类:


如何使用两台服务器实现主从同步与数据读写分离(二)


areaDao的信息(只有两个方法)


如何使用两台服务器实现主从同步与数据读写分离(二)


对应的mybatis的select语句为:


如何使用两台服务器实现主从同步与数据读写分离(二)



我的SSM框架的简略信息


如何使用两台服务器实现主从同步与数据读写分离(二)



以上就是我演示开始之前的准备(ps:想跟着做,就把你的环境弄成上面的样子,SSM框架搭好,接下来就可以跟着敲了)




下面开始配置




      1.AbstractRoutingDataSource的继承


        在dao层下面建立一个包split(存放数据 分离的配置文件),创建实体类DynamicDataSource类继承AbstractRoutingDataSource,实现其中的方法,determineCurrentLookupKey。添加代码返回值如下:



如何使用两台服务器实现主从同步与数据读写分离(二)

简单说明:AbstractRoutingDataSource,翻译过来就是抽象数据路由,可以路由到不同的数据源,里面有个方法,即determineCurrentLookupKey,根据字段key的不同决定不同的数据源。


     2.DynamicDataSourceHolder工具类的编写


      实现DynamicDataSourceHolder工具类,进行获取,设置,清空字段,决定数据源,具体代码,说明如下:



如何使用两台服务器实现主从同步与数据读写分离(二)


接上图


如何使用两台服务器实现主从同步与数据读写分离(二)


只就是DynamicDataSourceHolder的全部代码,就是一个工具类,主要作用就是将字段设置到线程中,清理连接,从线程中获取字段,进行返回,从而决定不同的数据源。


    3.配置mybats拦截器


       配置mybats拦截器,根据sql信息进行拦截判断请求为读还是写,从而设置不同的字段到线程,返回供第一步的determineCurrentLookupKey方法判断,决定数据库。


创建拦截器DynamicDataSourceIntercept,实现拦截器的配置(ps:Interceptor引入ibstis的拦截器),具体如下:




如何使用两台服务器实现主从同步与数据读写分离(二)


如何使用两台服务器实现主从同步与数据读写分离(二)


如何使用两台服务器实现主从同步与数据读写分离(二)


以上就是mybatis拦截器的全部配置了,具体说明也在图上 


简要说明,该拦截器拦截mybatis的sql语句,根据拦截的sql语句进行判断要使用哪个数据库,然后调用 DynamicDataSourceHolder工具类,保存到线程中,返回key,决定使用哪个数据库。




最后将配置好的Mybatis拦截器(DynamicDataSourceIntercept)放入到Mybatis的核心配置文件中mybatis-config.xml(别忘记了)


   如下:


如何使用两台服务器实现主从同步与数据读写分离(二)


      

   


    4.配置Spring配置文件的数据源


a.将db.properties中的数据原配置,增加一台jdbc的信息配置,我的如下:我master和slave中的中的用户名和密码都一样,所以只需要增加一个url就行了。


  

如何使用两台服务器实现主从同步与数据读写分离(二)


b.找到spring中配置数据源的地方,修改配置原有的DataSource为抽象数据源,创建master和slave数据源,进行继承,配置详情如图:


 

如何使用两台服务器实现主从同步与数据读写分离(二)


c.配置动态数据源

 

如何使用两台服务器实现主从同步与数据读写分离(二)


注:最后配置的bean将其id设置为dataSource(即刚开始的数据源id),这样就不需要修改Spring中的其他配置了,第一个bean中的属性为targetDataSources,第二个为targetDataSource



以上所有主从同步所有配置都完成了,接下来就让我们测试一下效果吧


这里笔者用的Junit单元测试


1.建立一个基本类(baseTest)用来加载spring的各种配置文件,配置如下:


如何使用两台服务器实现主从同步与数据读写分离(二)



2.建立areaDaoTest测试类,继承baseTest,开始测试,具体代码如下:


如何使用两台服务器实现主从同步与数据读写分离(二)


运行,测试结果如下(如果配置都正确的话):


如何使用两台服务器实现主从同步与数据读写分离(二)

日志打印出所用的到sql语句为select类型,使用的数据库为slave(从数据库)



再来看看查询到的数据


如何使用两台服务器实现主从同步与数据读写分离(二)


查询到的数据为3,和上面我展示的master数据库中的数据记录一样,的确是3条


如何使用两台服务器实现主从同步与数据读写分离(二)



接下来我们来测试一下写操作,这里我向数据库添加一条数据


在该测试类中添加测试方法:


如何使用两台服务器实现主从同步与数据读写分离(二)



测试结果如下:


如何使用两台服务器实现主从同步与数据读写分离(二)


可以看出select语句为insert,使用的数据库为master


再让我们来看看Master和Slave服务器上的数据吧


如何使用两台服务器实现主从同步与数据读写分离(二)


可以看到数据添加到master上了


再来看看slave服务器上的数据变换吧


如何使用两台服务器实现主从同步与数据读写分离(二)


此时,Slave服务器上的数据已经自动同步了。是不是很神奇啊如何使用两台服务器实现主从同步与数据读写分离(二)


以后你就可以在你的项目中使用该方法了,是不是很方便呢。



这里补充一下可能会遇到的一些问题:


1.数据库连接失败



造成该种可能的原因:


     a.你的账号和密码错误

     b.mysql的3306端口防火墙没关

     c.没有授予mysql远程连接权限:使用 GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '你的密码' WITH GRANT OPTION;进行授权。


可以使用本地的mysql工具进行连接测试一下,如果连接上了,那表明问题解决


2.测试写入数据时,出现隔离级别




          这是什么原因呢,刚刚读的时候就没问题,写就出问题呢,原因是因为mysql驱动包版本和mysql冲突,比如我服务器mysql用的5.5,驱动包用的6.0就出现这个问题了,直接将驱动包替换为5.1.32就行了



         好了,以上主从同步实现数据的读写分离运用到实际开发中的demo就写完了,能看懂以上的原理,就可以运用到其他框架中去,方法如出一辙。赶快去试一试吧。


        特别注意:主从同步,所有写都在主数据库中进行,读在从数据库中执行,请不要把写操作写到从数据库中了。否者会造成主从混乱。(ps:如果严格按照该方法配置的,一般不会弄错)


       希望该方法能对你有所帮助,搭建到你自己的项目中,优化数据库。有什么不懂的可以加本萌新qq1097703676骚扰我哦!

        



以上是关于如何使用两台服务器实现主从同步与数据读写分离的主要内容,如果未能解决你的问题,请参考以下文章

测试mysql主从配置:实现一主一从读写分离

CentOS 7上部署Amoeba实现MySQL主从同步,读写分离,负载均衡高可用群集

MySQL的读写分离与主从同步数据一致性

mysql主从库与读写分离

mariadb的主从同步和读写分离

mariadb的主从同步和读写分离