架构概念

在实际生产环境中,在一个数据库服务器进行读写操作,不管从安全性、高可用性或者高并发等方面都无法满足实际需求,因此采用主从复制来同步数据,读写分离来提升数据库的并发负载能力。

mysql读写分离原理

简单来说,读写分离就是只在主服务器上写、只在从服务器上读。基本的原理是让主数据库处理事务性查询,而从数据库处理select查询。数据库复制被用来把事务性查询导致的变更同步到群集中的从数据库,目前常见的Mysql读写分离分为两种:

1.基于程序代码内部实现
在代码中根据select、insert进行路由分类,这类方法也是目前生产环境应用最广泛的。优点是性能较好,因为在程序代码中实现,不需要增加额外的设备作为硬件开支,缺点是需要开发人员来实现,运维人员无从下手。

2.基于中间代理层实现
代理层一般位于客户端和服务器之间,代理服务器接到客户端请求后通过解析SQL文本再将SQL路由至可用的数据库节点中。优点是程序不需要改造可以实现无缝迁移,可移植性较好。缺点是性能相对前者略微逊色一些,并且并不是所有的读操作都能够被路由至从节点中。

经过上述简单的比较,通过程序代码实现MySQL读写分离自然是一个不错的选择,但是并不是所有的应用都适合在程序代码中实现读写分离。例如:一些大型复杂Java应用,如果在程序代码中实现分离对代码改动较大。

基于Mycat中间件实现

MyCat 是目前最流行的基于 java 语言编写的数据库中间件,是一个实现了 MySQL 协议的服务器,前端用户可以把它看作是一个数据库代理,用 MySQL 客户端工具和命令行访问,而其后端可以用 MySQL 原生协议与多个 MySQL 服务器通信,也可以用 JDBC 协议与大多数主流数据库服务器通信,其核心功能是分库分表,配合数据库的主从模式可实现读写分离。

数据库的主从模式可参考站内文章部署

主从服务器创建相关用户,并赋予权限

GRANT select, insert, update, delete ON 数据库.* TO '用户'@'MyCatIP' IDENTIFIED by '密码';
//读写用户权限,主数据服务器

GRANT SELECT ON 数据库.* TO '用户'@'MyCatIP' IDENTIFIED by '密码';
//只读用户权限,从服务器

安装jdk环境

yum install -y java-1.8.0-openjdk -y

下载解压MyCat

tar -zxf Mycat-server-1.6.7.5-release-20200422133810-linux.tar.gz -C /usr/local

bin 脚本存放处
conf 配置存放处
catlet 扩展功能
lib 依赖存放处
logs 日志存放处

MyCat服务启动/停止/重启/查询状态

./mycat/bin/mycat <start|stop|restart|status>

MyCat有三大重要配置文件
server.xml 账号、参数等的配置
schema.xml 映射的数据库配置
rule.xml 分片(分库分表)配置

配置schema.xml

<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
	<schema name="逻辑库名称" checkSQLschema="false" sqlMaxLimit="100" dataNode="节点名称" >
	</schema>
	<dataNode name="节点名称" dataHost="标签" database="物理数据库名称" />
	<dataHost name="标签" maxCon="1000" minCon="10" balance="1"
			  writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
		<heartbeat>select user()</heartbeat>
		<writeHost host="host1" url="主服务器:3306" user="数据库密码"
				   password="数据库用户">
			<readHost host="hostS2" url="从服务器:3306" user="数据库用户" password="数据库密码" />
		</writeHost>
	</dataHost>
</mycat:schema>

修改server.xml

        <user name="MyCat用户" defaultAccount="true">
                <property name="password">密码</property>
                <property name="schemas">逻辑库名称</property>
                <property name="defaultSchema">逻辑库名称</property>
        </user>

重新启动服务

./mycat/bin/mycat restart

连接测试读写(修改配置文件log4j2.xml,将日志level调成debug级别,然后进行读写操作并观察mycat.log显示IP)

mysql -u root -p -h mycat服务器地址 -P 8066