【MySQL 读写分离实战教程:基于 Mycat 中间件,从环境搭建、JDK 与 Mycat 安装、用户配置、server.xml 与 schema.xml 文件修改,到读写分离,主从同步结果验证】

【MySQL 读写分离实战教程:基于 Mycat 中间件,从环境搭建、JDK 与 Mycat 安装、用户配置、server.xml 与 schema.xml 文件修改,到读写分离,主从同步结果验证】

本文原创作品,良心制作,干货为主,简洁清晰,一看就会


前言

学习读写分离,可拆分数据库读写压力,主库专注写操作,从库分担读请求,提升系统吞吐量;还能避免读操作阻塞写操作,优化响应速度,是高并发场景下保障数据库性能的关键方案


一、什么是读写分离

读写分离核心是拆分数据库读写操作:主库专注处理写入(增删改),并通过主从同步将数据变更实时同步到从库;从库仅承担查询(select)请求
通过中间件(如MyCat、Sharding-JDBC)或应用层路由,将写操作定向到主库,读操作分发到从库,实现压力分流,提升整体性能。


二、Mycat中间件及其作用

Mycat 是数据库中间件,就是介于数据库与应用之间,进行数据处理与交互的中间服 务是实现对主从数据库的读写分离、读的负载均衡

Java程序层
java1、java2、java3… 是业务应用,负责发起数据库操作请求
中间件层(MyCat)
接收Java程序的请求后,根据操作类型(读/写)分发到不同数据库,同时对外提供逻辑库、逻辑用户、逻辑密码,让Java程序无需感知后端真实数据库的差异,像连接单库一样操作
数据库层
所有写操作(增删改)路由到 mysql-master(主库);
所有读操作(查询)分发到 mysql-slave1(从库) (或 mysql-slave2可选),实现读压力分摊

整体架构通过“主库写+从库读”的分工,结合MyCat的路由能力,实现了数据库读写压力的分离,从而提升系统性能和可用性


三、读写分离实战

3.1 环境介绍

环境介绍:做实验前需同步时间,最好每台机器都ntpdate ntp.aliyun.***一下,防火墙需要关闭或者开启3306和8066端口

主机名 ip地址 服务 系统
mycat 192.168.136.20 mycat CentOs
mysql-master 192.168.136.10 mysql5.7.27 CentOs
mysql-slave1 192.168.136.134 mysql5.7.24 Ubuntu
mysql-slave2(可选) 192.168.136.135 mysql5.7.24 Ubuntu

说明:教程中我用了CentOS和Ubuntu只是因为我刚好只有这四台测试机,其实不用纠结系统选型,只要保证MySQL版本一致,其余操作完全相同,不管你用什么系统,这个教程都适用


3.2 安装mycat

mycat 是使用 JAVA语言进行编写开发,使用前需要先安装 JAVA 运行环境(JRE),由于 MyCAT 中使用了 JDK7 中的一些特性,所以要求必须在 JDK7 以上的版本上运行

3.2.1 安装jdk环境

官网下载地址:https://www.oracle.***/java/technologies/downloads/#java8

[root@mycat ~]# tar xf jdk-8u211-linux-x64.tar.gz -C /usr/local
[root@mycat ~]# cd /usr/local
[root@mycat local]# ls
bin  etc  games  include  jdk1.8.0_211  lib  lib64  libexec  sbin  share  src
[root@mycat local]# mv jdk1.8.0_211/ java
[root@mycat local]# vim /etc/profile   #配置环境变量
JAVA_HOME=/usr/local/java
PATH=$JAVA_HOME/bin:$PATH
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
[root@mycat local]# source /etc/profile
[root@mycat ~]# java -version   #验证
java version "1.8.0_211"
Java(TM) SE Runtime Environment (build 1.8.0_211-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.211-b12, mixed mode)

3.2.2 安装mycat

MyCat官网:http://www.mycat.org.***/

