数据库的主从复制环境已经配好,该要解决系统如何实现读写分离功能了。Mysql的jdbc驱动提供了一种实现ReplicationDriver。

1 数据库地址的两种写法

参考:https://dev.mysql.com/doc/connector-j/5.1/en/connector-j-reference-url-format.html

因为后续配置可能会用到,先介绍一下mysql url中主机地址的两种写法。

最简单的写法就是 host:port ,如 192.168.5.128:3306,如果端口是缺省的3306,也可以不写,直接使用 192.168.5.128。

更复杂的写法是指定属性,格式为 address=(host=host_or_ip)(port=port)(key1=value1)(key2=value2)...(keyN=valueN),如 address=(host=192.168.5.128)(port=3306)(type=master)。

2 数据池配置

参考:https://dev.mysql.com/doc/connector-j/5.1/en/connector-j-master-slave-replication-connection.html

driverClassName: com.mysql.jdbc.ReplicationDriver

url字符串格式:

jdbc:mysql:replication://[master host][:port],[slave host 1][:port][,[slave host 2][:port]]...[/[database]][?propertyName1=propertyValue1[&propertyName2=propertyValue2]...]

数据库地址的写法有两种,上面是第一种简单的写法,ReplicationDriver默认将第一个数据库服务器作为Master库,后续其他数据库服务器作为从数据库。

如果数据库主从设置了多台数据库作为Master,则url格式为:

jdbc:mysql:replication://address=(type=master)(host=master1host),address=(type=master)(host=master2host),address=(type=slave)(host=slave1host)/database[?propertyName1=propertyValue1[&propertyName2=propertyValue2]...]

3 ReplicationDriver的调用方法

Mysql驱动使用究竟使用 master还是 slave数据库,取决于 Connection.getReadOnly()的值。如果值为false,则将命令发送到master数据库,如果值为true,则将命令发送到slave数据库。当有多台slave数据库时,使用轮询调度(round-robin)算法选择某一台slave数据库。

所以,为了让mysql驱动能够准确的将命令发送到master或slave,代码需要在获取到数据连接后,执行命令 Connection.setReadOnly(true) 或 Connection.setReadOnly(false)。

以下是mysql官方提供的示例代码

import java.sql.Connection;

import java.sql.ResultSet;

import java.util.Properties;

import com.mysql.jdbc.ReplicationDriver;

public class ReplicationDriverDemo {

public static void main(String[] args) throws Exception {

ReplicationDriver driver = new ReplicationDriver();

Properties props = new Properties();

// 从库上允许自动重连

props.put("autoReconnect", "true");

// 多台从库使用负载均衡

props.put("roundRobinLoadBalance", "true");

props.put("user", "foo");

props.put("password", "password");

Connection conn = driver.connect("jdbc:mysql:replication://master,slave1,slave2 /test", props);

// 在主库上读写,设置 read-only 为 "false"

conn.setReadOnly(false);

conn.setAutoCommit(false);

conn.createStatement().executeUpdate("UPDATE some_table ....");

conn.commit();

// 现在在从库上执行查询,驱动会自动选择一台从库执行查询

conn.setReadOnly(true);

ResultSet rs = conn.createStatement().executeQuery("SELECT a,b FROM alt_table");

.......

}

}

4 Spring TX实现读写分离

项目使用Spring Transaction管理事务,注解Transactional已经帮我们做了封装,注解属性 readOnly,缺省为 false。

/**

* {@code true} if the transaction is read-only.

* Defaults to {@code false}.

* <p>This just serves as a hint for the actual transaction subsystem;

* it will <i>not necessarily</i> cause failure of write access attempts.

* A transaction manager which cannot interpret the read-only hint will

* <i>not</i> throw an exception when asked for a read-only transaction.

* @see org.springframework.transaction.interceptor.TransactionAttribute#isReadOnly()

*/

boolean readOnly() default false;

简单用法

@Transactional(readOnly = true)

public List<Enterprise> queryList(EnterpriseCriteria criteria) {

return enterpriseDao.queryList(criteria);

}

在现有项目上拉了一个分支,使用VMWare上搭建的MariaDB主从库进行测试,确实能实现读写分离。

5 还需要了解的扩展知识

有空时应该进一步读一下代码,看看以下一些内容:

  1. Transactional的注解,是怎样逐渐调用到Connection.setReadOnly()的?
  2. 多个Transactional注解的函数调用时,readOnly参数是否会每次都调用?

