MySQL 读写分离
一、MySQL 读写分离原理
简单来说,读写分离就是只在主服务器上写,只在从服务器上读。基本的原理是让主数据库处理事务性查询,而从数据库处理 select 查询。数据库复制被用来把主数据库上事务性查询导致的变更同步到集群中的从数据库。
1、MySQL 读写分离实现方法
目前较为常见的 MySQL 读写分离分为两种:
(1)基于程序代码内容实现
在代码中根据 select、insert 进行路由分类,这类方法也是目前生产环境应用最广泛的。优点是性能较好,因为在程序代码中实现,不需要增加额外的设备作为硬件开支。
缺点是需要开发人员来实现,运维人员无从下手。
(2)基于中间代理层实现
代理一般位于客户端和服务器之间,代理服务器接到客户端请求后通过判断后转发到后端数据库,有几个代表性程序。
MySQL-Proxy。MySQL-Proxy 为 MySQL 开源项目,通过其自带的 lua 脚本进行 SQL 判断,虽然是 MySQL 官方产品,但是 MySQL 官方并不建议将 MySQL-Proxy 用到生产环境。
Amoeba。由陈思儒开发,作者曾就职于阿里巴巴。该程序由Java 语言进行开发,阿里巴巴将其用于生产环境。它不支持事务和存储过程。经过上述简单的比较,通过程序代码实现 MySQL读写分离自然是一个不错的选择,但是并不是所有的应用都适合在程序代码中实现读写分离,像一些大型复杂的Java 应用,如果在程序代码中实现读写分离对代码改动就较大。所以,像这种应用一般会考虑使用代理层来实现。本章后续案例通过 Amoeba 实现。
MyCAT 是一款开源的分布式关系型数据库中间件,主要用于解决大规模数据存储和高效查询的需求。它支持分布式 SQL 查询,兼容 MySQL通信协议,能够通过数据分片提高数据查询处理能力。MyCAT的前端用户可以将其视为一个数据库代理,使用 MySQL 客户端工具和命令行访问,而后端则可以通过 MySQL, 原生协议与多个 MySQL服务器通信,或者使用 JDBC协议与大多数主流数据库服务器通信
二、实验案例
1、案例环境
主机 | 操作系统 | IP | 应用 |
Master | openEuler 24.03 | 192.168.10.101 | Mysql-server |
Slave1 | openEuler 24.03 | 192.168.10.102 | Mysql-server |
Slave2 | openEuler 24.03 | 192.168.10.103 | Mysql-server |
Mycat(代理服务器) | openEuler 24.03 | 192.168.10.104 | Mycat2 |
客户端 | openEuler 24.03 | 192.168.10.105 | mysql |
所需软件包
mycat2-install-template-1.20.zip
jdk-8u171-linux-x64.rpm
mysql-connector-java-8.0.18.jar
mycat2-1.21-release-jar-with-dependencies.jar
之前已经配置过MySQL 主从复制,此文不再赘述
2、搭建MySQL 读写分离
MyCAT 是目前最流行的分布式数据库中间插件,是一个开源的分布式数据库系统,是一个实现了 MySQL协议的服务器。前端用户可以把它看作一个数据库代理,用 MySQL客户端工具和命令行访问,其后端可以用MySQL原生协议与多个MySQL服务器通信,也可以用JDBC协议与大多数主流数据库服务器通信,其核心功能是分表分库,即将一个大表水平分割为N个小表,存储在后端 MySQL服务器里或者其他数据库里。
MyCAT 发展到目前,已经不是一个单纯的 MySQL代理了,它的后端可以支持MySQL、SQL Server、0racle、DB2、PostgreSQL 等主流数据库,也支持 MongoDB这种新型 NoSQL 方式的存储。未来,它还会支持更多类型的存储。
不过,无论是哪种存储方式,在最终用户看,MyCAT里都是一个传统的数据库表,支持标准的SQL语句进行数据的操作,这样一来,对前端业务系统来说,可以大幅降低开发难度,提升开发速度。
(1)安装Mycat2
[root@localhost ~]# rpm -ivh jdk-8u171-linux-x64.rpm
(2)安装并配置mycat 软件
[root@localhost ~]# unzip mycat2-install-template-1.20.zip -d /usr/local/
[root@localhost ~]# cd /usr/local/
[root@localhost local]# ls
bin etc games include lib lib64 libexec mycat sbin share src
-d:解压到的位置
[root@localhost local]# ln -s /usr/local/mycat/bin/* /usr/local/bin/
[root@localhost ~]# cp mysql-connector-java-8.0.18.jar mycat2-1.21-release-jar-with-dependencies.jar /usr/local/mycat/lib/
为Mycat 命令添加执行权限
[root@localhost bin]# chmod -R +x /usr/local/mycat/bin
到目前为止,安装的步骤基本上算是完成了,任意命令行下执行指令“mycat-h”,验证安装的正确性
[root@localhost ~]# mycat -h
Usage: /usr/local/bin/mycat { console | start | stop | restart | status | dump }
3、配置Mycat 读写分离
Mycat2 读写分离配置可分为:创建数据库连接账号、启动Mycat2 与读写分离配置等几个步骤。
(1)创建Mycat2 工作所必须的账号
启动 Mycat2 服务,需要有真实的数据库服务器支撑才能运行,因此,需要在 MySQL 服务器(其它被 Mycat2 支持的数据库也如此)创建账号并给账号授权然后在 Mycat2所在的宿主系统用 MySQL 客户端用创建好的账号远程进行连接,验证账号的有效性和正确性。
由于我们已经做好了 MySQL 数据库间的主从同步,因此创建 Mycat2 所需账号的操作只需也只能在主数据库上进行,具体的指令如下:
mysql -uroot -ppwd123
create user 'mycat'@'%' identified by 'pwd123';
grant all on *.* to 'mycat'@'%';
alter user 'mycat'@'%' identified with mysql_native_password by 'pwd123';
flush privileges;
(2)启动Mycat2
与 Mycat1.x版本相比,Mycat2 的配置基本不需要手动去修改配置文件,而是可以在 Mycat2 启动之后,登录 Mycat 管理后台,用SQL指令或者客户端工具进行配置。在启动 Mycat2之前,需要对原型库的数据源做相应的修改,修改的项主要是主数据库的连接信息,一个完整的修改过的原型数据源文件“/usr/local/mycat/conf/datasources/prototypeDs.datasource.json”的内容如下:
mycat
vim /usr/local/mycat/conf/datasources/prototypeDs.datasource.json
"password":"pwd123","url":"jdbc:mysql://192.168.10.101:3306/mysql?useUnicode=true&serverTimezone=Asia/Shanghai&characterEncoding=UTF-8","user":"mycat",
因为已经对系统变量做了设置,所以在任意路径执行“mycat start”就可以启动 Mycat2。在 Mycat2 的安装目录“/usr/local/mycat”下,存在目录“logs”,打开此目录中的日志文件“wrapper.log”,可了解 Mycat2 服务的运行状况
[root@localhost ~]# mycat start
Starting mycat2...
[root@localhost ~]# netstat -anpt | grep 8066
tcp6 0 0 :::8066 :::* LISTEN 2405/java
[root@localhost ~]# systemctl stop firewalld
用 MySQL, 客户端工具连接 Mycat 的服务端口 TCP 8066、用户名与密码在配置文件“/usr/local/mycat/conf/users/root.user.json
[root@localhost ~]# cat /usr/local/mycat/conf/users/root.user.json
{"dialect":"mysql","ip":null,"password":"123456","transactionType":"xa","username":"root"
用命令行连接 Mycat 管理后台的指令为“mysql -uroot -p123456 -P8066 -h192.168.10.101 ”,进入用户交互界面,表明 Mycat2 运行正常,可在此交互界面进行读写分离配置。
客户机
dnf -y install mysql/mariadb #客户机,下载任意一个就行
[root@localhost ~]# mysql -uroot -p123456 -P8066 -h192.168.10.104
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 1
Server version: 5.7.33-mycat-2.0 MySQL Community Server - GPLCopyright (c) 2000, 2025, Oracle and/or its affiliates.Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.mysql>
(3)Mycat2 配置读写分离
两种配置 MySQL读写分离的方法,一种是直接在 Mycat 的配置目录“/usr/local/mycat/conf”的子目录编辑相关的文本文件(Mycat1.x版本只用这种方法);另一种登录到 Mycat 交互界面,用特殊语法的 SQL 命令进行配置。本文采用第二种方法,直接在 Mycat 的交互界面输入命令。
第一步:Mycat增加数据源
需要正确输入的数据主要包括:MySQL 主从数据库的 IP地址、数据库库名(chema)、数据库账号、数据库密码(生产数据库请使用复杂密码)、实例类型(READ、WRITE或READWRITE)。
下边是添加一个主库源和两个从库源的具体指令:
[root@localhost ~]# mysql -uroot -p123456 -P8066 -h192.168.10.104
增加主库master:
mysql> /*+ mycat:createDataSource{ "name":"master","url":"jdbc:mysql://192.168.10.101:3306/?useSSL=false&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true","instanceType":"WRITE","user":"mycat","password":"pwd123"} */;
增加从库slave1 和slave2:
mysql> /*+ mycat:createDataSource{ "name":"slave1","url":"jdbc:mysql://192.168.10.102:3306/?useSSL=false&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true","instanceType":"READ","user":"mycat","password":"pwd123"} */;
mysql> /*+ mycat:createDataSource{ "name":"slave2","url":"jdbc:mysql://192.168.10.103:3306/?useSSL=false&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true","instanceType":"READ","user":"mycat","password":"pwd123"} */;
可以使用以下命令查看:
mysql> /*+ mycat:showDataSources{} */\G
如数据源配置有误可使用” /*+ mycat:resetConfig{}*/; “ 进行重置
mycat
[root@localhost ~]# ll /usr/local/mycat/conf/datasources
总计 16
-rw-r--r--. 1 root root 477 5月15日 09:59 master.datasource.json
-rw-r--r--. 1 root root 423 5月15日 09:41 prototypeDs.datasource.json
-rw-r--r--. 1 root root 476 5月15日 09:59 slave1.datasource.json
-rw-r--r--. 1 root root 476 5月15日 10:00 slave2.datasource.json
第二步:创建mycat 集群
在本文中,集群成员包括一个主库与两个从库。根据业务场景,也可以创建多个集群,充分、有效的利用系统资源。创建 Mycat 集群的SQL语句如下:
客户机
mysql> /*! mycat:createCluster{"name":"cls01","masters":["master"],"replicas":["slave1","slave2"]} */;
修改负载均衡的默认策略为沦陷
mycat
[root@localhost ~]# vim /usr/local/mycat/conf/server.json"defaultLoadBalance":"BalanceRoundRobin", #3行
修改配置后需要重启mycat
[root@localhost conf]# mycat restart
Stopping mycat2...
Stopped mycat2.
Starting mycat2...
4、验证mycat 读写分离
客户机
[root@localhost ~]# mysql -uroot -p123456 -P8066 -h192.168.10.104
mysql> create database test;
之后可以查询master 主服务器,尝试多种写入、读取、删除以验证读写分离