
MySQL数据库之读写分离
MySQL数据库之读写分离
一、数据库分类
数据库主要分为两大类:关系型数据库与 NoSQL 数据库。
关系型数据库,是建立在关系模型基础上的数据库,其借助于集合代数等数学概念和方法来处理数据库中的数据。主流的 MySQL、Oracle、MS SQL Server 和 DB2 都属于这类传统数据库。
NoSQL 数据库,全称为 Not Only SQL,意思就是适用关系型数据库的时候就使用关系型数据库,不适用的时候也没有必要非使用关系型数据库不可,可以考虑使用更加合适的数据存储。主要分为临时性键值存储(memcached、Redis)、永久性键值存储(ROMA、Redis)、面向文档的数据库(MongoDB、CouchDB)面向列的数据库(Cassandra、HBase),每种 NoSQL 都有其特有的使用场景及优点。
Oracle,mysql 等传统的关系数据库非常成熟并且已大规模商用,为什么还要用 NoSQL 数据库呢?主要是由于随着互联网发展,数据量越来越大,对性能要求越来越高,传统数据库存在着先天性的缺陷,即单机(单库)性能瓶颈,并且扩展困难。这样既有单机单库瓶颈,却又扩展困难,自然无法满足日益增长的海量数据存储及其性能要求,所以才会出现了各种不同的 NoSQL 产品,NoSQL 根本性的优势在于在云计算时代,简单、易于大规模分布式扩展,并且读写性能非常高
RDBMS和NOSQL的特点及优缺点:
二、MySQL读写分离
2.1 什么是MySQL的读写分离?
Mysql作为目前世界上使用最广泛的免费数据库,相信所有从事系统运维的工程师都一定接触过。但在实际的生产环境中,由单台Mysql作为独立的数据库是完全不能满足实际需求的,无论是在安全性,高可用性以及高并发等各个方面。
因此,一般来说都是通过 主从复制(Master-Slave)的方式来同步数据,再通过读写分离(MySQL-Proxy/Amoeba/Mycat)来提升数据库的并发负载能力 这样的方案来进行部署与实施的。
2.2 MySQL读写分离的原理
基本的原理是让主数据库处理事务性增、改、删操作(INSERT、UPDATE、DELETE),而从数据库处理SELECT查询操作。数据库复制被用来把事务性操作导致的变更同步到集群中的从数据库。
2.3 内部数据交换过程
通过部署MySQL主从同步集群,当有业务请求过来,会先进行语句分析,如果是查询的语句,会转发给从服务器进行处理,如果是写的数据,则转交给主服务器进行处理,在一般的网站上,绝大部分的请求是读请求要大于写的请求的,因此为了缓解从服务器的压力,因此可以部署成M-S-S的模式。
2.4 为什么要做读写分离?
面对越来越大的访问压力,单台的服务器的性能成为瓶颈,需要分担负载
1、 主从只负责各自的写和读,极大程度的缓解X锁(排它锁)和S锁(共享锁)争用
2、 从库可配置myisam引擎,提升查询性能以及节约系统开销
3、 增加冗余,提高可用性
4、应用程序和数据库强耦合
2.5 实现读写分离的方式
一般有两种方式实现:
1)应用程序层实现,网站的程序实现
应用程序层实现指的是在应用程序内部及连接器中实现读写分离
优点:
1:应用程序内部实现读写分离,安装既可以使用
2:减少一定部署难度
3:访问压力在一定级别以下,性能很好
缺点:
1:架构一旦调整,代码要跟着变
2:难以实现高级应用,如自动分库,分表
3:无法适用大型应用场景
2)中间件层实现
中间件:是一类连接软件组件和应用的计算机软件,以便于软件之间各部分之间的沟通
1、 mysql-proxy:Oracle,https://downloads.mysql.com/archives/proxy/
2、 Atlas:Qihoo,https://github.com/Qihoo360/Atlas/blob/master/README_ZH.md
3、 dbproxy:美团,https://github.com/Meituan-Dianping/DBProxy
4、 Cetus:网易乐得,https://github.com/Lede-Inc/cetus
5、 Amoeba:https://sourceforge.net/projects/amoeba/
6、 Cobar:阿里巴巴,Amoeba的升级版, https://github.com/alibaba/cobar
7、 Mycat:基于Cobar http://www.mycat.io/ (原网站)
http://www.mycat.org.cn/
https://github.com/MyCATApache/Mycat-Server
8、 ProxySQL:https://proxysql.com/
三、MYCAT
3.1 什么是mycat?
1)一个彻底开源的,面向企业应用开发的大数据库集群
2)支持事务、ACID、可以替代MySQL的加强版数据库
3) 一个可以视为MySQL集群的企业级数据库,用来替代昂贵的Oracle集群
4)一个融合内存缓存技术、NoSQL技术、HDFS大数据的新型SQL Server
5)结合传统数据库和新型分布式数据仓库的新一代企业级数据库产品
6)一个新颖的数据库中间件产品
3.2 mycat的主要功能
3.2.1 mycat读写分离
3.2.2 分库分表
简单来说,就是指通过某种特定的条件,将我们存放在同一个数据库中的数据分散存放到多个数据库(主机) 上面,以达到分散单台设备负载的效果。
数据的切分(Sharding)根据其切分规则的类型,可以分为两种切分模式。
一种是按照不同的表(或者 Schema)来切分到不同的数据库(主机)之上,这种切可以称之为数据的垂直(纵向)切分;另外一种则是根据 表中的数据的逻辑关系,将同一个表中的数据按照某种条件拆分到多台数据库(主机)上面,这种切分称之为数据的水平(横向)切分。
垂直切分的最大特点就是规则简单,实施也更为方便,尤其适合各业务之间的耦合度非常低,相互影响很小, 业务逻辑非常清晰的系统。在这种系统中,可以很容易做到将不同业务模块所使用的表分拆到不同的数据库中。 根据不同的表来进行拆分,对应用程序的影响也更小,拆分规则也会比较简单清晰。
水平切分于垂直切分相比,相对来说稍微复杂一些。因为要将同一个表中的不同数据拆分到不同的数据库中, 对于应用程序来说,拆分规则本身就较根据表名来拆分更为复杂,后期的数据维护也会更为复杂一些。
3.2.2.1 垂直切分
一个数据库由很多表的构成,每个表对应着不同的业务,垂直切分是指按照业务将表进行分类,分布到不同的数据库上面,这样也就将数据或者说压力分担到不同的库上面,如下图:
系统被切分成了,用户,订单交易,支付几个模块。 一个架构设计较好的应用系统,其总体功能肯定是由很多个功能模块所组成的,而每一个功能模块所需要的数据对应到数据库中就是一个或者多个表。而在架构设计中,各个功能模块相互之间的交互点越统一越少,系统的耦合度就越低,系统各个模块的维护性以及扩展性也就越好。这样的系统,实现数据的垂直切分也就越容易。
但是往往系统之有些表难以做到完全独立,存在着跨库 join 的情况,对于这类表,就需要去做平衡,是数据库让步业务,共用一个数据源,还是分成多个库,业务之间通过接口来做调用。在系统初期,数据量比较 少,或者资源有限的情况下,会选择共用数据源,但是当数据发展到了一定的规模,负载很大的情况,就需要必须去做分割。
一般来讲业务存在着复杂 join 的场景是难以切分的,往往业务独立的易于切分。如何切分,切分到何种程度是考验技术架构的一个难题。
垂直切分的优缺点
优点:
- 拆分后业务清晰,拆分规则明确
- 系统之间整合或扩展容易
- 数据维护简单
缺点:
- 部分业务表无法 join,只能通过接口方式解决,提高了系统复杂度
- 受每种业务不同的限制存在单库性能瓶颈,不易数据扩展跟性能提高
- 事务处理复杂
由于垂直切分是按照业务的分类将表分散到不同的库,所以有些业务表会过于庞大,存在单库读写与存 储瓶颈,所以就需要水平拆分来做解决。
3.2.2.2 水平切分
对应shard中查询相关数据
相对于垂直拆分,水平拆分不是将表做分类,而是按照某个字段的某种规则来分散到多个库之中,每个表中包含一部分数据。简单来说,我们可以将数据的水平切分理解为是按照数据行的切分,就是将表中的某些行切分 到一个数据库,而另外的某些行又切分到其他的数据库中,如图:
拆分数据就需要定义分片规则。关系型数据库是行列的二维模型,拆分的第一原则是找到拆分维度。比如: 从会员的角度来分析,商户订单交易类系统中查询会员某天某月某个订单,那么就需要按照会员结合日期来拆分, 不同的数据按照会员 ID 做分组,这样所有的数据查询 join 都会在单库内解决;如果从商户的角度来讲,要查询某个商家某天所有的订单数,就需要按照商户 ID 做拆分;但是如果系统既想按会员拆分,又想按商家数据,则会有 一定的困难。如何找到合适的分片规则需要综合考虑衡量。
几种典型的分片规则包括:
- 按照用户 ID 求模,将数据分散到不同的数据库,具有相同数据用户的数据都被分散到一个库中
- 按照日期,将不同月甚至日的数据分散到不同的库中
- 按照某个特定的字段求摸,或者根据特定范围段分散到不同的库中
如图,切分原则都是根据业务找到适合的切分规则分散到不同的库,下面用用户 ID 求模举例:
既然数据做了拆分有优点也就优缺点。
**水平切分的优缺点 **
优点:
- 拆分规则抽象好,join 操作基本可以数据库做
- 不存在单库大数据,高并发的性能瓶颈
- 应用端改造较少
- 提高了系统的稳定性跟负载能力
缺点:
- 拆分规则难以抽象
- 分片事务一致性难以解决
- 数据多次扩展难度跟维护量极大
- 跨库 join 性能较差
3.2.3 多数据源整合
针对数据源管理,目前主要有两种思路:
A. 客户端模式,在每个应用程序模块中配置管理自己需要的一个(或者多个)数据源,直接访问各个数据库, 在模块内完成数据的整合
B. 通过中间代理层来统一管理所有的数据源,后端数据库集群对前端应用程序透明; 可能 90%以上的人在面对上面这两种解决思路的时候都会倾向于选择第二种,尤其是系统不断变得庞大复杂 的时候。确实,这是一个非常正确的选择,虽然短期内需要付出的成本可能会相对更大一些,但是对整个系统的 扩展性来说,是非常有帮助的。
MySQL中间件服务器可以通过将数据切分解决传统数据库的缺陷,又有了 NoSQL 易于扩展的优点。通过中间代理层规避了多数 据源的处理问题,对应用完全透明,同时对数据切分后存在的问题,也做了解决方案。
由于数据切分后数据 Join 的难度在此也分享一下数据切分的经验:
第一原则:能不切分尽量不要切分
第二原则:如果要切分一定要选择合适的切分规则,提前规划好。
第三原则:数据切分尽量通过数据冗余或表分组(Table Group)来降低跨库 Join 的可能
第四原则:由于数据库中间件对数据 Join 实现的优劣难以把握,而且实现高性能难度极大,业务读取尽量少使用多表 Join。
3.3 mycat原理
Mycat的原理中最重要的一个动词是“拦截”,它拦截了用户发送过来的SQL语句,首先对SQL语句做了一些特定的分析:如分片分析、路由分析、读写分离分析、缓存分析等,然后将此SQL发往后端的真实数据库,并将返回的结果做适当的处理,最终再返回给用户。
3.4 部署读写分离(一主一从架构)
角色 | IP | 数据库版本 | 操作系统版本 |
---|---|---|---|
mycat | 192.168.1.101 | 无 | CentOS7.9 |
master | 192.168.1.102 | mysql5.7.36 | CentOS7.9 |
slave | 192.168.1.103 | mysql5.7.36 | CentOS7.9 |
MyCAT有提供编译好的安装包,支持windows、Linux、Mac、Solaris等系统上安装与运行。
官方下载主页:http://www.mycat.org.cn/
3.4.1 安装JDK 1.7 或者以上版本
[root@mycat ~]# tar zxvf jdk-8u311-linux-x64.tar.gz -C /usr/local/src/
[root@mycat ~]# vim /etc/profile
#添加如下内容
JAVA_HOME=/usr/local/src/jdk1.8.0_311
JAVA_BIN=$JAVA_HOME/bin
JRE_HOME=$JAVA_HOME/jre
JRE_BIN=$JRE_HOME/bin
PATH=$JAVA_BIN:$JRE_BIN:$PATH
CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib
export JAVA_HOME JRE_HOME PATH CLASSPATH
[root@mycat ~]# source /etc/profile
[root@mycat ~]# java -version
java version "1.8.0_311"
Java(TM) SE Runtime Environment (build 1.8.0_311-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.311-b11, mixed mode)
3.4.2 部署Mycat
[root@mycat ~]# tar zxvf Mycat-server-1.6.7.6-test-20201124193646-linux.tar.gz -C /usr/local/
linux下可以下载Mycat-server-xxxxx.linux.tar.gz 解压在某个目录下,注意目录不能有空格,在Linux(Unix)下,建议放在usr/local/Mycat目录下,如下:
[root@mycat mycat]# ll
total 12
drwxr-xr-x. 2 root root 190 Jun 15 14:36 bin
drwxrwxrwx. 2 root root 6 Jul 18 2019 catlet
drwxrwxrwx. 4 root root 4096 Jun 15 14:36 conf
drwxr-xr-x. 2 root root 4096 Jun 15 14:36 lib
drwxrwxrwx. 2 root root 6 Aug 28 2019 logs
-rwxrwxrwx. 1 root root 227 Aug 28 2019 version.txt
3.4.2.1 常见目录含义
bin 程序目录:存放了window版本和linux版本,除了提供封装成服务的版本之外,也提供了nowrap的shell脚本命令,方便大家选择和修改,进入到bin目录
Linux下运行:./mycat console,首先要chmod +x *
注:mycat支持的命令{ console | start | stop | restart | status | dump }
conf目录:存放配置文件,server.xml是Mycat服务器参数调整和用户授权的配置文件,schema.xml是逻辑库定义和表以及分片定义的配置文件,rule.xml是分片规则的配置文件,分片规则的具体一些参数信息单独存放为文件,也在这个目录下,配置文件修改,需要重启Mycat或者通过9066端口reload
lib目录:主要存放mycat依赖的一些jar文件.
log目录:每天一个文件,日志的配置是在conf/log4j.xml中,根据自己的需要,可以调整输出级别为debug,debug级别下,会输出更多的信息,方便排查问题.
3.4.2.2 mycat的几个配置文件
1)schema.xml:定义逻辑库,表,分片节点等内容
2)rule.xml:定义分片规则
3)server.xml:定义用户以及系统相关的变量,如端口,账号和密码等
3.4.2.3 配置环境变量
Mycat在Linux中部署启动时,首先需要在Linux系统的环境变量中配置MYCAT_HOME,操作方式如下:
1) vim /etc/profile,在系统环境变量文件中增加 MYCAT_HOME=/usr/local/mycat
2) 执行 source /etc/profile 命令,使环境变量生效。
如果是在多台Linux系统中组建的MyCAT集群,那需要在MyCAT Server所在的服务器上配置对其他ip和主机名的映射,配置方式如下:
vim /etc/hosts
例如:我有3台机器,配置如下:
192.168.1.101 mycat.com
192.168.1.102 master.com
192.168.1.103 slave.com
编辑完后,保存文件。
[root@slave ~]# ping mycat.com
PING mycat.com (192.168.1.101) 56(84) bytes of data.
64 bytes from mycat.com (192.168.1.101): icmp_seq=1 ttl=64 time=0.271 ms
[root@slave ~]# ping master.com
PING master.com (192.168.1.102) 56(84) bytes of data.
64 bytes from master.com (192.168.1.102): icmp_seq=1 ttl=64 time=0.331 ms
64 bytes from master.com (192.168.1.102): icmp_seq=2 ttl=64 time=0.518 ms
[root@slave ~]# ping slave.com
PING slave.com (192.168.1.103) 56(84) bytes of data.
64 bytes from slave.com (192.168.1.103): icmp_seq=1 ttl=64 time=0.019 ms
64 bytes from slave.com (192.168.1.103): icmp_seq=2 ttl=64 time=0.043 ms
3.4.3 编辑mycat的读写分离规则
3.4.3.1 编辑 conf/server.xml
文件,这里是存放的数据库的账号密码信息
<user name="root" defaultAccount="true"> #连接数据库的用户名
<property name="password">123456</property> #数据库的密码
<property name="schemas">HA</property> #连接的逻辑数据库
<property name="defaultScheddma">HA</property>
<!--No MyCAT Database selected 错误前会尝试使用该schema作为schema,不设置则为null,报错 -->
<!-- 表级 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">HA</property>
<property name="readOnly">true</property>
<property name="defaultSchema">HA</property>
</user>
3.4.3.2 编辑schema.xml
是最主要的配置项,此文件关联mysql读写分离策略,读写分离、分库分表策略、分片节点都是在此文件中配置的.MyCat作为中间件,它只是一个代理,本身并不进行数据存储,需要连接后端的MySQL物理服务器,此文件就是用来连接MySQL服务器的
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
<schema name="HA" checkSQLschema="true" sqlMaxLimit="100" dataNode='dn1'>
</schema>
<dataNode name="dn1" dataHost="host1" database="HA" />
<dataHost name="host1" maxCon="1000" minCon="10" balance="3"
writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<!-- can have multi write hosts -->
<writeHost host="hostM1" url="192.168.1.102:3306" user="root" #指定写主机
password="123456">
<!-- can have multi read hosts --> #指定读主机
<readHost host="hostS1" url="192.168.1.103:3306" user="root" password="123456" />
</writeHost>
</dataHost>
</mycat:schema>
schema.xml文件中配置的参数解释:
参数 说明
schema 数据库设置,此数据库为逻辑数据库,name与server.xml中schema对应
dataNode 分片信息,也就是分库相关配置
dataHost 物理数据库,真正存储数据的数据库
配置说明
name属性唯一标识dataHost标签,供上层的标签使用。
maxCon属性指定每个读写实例连接池的最大连接。也就是说,标签内嵌套的
writeHost、readHost标签都会使用这个属性的值来实例化出连接池的最大连接数。
minCon属性指定每个读写实例连接池的最小连接,初始化连接池的大小。
每个节点的属性逐一说明
schema:
属性 说明
name 逻辑数据库名,与server.xml中的schema对应
checkSQLschema 数据库前缀相关设置,建议看文档,这里暂时设为false
sqlMaxLimit select 时默认的limit,避免查询全表
table
属性 说明
name 表名,物理数据库中表名
dataNode 表存储到哪些节点,多个节点用逗号分隔。节点为下文dataNode设置的name
primaryKey 主键字段名,自动生成主键时需要设置
autoIncrement 是否自增
rule 分片规则名,具体规则下文rule详细介绍
dataNode
属性 说明
name 节点名,与table中dataNode对应
datahost 物理数据库名,与datahost中name对应
database 物理数据库中数据库名
dataHost
属性 说明
name 物理数据库名,与dataNode中dataHost对应
balance 均衡负载的方式
writeType 写入方式
dbType 数据库类型
heartbeat 心跳检测语句,注意语句结尾的分号要加
schema.xml文件中有三点需要注意:balance="1",writeType="0" ,switchType="1"
schema.xml中的balance的取值决定了负载均衡对非事务内的读操作的处理。balance 属性负载均衡类型,目前的取值有 4 种:
balance="0",不开启读写分离机制, 所有读操作都发送到当前可用的 writeHost 上。
balance="1",全部的 readHost与 stand by writeHost 参与 select 语句的负载均衡,简单的说,当双主双从模式(M1->S1, M2->S2,并且M1与M2 互为主备),正常情况下, M2,S1,S2 都参与 select 语句的负载均衡。
balance="2",所有读操作都随机的在 writeHost、 readhost 上分发。
balance="3",所有读请求随机的分发到 readhost 执行,writerHost 不负担读压力
writeType 属性,负载均衡类型,目前的取值有 3 种
writeType="0" 所有写操作发送到配置的第一个 writeHost,第一个挂了切到还生存的第二个writeHost。
writeType="1" 所有写操作都随机的发送到配置的 writeHost。
writeType="2" 没实现。
schema.xml中的writeType的取值决定了负载均衡对写操作的处理:
writeType="0":所有的写操作都发送到配置文件中的第一个write host。(第一个write host故障切换到第二个后,即使之后修复了仍然维持第二个为写库)。推荐取0值,不建议修改.
主从切换(双主failover):switchType 属性
如果细心观察schem.xml文件的话,会发现有一个参数:switchType,如下配置:
<dataHost name="237_15" maxCon="1000" minCon="10" balance="1" writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
参数解读
switchType="-1": 不自动切换
switchType="1": 默认值,自动切换
switchType="2": 基于MySQL主从同步的状态来决定是否切换。需修改heartbeat语句(即心跳语句):show slave status
指定后端连接的数据库类型,目前支持二进制的mysql协议,还有其他使用JDBC连接的数据库。例如:mongodb、oracle、spark等。
dbDriver属性指定连接后端数据库使用的
Driver,目前可选的值有native和JDBC。
使用native的话,因为这个值执行的是二进制的mysql协议,所以可以使用mysql和maridb。
其他类型的数据库则需要使用JDBC驱动来支持。从1.6版本开始支持postgresql的native原始协议。
这个标签内指明用于和后端数据库进行心跳检查的语句。例如,MYSQL可以使用select user(),Oracle可以使用select 1 from dual等。
这个标签还有一个connectionInitSql属性,主要是当使用Oracla数据库时,需要执行的初始化SQL语句就这个放到这里面来。例如:altersession set nls_date_format='yyyy-mm-dd hh24:mi:ss'
writeHost标签、readHost标签
这两个标签都指定后端数据库的相关配置给mycat,用于实例化后端连接池。
唯一不同的是:writeHost指定写实例、readHost指定读实例,组着这些读写实例来满足系统的要求。
在一个dataHost内可以定义多个writeHost和readHost。但是,如果writeHost指定的后端数据库宕机,那么这个writeHost绑定的所有readHost都将不可用。另一方面,由于这个writeHost宕机系统会自动的检测到,并切换到备用的writeHost上去。
3.4.4 调试mycat
经过以上两个步骤的配置,就可以到/usr/local/mycat/bin 目录下执行:
[root@mycat bin]# ./mycat start ##Usage: ./mycat { console | start | stop | restart | status | dump }
Starting Mycat-server...
也可以调试查看是否有报错,可以执行:
[root@mycat bin]# ./mycat console
Running Mycat-server...
wrapper | --> Wrapper Started as Console
wrapper | Launching a JVM...
jvm 1 | Wrapper (Version 3.2.3) http://wrapper.tanukisoftware.org
jvm 1 | Copyright 1999-2006 Tanuki Software, Inc. All Rights Reserved.
jvm 1 |
jvm 1 | MyCAT Server startup successfully. see logs in logs/mycat.log ##看到有“ successfully”说明启动成功
3.4.5 部署后端数据库
3.4.5.1安装Mysql(master和slave数据库都要安装)
[root@master ~]# ~]# wget -i -c http://dev.mysql.com/get/mysql57-community-release-el7-10.noarch.rpm
##使用上面的命令就直接下载了安装用的Yum Repository,大概25KB的样子,然后就可以直接yum安装了。
[root@master ~]# yum -y install mysql57-community-release-el7-10.noarch.rpm
##之后就开始安装MySQL服务器。
[root@master ~]# yum -y install mysql-community-server
##这步可能会花些时间,安装完成后就会覆盖掉之前的mariadb。
3.4.5.2 使用临时密码登录,并重置密码,并关闭密码审计强度
mysql> set global validate_password_policy=0;
Query OK, 0 rows affected (0.00 sec)
mysql> set global validate_password_length=6;
Query OK, 0 rows affected (0.00 sec)
mysql> set password for 'root'@'localhost'=password('123456');
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> quit
Bye
[root@master ~]# mysql -uroot -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.7.36 MySQL Community Server (GPL)
Copyright (c) 2000, 2021, 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> quit
Bye
[root@master ~]#
3.4.5.3 编辑主数据库My.cnf文件,并重启数据库
##加入下面,并重启服务
log-bin=mysql-bin-master #启用二进制日志
server-id=1 #本机数据库ID 标示
binlog-do-db=HA #可以被从服务器复制的库。二进制需要同步的数据库名
binlog-ignore-db=mysql #不可以被从服务器复制的库
validate-password=off
[root@master ~]# systemctl restart mysqld
3.4.5.4 配置主服务器,创建库和表,用于写操作
mysql> create database HA;
Query OK, 1 row affected (0.00 sec)
mysql> use HA;
Database changed
mysql> create table u1(id int,name varchar(128));
Query OK, 0 rows affected (0.00 sec)
mysql> insert into u1 values(1,"zhangsan");
Query OK, 1 row affected (0.00 sec)
3.4.5.5 授权从服务器复制连接账号
mysql> grant replication slave on *.* to slave@"192.168.1.%" identified by "123456";
Query OK, 0 rows affected, 1 warning (0.00 sec)
3.4.5.6 将数据库信息导出,导入到从库
[root@master ~]# mysqldump -uroot -p123456 -B HA>HA.sql
mysqldump: [Warning] Using a password on the command line interface can be insecure.
[root@master ~]# ls
anaconda-ks.cfg HA.sql mysql57-community-release-el7-10.noarch.rpm
3.4.5.7 将数据库传给从库
[root@master ~]# scp HA.sql 192.168.1.103:/root
The authenticity of host '192.168.1.102 (192.168.1.103)' can't be established.
ECDSA key fingerprint is SHA256:N8H4e2TVds/6VVyoE1RgKuXAXwgRPODlnVzjGrcen28.
ECDSA key fingerprint is MD5:1d:fd:db:8a:47:2c:a5:14:09:67:3e:e3:cf:8c:9e:39.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.1.103' (ECDSA) to the list of known hosts.
root@192.168.1.103's password:
HA.sql 100% 1937 6.1MB/s 00:00
3.4.5.8 在从库将数据库导入,用于实现读操作
mysql> create database HA;
Query OK, 1 row affected (0.01 sec)
mysql> quit
Bye
[root@slave ~]# mysql -uroot -p123456 HA <HA.sql
mysql: [Warning] Using a password on the command line interface can be insecure.
3.4.5.9 配置My.cnf文件,并重启数据库
添加如下内容:
validate-password=off
server-id = 2
[root@slave ~]# systemctl restart mysqld
3.4.5.10 连接主数据库
mysql> stop slave;
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> change master to master_host='192.168.1.102',master_user='slave',master_password='123456';master_log_file='mysql-log-master.000001',masterer_log_pos=1036;
Query OK, 0 rows affected, 2 warnings (0.01 sec)
3.4.5.11 启动slave
mysql> start slave;
Query OK, 0 rows affected (0.00 sec)
3.4.6 启动Mycat
[root@mycat bin]# ./mycat start #启动数据库
Starting Mycat-server...
3.4.7 测试连接
3.4.7.1 在测试机上提前安装mysql的客户端
[root@client ~]# yum -y install mysql
3.4.7.2 连接mycat:(8066应用端口,9066管理端口)
[root@client ~]# mysql -uroot -p123456 -h 192.168.1.101 -P8066
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MySQL connection id is 1
Server version: 5.6.29-mycat-1.6.7.3-release-20190828215749 MyCat Server (OpenCloudDB)
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MySQL [(none)]> show databases;
+----------+
| DATABASE |
+----------+
| HA |
+----------+
1 row in set (0.01 sec)
3.4.7.3 授权mycat可以连接数据库
注意:此操作需要在主从数据库都操作授权,否则连接不上数据库。
mysql> GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '123456';
3.4.7.4 客户端主机上执行查看表数据
MySQL [(none)]> use HA;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
MySQL [HA]> show tables;
+--------------+
| Tables_in_HA |
+--------------+
| u1 |
+--------------+
1 row in set (0.01 sec)
MySQL [HA]> select * from u1;
+------+----------+
| id | name |
+------+----------+
| 1 | zhangsan |
| 2 | lisi |
+------+----------+
2 rows in set (0.02 sec)
MySQL [HA]>
扩展:如果没有授权的话,会出现如下的报错:
具体表现,在切库时非常卡顿,同时查表提示失败。
3.4.8 测试
3.4.8.1 打开Mycat.log的日志,将日志级别调整到"debug"
[root@mycat conf]# vim log4j2.xml ##打开日志配置文件
[root@mycat conf]# cat log4j2.xml |grep 'debug'
<asyncRoot level="debug" includeLocation="true"> #日志级别调整成debug
修改完了日志级别后,重启mycat
[root@mycat bin]# ./mycat restart
Stopping Mycat-server...
Stopped Mycat-server.
Starting Mycat-server...
1)当balance="0"时,插入数据查看日志(编辑schema.xml配置文件,完成后重启mycat服务,下同)
MySQL [HA]> insert into u1 values(1,'zhangsan');
MySQL [HA]> select * from u1;
发现读写都落到了192.168.1.102这台master数据库中,说明并未起到读写分离的效果。
2)当balance="2"时,查询数据。
MySQL [HA]> select * from u1;
可以看到读随机请求分配到了2台不同的服务器上。
3)当balance="3"时,插入数据查看日志
MySQL [HA]> select * from u1;
MySQL [HA]> insert into u1 values(3,'wangwu');
可以看到当查询数据时,查询的后端服务器是从服务器,数据插入是主服务器,所以读写分离成功。
3.4.9 故障模拟
当将balance设置成1后,我们将主数据断开后,查看是否可以读取到数据
[root@master ~]# systemctl stop mysqld
客户端测试获取数据
MySQL [HA]> select * from u1;
ERROR 1184 (HY000): java.net.ConnectException: Connection refused
说明:
“readHost是从属于writeHost的,即意味着它从那个writeHost获取同步数据,因此,当它所属的writeHost宕机了,则它也不会再参与到读写分离中来,即“不工作了”,这是因为此时,它的数据已经“不可靠”了。基于这个考虑,目前mycat 1.3和1.4版本中,若想支持MySQL一主一从的标准配置,并且在主节点宕机的情况下,从节点还能读取数据,则需要在Mycat里配置为两个writeHost并设置banlance=1。”
3.5 部署双主双从架构
3.5.1 环境要求
关闭防火墙和SELinux
角色 | IP | 数据库版本 | 系统版本 |
---|---|---|---|
client | 192.168.1.20 | 无 | CentOS7.9 |
mycat | 192.168.1.101 | 无 | CentOS7.9 |
master1 | 192.168.1.102 | mysql 5.7.36 | CentOS7.9 |
slave1 | 192.168.1.103 | mysql5.7.36 | CentOS7.9 |
master2 | 192.168.1.104 | mysql5.7.36 | CentOS7.9 |
slave2 | 192.168.1.105 | mysql5.7.36 | CentOS7.9 |
3.5.2 master2和slave2安装mysql数据库(接上个实验)
[root@master2 ~]# ~]# wget -i -c http://dev.mysql.com/get/mysql57-community-release-el7-8.noarch.rpm ##使用上面的命令就直接下载了安装用的Yum Repository,大概25KB的样子,然后就可以直接yum安装了。
[root@master2 ~]# yum -y install mysql57-community-release-el7-8.noarch.rpm ##之后就开始安装MySQL服务器。
[root@master2 ~]# yum -y install mysql-community-server ##这步可能会花些时间,安装完成后就会覆盖掉之前的mariadb。
3.5.3 修改密码
安装完成后,启动数据库使用默认密码登录数据库进行基本设置
mysql> set global validate_password_policy=0;
Query OK, 0 rows affected (0.00 sec)
mysql> set global validate_password_length=6;
Query OK, 0 rows affected (0.00 sec)
mysql> set password for 'root'@'localhost'=password('123456');
Query OK, 0 rows affected, 1 warning (0.00 sec)
3.5.4 将原来的master1和slave1的主从配置重置一下
mysql> stop slave;
Query OK, 0 rows affected, 1 warning (0.02 sec) #停止从服务器复制功能
mysql> reset slave;
Query OK, 0 rows affected (0.03 sec) #重置主从配置
3.5.5 重新配置my.cnf
3.5.5.1 master1的my.cnf的配置
validate-password=off
log-bin=mysql-bin-master
server-id=1
binlog-do-db=HA #需要复制的数据库名字
binlog-ignore-db=mysql #忽略复制的数据库,如果有多个,可以写多行
binlog_format=STATEMENT #设置binlog的日志格式
log-slave-updates #在作为从数据库时,有写入操作也要更新二进制日志文件
auto-increment-increment=2 #表示自增长字段每次递增的量,指自增长的起始值,默认是1,取值是1-65535
auto-increment-offset=1 #表示自增长字段从那个数开始,指字段一次递增多少,取值是1-65535
3.5.5.2 master2的my.cnf的配置
validate-password=off
log-bin=mysql-bin-master
server-id=3 #服务器ID
binlog-do-db=HA #需要复制的数据库名字
binlog-ignore-db=mysql #忽略复制的数据库,如果有多个,可以写多行
binlog_format=STATEMENT #设置binlog的日志格式
log-slave-updates #在作为从数据库时,有写入操作也要更新二进制日志文件
auto-increment-increment=2 #表示自增长字段每次递增的量,指自增长的起始值,默认是1,取值是1-65535
auto-increment-offset=2 #表示自增长字段从那个数开始,指字段一次递增多少,取值是1-65535
3.5.5.3 slave1的my.cnf的配置
validate-password=off #关闭密码强度审计
server-id=2 #服务器ID
relay-log=mysql-relay #开启中继日志
3.5.5.4 slave2的my.cnf的配置
validate-password=off #关闭密码强度审计
server-id=4 #服务器ID
relay-log=mysql-relay #开启中继日志
3.5.6 将4台数据库服务重启
[root@master ~]# systemctl restart mysqld
[root@master2 ~]# systemctl restart mysqld
[root@slave ~]# systemctl restart mysqld
[root@slave2 ~]# systemctl restart mysqld
3.5.7 在2个master上建立账号并授权slave
3.5.7.1 在master1授权
mysql> grant replication slave on *.* to slave@'%' identified by '123456';
#授权
#查看状态
mysql> show master status;
+-------------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+-------------------------+----------+--------------+------------------+-------------------+
| mysql-bin-master.000001 | 443 | HA | mysql | |
+-------------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
3.5.7.2 在master2上授权
mysql> grant replication slave on *.* to slave@'%' identified by '123456'; #授权
mysql> show master status;
+-------------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+-------------------------+----------+--------------+------------------+-------------------+
| mysql-bin-master.000001 | 443 | HA | mysql | |
+-------------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
3.5.8 在2个slave服务器上指定主服务器
3.5.8.1 slave1上执行(这里的pos一定要和主数据库上的一致,下同)
mysql> change master to master_host='192.168.1.102',master_user='slave',master_password='123456',master_log_file='mysql-bin-master.000001',master_log_pos=443;
mysql> start slave;
Query OK, 0 rows affected (0.00 sec)
mysql> start slave;
Query OK, 0 rows affected (0.00 sec)
mysql> show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.1.102
Master_User: slave
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin-master.000001
Read_Master_Log_Pos: 443
Relay_Log_File: mysql-relay.000002
Relay_Log_Pos: 327
Relay_Master_Log_File: mysql-bin-master.000001
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
....省略....
3.5.8.2 在slave2上执行
mysql> change master to master_host='192.168.1.104',master_user='slave',master_password='123456',master_log_file='mysql-bin-master.000001',master_log_pos=443;
mysql> start slave;
Query OK, 0 rows affected (0.00 sec)
mysql> show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.1.104
Master_User: slave
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin-master.000001
Read_Master_Log_Pos: 443
Relay_Log_File: mysql-relay.000002
Relay_Log_Pos: 327
Relay_Master_Log_File: mysql-bin-master.000001
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
....省略....
3.5.9 2台master之间互为主备配置
3.5.9.1 在master1上配置master2为主
mysql> change master to master_host='192.168.1.104',master_user='slave',master_password='123456',master_log_file='mysql-bin-master.000001',master_log_pos=443;
Query OK, 0 rows affected, 2 warnings (0.02 sec)
mysql> start slave;
Query OK, 0 rows affected (0.01 sec)
mysql> show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.1.104
Master_User: slave
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin-master.000001
Read_Master_Log_Pos: 443
Relay_Log_File: master-relay-bin.000002
Relay_Log_Pos: 327
Relay_Master_Log_File: mysql-bin-master.000001
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
....省略....
3.5.9.2 在master2上指定master1为主
mysql> change master to master_host='192.168.1.102',master_user='slave',master_password='123456',master_log_file='mysql-bin-master.000001',master_log_pos=443;
Query OK, 0 rows affected, 2 warnings (0.02 sec)
mysql> start slave;
Query OK, 0 rows affected (0.00 sec)
mysql> show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.1.102
Master_User: slave
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin-master.000001
Read_Master_Log_Pos: 443
Relay_Log_File: master2-relay-bin.000002
Relay_Log_Pos: 327
Relay_Master_Log_File: mysql-bin-master.000001
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB:
....省略....
至此,双主双备已经搭建完成!
3.5.10 验证是否可以同步数据库
3.5.10.1 在master1上创建HA库
mysql> create database HA;
Query OK, 1 row affected (0.01 sec)
mysql> use HA;
Database changed
mysql> create table u1(id int,name varchar(20)); #创建表
Query OK, 0 rows affected (0.04 sec)
mysql> insert into u1 values(1,'zhangsan'); #插入数据
Query OK, 1 row affected (0.11 sec)
mysql> select * from u1; #查看数据
+------+----------+
| id | name |
+------+----------+
| 1 | zhangsan |
+------+----------+
1 row in set (0.01 sec)
mysql>
3.5.10.2 在slave1查看
mysql> use HA;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> show tables;
+--------------+
| Tables_in_HA |
+--------------+
| u1 |
+--------------+
1 row in set (0.01 sec)
mysql> select * from u1; #查看数据
+------+----------+
| id | name |
+------+----------+
| 1 | zhangsan |
+------+----------+
1 row in set (0.00 sec)
mysql>
3.5.10.3 master2上查看
mysql> use HA;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> show tables;
+--------------+
| Tables_in_HA |
+--------------+
| u1 |
+--------------+
1 row in set (0.00 sec)
mysql> select * from u1; #查看数据
+------+----------+
| id | name |
+------+----------+
| 1 | zhangsan |
+------+----------+
1 row in set (0.00 sec)
mysql>
3.5.10.4 slave2上查看
mysql> use HA;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> show tables;
+--------------+
| Tables_in_HA |
+--------------+
| u1 |
+--------------+
1 row in set (0.00 sec)
mysql> select * from u1; #查看数据
+------+----------+
| id | name |
+------+----------+
| 1 | zhangsan |
+------+----------+
1 row in set (0.00 sec)
mysql>
可以看到数据库之间已经完成了同步。
3.5.11 读写分离配置
3.5.11.1 配置mycat机器,将balance设置为"1"
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
<schema name="HA" checkSQLschema="true" sqlMaxLimit="100" dataNode='dn1'>
</schema>
<dataNode name="dn1" dataHost="host1" database="HA" />
<dataHost name="host1" maxCon="1000" minCon="10" balance="1"
writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<!-- can have multi write hosts -->
<writeHost host="hostM1" url="192.168.1.102:3306" user="root"
password="123456">
<!-- can have multi read hosts -->
<readHost host="hostS1" url="192.168.1.103:3306" user="root" password="123456" />
</writeHost>
<writeHost host="hostM2" url="192.168.1.104:3306" user="root"
password="123456">
<!-- can have multi read hosts -->
<readHost host="hostS2" url="192.168.1.105:3306" user="root" password="123456" />
</writeHost>
</dataHost>
</mycat:schema>
3.5.12 重启mycat
[root@mycat bin]# ./mycat restart
Stopping Mycat-server...
Stopped Mycat-server.
Starting Mycat-server...
[root@mycat bin]#
3.5.13 验证读写分离
1)在写主机(master1)的数据库的表(u1)中插入一条带系统变量数据,造成主从数据不一致,以便以测试
mysql> insert into u1 values(2,@@hostname)
在master1上查看
mysql> select * from u1;
+------+----------+
| id | name |
+------+----------+
| 1 | zhangsan |
| 2 | master |
+------+----------+
2 rows in set (0.00 sec)
mysql>
在slave1上查看
mysql> select * from u1;
+------+----------+
| id | name |
+------+----------+
| 1 | zhangsan |
| 2 | slave |
+------+----------+
2 rows in set (0.00 sec)
在master2查看
mysql> select * from u1;
+------+----------+
| id | name |
+------+----------+
| 1 | zhangsan |
| 2 | master2 |
+------+----------+
2 rows in set (0.00 sec)
在slave2查看
mysql> select * from u1;
+------+----------+
| id | name |
+------+----------+
| 1 | zhangsan |
| 2 | slave2 |
+------+----------+
2 rows in set (0.00 sec)
可以看到4个数据库的数据均不一致
2)在mycat上进行测试
[root@mycat logs]# mysql -uroot -p123456 -h 192.168.1.101 -P8066 #登录Mycat
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.6.29-mycat-1.6.7.6-release-20201124193646 MyCat Server (OpenCloudDB)
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MySQL [(none)]> use HA; #切换数据库
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
MySQL [HA]> select * from u1; #查询
+------+----------+
| id | name |
+------+----------+
| 1 | zhangsan |
| 2 | master2 |
+------+----------+
2 rows in set (0.00 sec)
MySQL [HA]> select * from u1;
+------+----------+
| id | name |
+------+----------+
| 1 | zhangsan |
| 2 | slave2 |
+------+----------+
2 rows in set (0.01 sec)
MySQL [HA]> select * from u1;
+------+----------+
| id | name |
+------+----------+
| 1 | zhangsan |
| 2 | slave |
+------+----------+
2 rows in set (0.00 sec)
测试发现可以在3台机器之间进行切换。
注意:如果测试发现无法切到master2和slave2,则需要在这2台数据库中进行授权连接,命令如下:
mysql> grant all privileges on *.* to root@'%' identified by '123456';
3.5.14 测试故障切换
1)将master1主机的mysql服务停止掉,查看是否能切换到master2
[root@master mysql]# systemctl stop mysqld #停止数据库
[root@master mysql]# systemctl status mysqld
● mysqld.service - MySQL Server
Loaded: loaded (/usr/lib/systemd/system/mysqld.service; enabled; vendor preset: disabled)
Active: inactive (dead) since Sun 2022-03-27 20:14:23 CST; 4s ago
Docs: man:mysqld(8)
http://dev.mysql.com/doc/refman/en/using-systemd.html
Process: 13975 ExecStart=/usr/sbin/mysqld --daemonize --pid-file=/var/run/mysqld/mysqld.pid $MYSQLD_OPTS (code=exited, status=0/SUCCESS)
Process: 13951 ExecStartPre=/usr/bin/mysqld_pre_systemd (code=exited, status=0/SUCCESS)
Main PID: 13978 (code=exited, status=0/SUCCESS)
Mar 27 19:02:51 master systemd[1]: Starting MySQL Server...
Mar 27 19:02:58 master systemd[1]: Started MySQL Server.
Mar 27 20:14:12 master systemd[1]: Stopping MySQL Server...
Mar 27 20:14:23 master
2)在mycat插入数据测试
MySQL [HA]> insert into u1 values(3,@@hostname);
Query OK, 1 row affected, 1 warning (0.01 sec)
可以看到任然可以写入数据
3)重新启动master1数据库
[root@master mysql]# systemctl start mysqld
4)mycat上查询
MySQL [HA]> select * from u1;
+------+----------+
| id | name |
+------+----------+
| 1 | zhangsan |
| 2 | slave2 |
| 3 | slave2 |
+------+----------+
3 rows in set (0.01 sec)
MySQL [HA]> select * from u1; ##可以发现写主机变成了master2,master1变成了读数据库
+------+----------+
| id | name |
+------+----------+
| 1 | zhangsan |
| 2 | master |
| 3 | master |
+------+----------+
3 rows in set (0.00 sec)
MySQL [HA]> select * from u1;
+------+----------+
| id | name |
+------+----------+
| 1 | zhangsan |
| 2 | slave |
| 3 | slave |
+------+----------+
3 rows in set (0.00 sec)
MySQL [HA]>
到此,双主双从的读写分离已经完成!
四、总结
Mycat中间件是一个开源的数据库中间件,旨在提供高性能、高可用性和可伸缩性的数据库访问解决方案。它主要用于分布式数据库架构中,为应用程序提供透明的数据库访问,同时具备负载均衡、故障转移和数据分片等功能。
Mycat中间件以其卓越的功能和灵活性在数据库领域广泛应用。首先,它提供了数据库访问的负载均衡机制,可以有效地分配用户请求到后端数据库服务器,从而提高整体系统的性能和可用性。通过动态路由和连接池管理,Mycat中间件能够根据实际负载情况智能地分配数据库资源,避免单个数据库节点过载或出现瓶颈。
其次,Mycat中间件支持数据的分片存储和水平扩展,这对于处理大规模数据和应对高并发访问非常重要。通过将数据水平划分为多个分片,每个分片可以独立存储在不同的数据库节点上,从而提高了数据读写的并发性能。同时,Mycat中间件还提供了数据迁移和扩容等管理工具,使得系统能够方便地进行扩展和维护。
此外,Mycat中间件还具备故障转移和容灾备份的功能。当数据库节点发生故障时,Mycat可以自动将请求切换到备用节点,从而保证系统的连续性和可用性。同时,它还支持数据的冗余备份和同步,以防止数据丢失和提高数据的可靠性。
总之,Mycat中间件是一个强大的数据库访问解决方案,为分布式数据库架构提供了重要的支持。它能够提供负载均衡、故障转移、数据分片等关键功能,同时还具备数据迁移、扩容和容灾备份等管理工具。通过使用Mycat中间件,开发人员可以轻松构建高性能、高可用性和可伸缩性的数据库系统,提升应用程序的性能和用户体验。
- 感谢你赐予我前进的力量