[root@mycat ~]# tar xf Mycat-server-1.6.7.5-release-20200422133810-linux.tar.gz -C /usr/local/
#待会我们要改的就是schema.xml和server.xml这两个文件
[root@mycat ~]# ls /usr/local/mycat/conf/
autopartition-long.txt      dnindex.properties           partition-hash-int.txt       sequence_distributed_conf.properties  zkconf
auto-sharding-long.txt      ehcache.xml                  partition-range-mod.txt      sequence_http_conf.properties         zkdownload
auto-sharding-rang-mod.txt  index_to_charset.properties  rule.xml                     sequence_time_conf.properties
cacheservice.properties     log4j2.xml                   schema.xml                   server.xml
dbseq.sql                   migrateTables.properties     sequence_conf.properties     sharding-by-enum.txt
dbseq - utf8mb4.sql         myid.properties              sequence_db_conf.properties  wrapper.conf
[root@mycat ~]# 

3.3 主数据库创建写用户

主库创建写用户,用于配置到mycat的schema.xml中,供mycat接收到Java程序请求的写操作时会登录此用户的数据库进行写操作

[root@mysql-master ~]# mysql -p'Qing@123'
mysql> create database tmpdb;

mysql> grant all on tmpdb.* to writeuser@'%' identified by 'Writeuser@123';

mysql> flush privileges;

3.4 从数据库创建读用户

从库创建读用户,用于配置到mycat的schema.xml中,供mycat接收到Java程序请求的读操作时会登录此用户的数据库进行读操作

#slave1创建读用户
root@mysql-slave1:~# mysql -p'Qing@123'
mysql> create database tmpdb;

mysql> grant all on tmpdb.* to readuser@'%' identified by 'Readuser@123';

mysql> flush privileges;
#slave2创建读用户(可选)
root@mysql-slave2:~# mysql -p'Qing@123'
mysql> create database tmpdb;

mysql> grant all on tmpdb.* to readuser@'%' identified by 'Readuser@123';

mysql> flush privileges;

3.5 修改server.xml文件

#修改前强烈建议先备份一份,待会改错了还有拯救的余地
[root@mycat mycat]# cp  /usr/local/mycat/conf/server.xml /tmp/server.xml   
[root@mycat mycat]# vim /usr/local/mycat/conf/server.xml  #直接看文件最后进行修改

3.6 修改schema.xml文件

[root@mycat mycat]# cp /usr/local/mycat/conf/schema.xml /tmp/schema.xml
#schema.xml中有很多需要删掉或者修改的地方,大家如果嫌麻烦可以直接复制下面代码,然后改一些关键的东西即可
[root@mycat mycat]# vim /usr/local/mycat/conf/schema.xml  
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">

        <schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn1" >
        </schema>
        <dataNode name="dn1" dataHost="localhost1" database="tmpdb" />

        <dataHost name="localhost1" maxCon="1000" minCon="10" balance="3"
                          writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
                <heartbeat>select user()</heartbeat>
                <writeHost host="hostM1" url="192.168.136.10:3306" user="writeuser"
                                   password="Writeuser@123">
                        <readHost host="hostS2" url="192.168.136.134:3306" user="readuser" password="Readuser@123" />
                        <readHost host="hostS3" url="192.168.136.135:3306" user="readuser" password="Readuser@123" />
                </writeHost>
        </dataHost>
</mycat:schema>
[root@mycat mycat]# 

3.7 启动mycat

3.7.1 调整JVM

[root@mycat ~]# vim /usr/local/mycat/conf/wrapper.conf  #添加一行
wrapper.startup.timeout=300   #超时时间300秒 

3.7.2 启动mycat

 [root@mycat ~]# /usr/local/mycat/bin/mycat start   #启动mycat,需要稍微等一会
