mycat学习-2 数据库的读写分离
1.读写分离
读和写的操作分开对应到不同的数据库服务器,可以有效的缓解数据库亚丽,减轻IO压力
主提供写,从提供读,当主进行写操作的时候数据同步到从数据库,这样才能有效保证主从数据库数据的完整性。
2.环境搭建
此处不讲解linux环境,本次在windows环境利用zip的方式配置的主从数据库
mysql官网下载zip文件并解压
安装mysql3和mysql4、mysql5: 解压mysql压缩包并修改my-default.ini为my.ini 并在[mysqld]下设置datadir和basedir以及port
[mysqld]
basedir=D:/software/mysql/mysql4
datadir=D:/software/mysql/mysql4/data
port=3309
安装mysql : D:\software\mysql\mysql4\bin>mysqld install MySQL4 --defaults-file="D:\software\mysql\mysql4\my.ini"
D:\software\mysql\mysql4\bin>net start mysql4
D:\software\mysql\mysql4\bin>mysql -uroot -p -P3309
mysql3同上述安装步骤一致
3.mycat实现读写分离配置
1>server.xml文件配置
------------------------------------------------------------------------------------------------------------
启动成功的server.xml文件的内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<!-- - - Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License. - You
may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0
- - Unless required by applicable law or agreed to in writing, software -
distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the
License for the specific language governing permissions and - limitations
under the License. -->
<!DOCTYPE mycat:server SYSTEM "server.dtd">
<mycat:server xmlns:mycat="http://io.mycat/">
<system>
<property name="useSqlStat">0</property> <!-- 1为开启实时统计、0为关闭 -->
<property name="useGlobleTableCheck">0</property> <!-- 1为开启全加班一致性检测、0为关闭 -->
<property name="sequnceHandlerType">2</property>
<!-- <property name="useCompression">1</property>--> <!--1为开启mysql压缩协议-->
<!-- <property name="fakeMySQLVersion">5.6.20</property>--> <!--设置模拟的MySQL版本号-->
<!-- <property name="processorBufferChunk">40960</property> -->
<!--
<property name="processors">1</property>
<property name="processorExecutor">32</property>
-->
<!--默认为type 0: DirectByteBufferPool | type 1 ByteBufferArena-->
<property name="processorBufferPoolType">0</property>
<!--默认是65535 64K 用于sql解析时最大文本长度 -->
<!--<property name="maxStringLiteralLength">65535</property>-->
<!--<property name="sequnceHandlerType">0</property>-->
<!--<property name="backSocketNoDelay">1</property>-->
<!--<property name="frontSocketNoDelay">1</property>-->
<!--<property name="processorExecutor">16</property>-->
<!--
<property name="serverPort">8066</property> <property name="managerPort">9066</property>
<property name="idleTimeout">300000</property> <property name="bindIp">0.0.0.0</property>
<property name="frontWriteQueueSize">4096</property> <property name="processors">32</property> -->
<!--分布式事务开关,0为不过滤分布式事务,1为过滤分布式事务(如果分布式事务内只涉及全局表,则不过滤),2为不过滤分布式事务,但是记录分布式事务日志-->
<property name="handleDistributedTransactions">0</property>
<!--
off heap for merge/order/group/limit 1开启 0关闭
-->
<property name="useOffHeapForMerge">1</property>
<!--
单位为m
-->
<property name="memoryPageSize">1m</property>
<!--
单位为k
-->
<property name="spillsFileBufferSize">1k</property>
<property name="useStreamOutput">0</property>
<!--
单位为m
-->
<property name="systemReserveMemorySize">384m</property>
<!--是否采用zookeeper协调切换 -->
<property name="useZKSwitch">true</property>
</system>
<!-- 全局SQL防火墙设置 -->
<!--
<firewall>
<whitehost>
<host host="127.0.0.1" user="mycat"/>
<host host="127.0.0.2" user="mycat"/>
</whitehost>
<blacklist check="false">
</blacklist>
</firewall>
-->
<user name="mycat2">
<property name="password">123456</property>
<property name="schemas">mycatdb2</property>
<!-- 表级 DML 权限设置 -->
<!--
<privileges check="false">
<schema name="TESTDB" dml="0110" >
<table name="tb01" dml="0000"></table>
<table name="tb02" dml="1111"></table>
</schema>
</privileges>
-->
</user>
<user name="user">
<property name="password">user</property>
<property name="schemas">mycatdb2</property>
<property name="readOnly">true</property>
</user>
</mycat:server>
------------------------------------------------------------------------------------------------------------
<!-- 全局SQL防火墙设置whitehost是白名单配置,blacklist是黑名单配置 -->
<!--
<firewall>
<whitehost>
<host host="127.0.0.1" user="mycat"/>
<host host="127.0.0.2" user="mycat"/>
</whitehost>
<blacklist check="false">
</blacklist>
</firewall>
-->
<user name="mycat">--更改mycat的用户名
<property name="password">123456</property>
<!-- mycat的逻辑数据库,逻辑数据库是虚拟的数据库不是真实存在的,但是可以对应真实的数据库 -->
<property name="schemas">mycatdatabase</property>
<!-- 表级 DML 权限设置 --> 0是没有增删改查的权限 1是有的
<!--
<privileges check="false">
<schema name="mycatdatabase" dml="0110" >
<table name="tb01" dml="0000"></table>
<table name="tb02" dml="1111"></table>
</schema>
</privileges>
-->
</user>
<user name="user">
<property name="password">user</property>
<property name="schemas">mycatdatabase</property>
<property name="readOnly">true</property>--只读的普通的查询用户
</user>
2>schema.xml文件-这个是配置的关键点
schema 用于配置逻辑数据库<只读写分离不用分库分表 那么不用配置table>
schema.xml文件的内容如下:
----------------------------------------------------------------------------------------------------
启动成功的mycat对应的schema.xml文件内容如下:
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
<!--
schema用户配置逻辑数据库 只做读写分离不做分库分表,schema中不需要配置表;给schema标签加上属性datanode配置datanode的名字(name)
最终的配置如下:
-->
<schema name="mycatdb2" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn2"></schema>
<!--
配置datanode,datanode定义了mycat中的数据节点<定义真实的物理数据库>,也就是我们通常说的数据分片,一个datanode
标签就是一个独立的数据分片,通俗理解,一个分片就是一个物理数据库database就是
实际的数据库名称;
<dataNode name="dn1" dataHost="localhost1" database="test01" />
配置说明:
name:定义数据节点的名称,这个名称需要是唯一的,这个名称在schema里面会使用到;
dataHost:用于定义该分片属于哪个数据库实例的,属性值是引用dataHost标签上定义的name属性
database:用于对应真实的数据库名,必须是真实存在的;
最终配置如下:
-->
<dataNode name="dn2" dataHost="localhost" database="test"></dataNode>
<!--
配置dataHost 定义具体的数据库实例、读写分离配置和心跳语句
<dataHost name="localhost1" 名称上面使用
maxCon="1000" 最大连接数
minCon="1"
balance="1" 负载均衡(改成1代表开启读写分离模式)目前的取值有4种:
0:不开启读写分离机制,所有读操作都发送到当前可用的writeHost上
1:全部的readHost与stand by writeHost<既是主又是从以下是3307和3308>参与select语句的负载均衡,简单的说就是当双主双从模式(M1->S1,M2->S2,并且M1与M2互为主备)正常情况下,当M1是写的时候,M2,S1,S2都参与
2:所有读操作都随机的在writeHost、readHost上分发
3:所有读请求随机的分发到writeHost对应的readHost执行,writeHost不负担读压力
推荐balance设置为1
dbType="mysql" 数据库类型
dbDriver="native" 数据库驱动 native代表本地驱动
switchType="1" 故障切换
-1表示不自动切换
1默认值 自动切换 心跳语句为 select user() 使用的比较多
2基于mysql主从同步的状态决定是否切换 心跳语句为 show slave status
3基于mysql galary cluster模式的切换机制(适合集群) 心跳语句 show status like 'wsrep%'
通常使用1自动切换,因为双主双从的模式2 3 比较复杂不适用
slaveThreshold="100"> 读写分离从服务器的最大个数
<heartbeat>select user()</heartbeat>心跳语句 mycat每隔一段时间会给mysql发送一条命令 检测mysql是否有响应 是否正常
writeHost 配置写数据库(主库),有几个主库就配置几个writeHost
<writeHost host="hostM3307" url="localhost:3307" user="root" password="111111">
配置读数据库(从库)
<readHost host="hosts3308" url="localhost:3308" user="root" password="111111">
<readHost host="hosts3309" url="localhost:3309" user="root" password="111111">
</writeHost>
<writeHost host="hostM3308" url="localhost:3308" user="root" password="111111">
配置读数据库(从库)
<readHost host="hosts3307" url="localhost:3307" user="root" password="111111">
<readHost host="hosts3310" url="localhost:3310" user="root" password="111111">
</writeHost>
</dataHost>
-->
<dataHost name="localhost"
maxCon="1000"
minCon="1"
balance="1"
dbType="mysql"
dbDriver="native"
switchType="1"
slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<!--配置写数据库(主库),有几个主库就配置几个writeHost -->
<writeHost host="hostM3308" url="localhost:3308" user="root" password="">
<!--配置读数据库(从库)-->
<readHost host="hosts3309" url="localhost:3309" user="root" password=""/>
<readHost host="hosts3310" url="localhost:3310" user="root" password=""/>
</writeHost>
</dataHost>
</mycat:schema>
----------------------------------------------------------------------------------------------------
一主两从的配置
双主双从的配置:
3.mycat读写分离测试验证:
将配置文件覆盖,windows环境下 cmd到mycat的bin目录,我的文件目录是D:\software\Mycat\mycat2\bin
输入命令 startup_nowrap.bat 启动mycat,代表启动成功
在mysql的目录下:利用mysql的命令登录mycat 用户名和密码是配置到mycat的server.xml文件中的
D:\software\mysql\mysql5\bin>mysql -umycat2 -p -P8066 -h127.0.0.1
在mycat重启之后,输入上述命令登录mycat成功后,查看虚拟的数据库,可以看到有mycatdb,这个是schema.xml文件中配置的schema标签的name属性对应的值
通过navicate连接 localhost:3308和localhost:3309 localhost:3310 然后分别在各自的test库中创建相同的表student表:
mysql3<3308>中的数据是
mysql4<3309>中的数据是
mysql5<3310>中的数据是
mysql> select * from student;发现查出来的数都是从库 3309和3310的
验证主库的功能: id=3是从库但是主库不存在的,0 rows不受影响,所以删除没成功
发现id=2的是删除成功了;
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理