Mysql使用ReplicationDriver驱动实现读写分离的更多相关文章

  1. Mysql主从配置,实现读写分离

    大型网站为了软解大量的并发访问,除了在网站实现分布式负载均衡,远远不够.到了数据业务层.数据访问层,如果还是传统的数据结构,或者只是单单靠一台服务器扛,如此多的数据库连接操作,数据库必然会崩溃,数据丢 ...

  2. 分布式架构高可用架构篇_08_MyCat在MySQL主从复制基础上实现读写分离

    参考: 龙果学院http://www.roncoo.com/share.html?hamc=hLPG8QsaaWVOl2Z76wpJHp3JBbZZF%2Bywm5vEfPp9LbLkAjAnB%2B ...

  3. 黄聪:Mysql主从配置,实现读写分离

    大型网站为了软解大量的并发访问,除了在网站实现分布式负载均衡,远远不够.到了数据业务层.数据访问层,如果还是传统的数据结构,或者只是单单靠一台服务器扛,如此多的数据库连接操作,数据库必然会崩溃,数据丢 ...

  4. Mysql 之主从复制,mysql-proxy读写分离

    准备两台mysql服务器,master(192.168.43.64).slave(192.168.84.129) master配置: log-bin=mysql-bin binlog_format=m ...

  5. Mysql多实例安装+主从复制+读写分离 -学习笔记

    Mysql多实例安装+主从复制+读写分离 -学习笔记 .embody{ padding:10px 10px 10px; margin:0 -20px; border-bottom:solid 1px ...

  6. 高可用架构篇--MyCat在MySQL主从复制基础上实现读写分离

    实战操作可参考:http://www.roncoo.com/course/view/3117ffd4c74b4a51a998f9276740dcfb 一.环境 操作系统:CentOS-6.6-x86_ ...

  7. MySQL+MyCat分库分表 读写分离配置

    一. MySQL+MyCat分库分表 1 MyCat简介 java编写的数据库中间件 Mycat运行环境需要JDK. Mycat是中间件.运行在代码应用和MySQL数据库之间的应用. 前身 : cor ...

  8. linux上使用amoeba实现MySql集群,以及读写分离,主从复制

    一.由于是MySql集群,所以就不可能只有一个MySql,需要多个MySql,具体安装步骤,可以参考http://www.cnblogs.com/ywzq/p/4882140.html这个地址进行安装 ...

  9. mysql主从复制 主主复制 读写分离

    首先是mysql的主从复制很简单 主主复制也就是互相主从最麻烦的最难的就是日志恢复,增量恢复什么的比较复杂 首先如果你不会安装mysql版本最好一样,或者往上的版本,因为mysql是向下兼容 请注意不 ...

随机推荐

  1. awk 输出前 N 列的最简单方法

    最近遇到一种场景,需要输出一个文本信息的前 N 列. 众所周知 cut 可以指定分隔符并指定列的范围,如 cut -d' ' -f-4 就是以空格为分隔符输出前 4 列.但是 cut 的分隔符只能是一 ...

  2. react-native聊天室|RN版聊天App仿微信实例|RN仿微信界面

    一.前言 9月,又到开学的季节.为每个一直默默努力的自己点赞!最近都沉浸在react native原生app开发中,之前也有使用vue/react/angular等技术开发过聊天室项目,另外还使用RN ...

  3. 如何通过纯javascript实现表单提交

    通常,如果是POST方法,一般使用vuejs+axios,或使用Jquery实现表单提交.有些地方,我想使用纯JS实现,比方简单的登陆跳转.话不多说,看原代码, laravel中的HTML部分,如果不 ...

  4. 0基础入门学习Python(第5章)

    列表,元组和字符串 5.1 列表:一个打了激素的数组 有时候可能需要将一些相互之间有关联的数据保存在一起,这个就叫数组.Python将其称为列表. 5.1.1 创建列表 >>> [1 ...

  5. 使用Fiddler进行HTTP流量分析

    - 安装 Fiddler是一款免费软件,可以到其官网下载,地址是https://www.telerik.com/fiddler,也可以从我的网盘中下载,发送"fiddler"获取下 ...

  6. KB奇遇记(3):糟糕的IT现状

    2015年8月3号,终于告别了过去来到了KB. 公司给安排的住房是一间套房里的小房间,小的简直连坐的地方都没有了,中间一个大床将房间隔了两边,显得特别狭小.由于是刚来,我也不好要求太多.但就这个小房间 ...

  7. iOS10 新特性一

    链接:http://www.jianshu.com/p/0cc7aad638d9 1.Notification(通知) 自从Notification被引入之后,苹果就不断的更新优化,但这些更新优化只是 ...

  8. iOS 禁用`URL Scheme`和`Universal Link`(通用链接)

    为什么要禁用URL Scheme和Universal Link(通用链接) 通常我们APP中都会嵌套一些web页面,有时我们的web页面会被DNS劫持从而跳转到其他APP中:或者是某些APP的Univ ...

  9. 生成前N个自然数随机置换的3个程序

    问题描述: 假设需要生成前N个自然数的一个随机置换.例如,{4,3,1,5,2}和{3,1,4,2,5}就是合法的置换,但{5,4,1,2,1}却不是,因为数1出现两次而数3却没有.这个程序常常用于模 ...

  10. 初学JavaScript正则表达式(五)

    范围类 [ ] 例: 'a1b1c1s1v1d1f1'.replace(/[a-z]/g,'q') //q1q1q1q1q1q1q1 将a-z范围内的字符替换为q 'a1b1c1s1v1d1f1AKS ...