Starting Mycat-server...
[root@mycat ~]# jps  #查看mycat是否启动,如果出现WrapperSimpleApp表示成功,这里mycat没有启动成功
6118 Jps
[root@mycat ~]# tail -f /usr/local/mycat/wrapper.log   #查看错误日志,显示没有logs目录
FATAL  | wrapper  | 2025/11/08 13:49:01 | ERROR: Could not write pid file /usr/local/mycat/logs/mycat.pid: No such file or directory
FATAL  | wrapper  | 2025/11/08 13:50:13 | ERROR: Could not write pid file /usr/local/mycat/logs/mycat.pid: No such file or directory
^C
[root@mycat ~]# mkdir -p /usr/local/mycat/logs  #创建目录
[root@mycat ~]# chown mysql.mysql /usr/local/mycat/logs   
[root@mycat ~]# /usr/local/mycat/bin/mycat start
Starting Mycat-server...
[root@mycat ~]# jps   #启动成功
6229 Jps
6203 WrapperSimpleApp

3.8 测试读写分离

测试读写是否分离,连接mycat,然后创建数据看看能不能查到
正常情况时mycat接受写请求时会分发给master数据库,读请求会分发给slave数据库,所以在没做主从同步的情况下,插入数据之后master数据库中有数据,而slave上没数据,证明读写分离成功

#用我们在server.xml中配置的逻辑用户和密码登录  
# -h mycat的ip地址  -P mycat端口
[root@mycat ~]# mysql -uroot -p'123456' -h 192.168.136.20 -P 8066   

mysql> show databases;  #这里显示的是逻辑库,对应实际上的tmpdb库
+----------+
| DATABASE |
+----------+
| TESTDB   |
+----------+

mysql> use TESTDB;   

mysql> create table student(id int);

mysql> insert into student values(1);

mysql> select * from student;   #查询不到数据
ERROR 1146 (HY000): Table 'tmpdb.student' doesn't exist
#master数据库
[root@mysql-master ~]# mysql -p'Qing@123'
mysql> use tmpdb;

mysql> select * from student;  #由于写操作是分配到了master数控,所以master数据库上肯定有数据
+------+
| id   |
+------+
|    1 |
+------+
#slave1数据库
root@mysql-slave1:~# mysql -p'Qing@123'
mysql> use tmpdb;

mysql> select * from student;  #slave1数据库只接受读操作,所以查不到数据,证明读写分离成功
ERROR 1146 (42S02): Table 'tmpdb.student' doesn't exist
#slave2数据库一样查不到数据
root@mysql-slave2:~# mysql -p'Qing@123'
mysql> use tmpdb;

mysql> select * from student;  
ERROR 1146 (42S02): Table 'tmpdb.student' doesn't exist

3.9 配置主从同步

我们已成功实现读写分离,但生产环境中还需搭配主从同步。这样一来,写入主库的数据会自动同步到从库,从库始终有最新数据可供查询,真正实现后端数据库的读写压力分担,发挥读写分离的核心价值

我这就不详细将怎么做主从同步了,我之前发过一篇文章,里面详细记录主从同步的两种方法,不会的小伙伴可以参考这篇https://blog.csdn.***/m0_63756214/article/details/154487592?spm=1001.2014.3001.5501


3.10 测试主从同步

主从同步已经做好了,现在来测试

[root@mycat ~]# mysql -uroot -p'123456' -h 192.168.136.20 -P 8066   #连接mycat

mysql> use TESTDB;

mysql> show tables;
+-----------------+
| Tables_in_tmpdb |
+-----------------+
| class           |
| student         |
+-----------------+

mysql> create table employees(id int,name varchar(20));  

mysql> insert into employees values(1,'lisa'),(2,'tom');  #插入数据

mysql> select * from employees;  #查看数据,实现了主从同步和读写分离,实验完成
+------+------+
| id   | name |
+------+------+
|    1 | lisa |
|    2 | tom  |
+------+------+

注:
文中若有疏漏,欢迎大家指正赐教。
本文为100%原创,转载请务必标注原创作者,尊重劳动成果。
求赞、求关注、求评论!你的支持是我更新的最大动力,评论区等你~
后续会持续分享MySQL相关知识。

转载请说明出处内容投诉
CSS教程网 » 【MySQL 读写分离实战教程:基于 Mycat 中间件,从环境搭建、JDK 与 Mycat 安装、用户配置、server.xml 与 schema.xml 文件修改,到读写分离,主从同步结果验证】

发表评论

欢迎 访客 发表评论

一个令你着迷的主题!

查看演示 官网购买