mycat介绍与操作步骤

文章目录

    • 1.分库分表
    • [2.mycat 入门](#2.mycat 入门)
    • [3.mycat 配置详解](#3.mycat 配置详解)
      • [3.1 schema.xml](#3.1 schema.xml)
      • [3.2 rule.xml](#3.2 rule.xml)
      • [3.3 server.xml](#3.3 server.xml)
    • [4.mycat 分片:垂直拆分](#4.mycat 分片:垂直拆分)
    • [5.mycat 分片:水平拆分](#5.mycat 分片:水平拆分)
    • [6.mycat 管理和监控](#6.mycat 管理和监控)
      • [6.1 9066管理端口](#6.1 9066管理端口)
      • [6.2 mycat-web](#6.2 mycat-web)
    • [7.mycat 读写分离](#7.mycat 读写分离)
      • [7.1 一主一从](#7.1 一主一从)
      • [7.2 双主双从](#7.2 双主双从)

1.分库分表

分库分表带来的问题

2.mycat 入门

2.1 概述

官网:http://www.mycat.org.cn/

注:先安装JDK,再解压mycat即可

注:lib中有mysql的jar包,需要根据mysql的版本进行更换

注:mycat在逻辑上进行分片处理,并不储存真正的数据

2.2 案例:水平分表

1)准备工作

准备三台mysql服务器,并创建同名的数据库,只建库,不要建表

在其中一台服务器上安装mycat(也可以再准备一台虚拟机进行操作)

  • 安装jdk
  • 配置环境变量
  • 解压mycat
2)配置

编辑以下两个配置文件

xml 复制代码
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">

	<schema name="TESTDB" checkSQLschema="true" sqlMaxLimit="100">
		<table name="student" dataNode="dn1,dn2,dn3" rule="auto-sharding-long" />
	</schema>
	<dataNode name="dn1" dataHost="dataHost1" database="testdb" />
	<dataNode name="dn2" dataHost="dataHost2" database="testdb" />
	<dataNode name="dn3" dataHost="dataHost3" database="testdb" />

	<dataHost name="dataHost1" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="jdbc">
		<heartbeat>select user()</heartbeat>
		<writeHost host="master" url="jdbc:mysql://192.168.9.3:3306?useSSL=false&amp;serverTimezone=Asia/Shanghai&amp;characterEncoding=utf8" user="root" password="123456">
		</writeHost>
	</dataHost>
	<dataHost name="dataHost2" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="jdbc">
		<heartbeat>select user()</heartbeat>
		<writeHost host="master" url="jdbc:mysql://192.168.9.8:3306?useSSL=false&amp;serverTimezone=Asia/Shanghai&amp;characterEncoding=utf8" user="root" password="123456">
		</writeHost>
	</dataHost>
	<dataHost name="dataHost3" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="jdbc">
		<heartbeat>select user()</heartbeat>
		<writeHost host="master" url="jdbc:mysql://192.168.9.9:3306?useSSL=false&amp;serverTimezone=Asia/Shanghai&amp;characterEncoding=utf8" user="root" password="123456">
		</writeHost>
	</dataHost>
</mycat:schema>
3)启动并测试

配置完毕,启动mycat。启动后,可查看日志

连接mycat与连接mysql基本一样

mysql 复制代码
# 建表
create table STUDENT (
  id bigint(20) not NULL ,
  name varchar(50) not NULL,
  sex char(1) not NULL,
  primary key (id)
) engine=innodb default charset=utf8;

# 此时分别查看三个真实数据库,会发现已创建好了相同的表结构

插入数据测试

mysql 复制代码
# 插入三条数据
insert into STUDENT (id,name,sex) values(1,'tom','M');
insert into STUDENT (id,name,sex) values(2,'marry','F');
insert into STUDENT (id,name,sex) values(3,'jack','M');

插入三条数据后分别查看三个真实数据库,发现可能只在其中一个库中插入了数据

这是由 schema.xml 中配置的 rule="auto-sharding-long" 分片规则决定的

这个分片规则定义在 rule.xml 中,追踪到 autopartition-long.txt 文件

插入新数据id为 5000001,则会插入到对应的物理数据库中,如果超过1500M后,则会报异常

3.mycat 配置详解

3.1 schema.xml

3.2 rule.xml

3.3 server.xml

4.mycat 分片:垂直拆分

1)准备工作

在上例的基础上进行配置,在三台mysql服务器上创建同名的数据库 appdb,只建库,不要建表。

数据库表说明:

  • ad_promotion:首页轮播图广告位
  • app_info:app信息
  • app_category:app类别
  • app_version:app版本
  • data_dictionary:数据字典
  • backend_user:后台用户
  • dev_user:开发者用户

2)配置

分片说明

  • 数据节点1:
    • app_info :app信息
    • app_category :app类别
    • app_version :app版本
    • data_dictionary :数据字典
  • 数据节点2:
    • backend_user :后台用户
    • dev_user :开发者用户
  • 数据节点3:
    • ad_promotion :首页轮播图广告位

schema.xml

shell 复制代码
#APPDB表示库名
<schema name="APPDB" checkSQLschema="true" sqlMaxLimit="100">
<table name="app_info" dataNode="dn1" primaryKey='id'/>
<table name="app_category" dataNode="dn1" primaryKey='id'/>
<table name="app_version" dataNode="dn1" primaryKey='id'/>

<table name="data_dictionary" dataNode="dn1" primaryKey='id'/>

<table name="backend_user" dataNode="dn2" primaryKey='id'/>
<table name="dev_user" dataNode="dn2" primaryKey='id'/>

<table name="ad_promotion" dataNode="dn3" primaryKey='id'/>
</schema>
shell 复制代码
#appdb表示连接的数据库名
<dataNode name="dn1" dataHost="dataHost1" database="appdb" />
<dataNode name="dn2" dataHost="dataHost2" database="appdb" />
<dataNode name="dn3" dataHost="dataHost3" database="appdb" />

server.xml

shell 复制代码
<user name="root" defaultAccount="true">
      <property name="password">123456</property>
      <property name="schemas">APPDB</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">123456</property>
                <property name="schemas">APPDB</property>
                <property name="readOnly">true</property>
        </user>

3)启动并测试

在mycat端,统一用脚本建表、导入数据

如果在虚拟机里执行app_table.sql需要把脚本上传到某个目录下

如:opt目录下

xxx表示脚本目录的地址 如:source /opt/app_table.sql

shell 复制代码
# 建表
mysql> source /xxx/app_table.sql
# 导入数据
mysql> source /xxx/app_data.sql

测试以下sql语句

shell 复制代码
# 查询数据字典表
SELECT * FROM DATA_DICTIONARY;

# 连接查询,查询app信息
SELECT a.id,softwareName,APKName,valueName
FROM APP_INFO a
INNER JOIN DATA_DICTIONARY d
ON a.status = d.valueId
WHERE d.typeCode= 'APP_STATUS';

# 连接查询,查询管理员信息,报错截图如下
SELECT u.id,userCode,u.creationDate,valueName
FROM BACKEND_USER u
INNER JOIN DATA_DICTIONARY d
ON u.userType = d.valueId
WHERE d.typeCode= 'USER_TYPE';

4)全局表

如果连接查询的表处于不同的分片,则会报错

比如数据字典表,其他表可能都会引用它,则应该把它设置为全局表,让它在每个分片上都存在

重新配置后,重启mycat,还需要把物理数据库中的表全部删除,重新执行建库脚本,再进行测试

编辑 schema.xml

shell 复制代码
<table name="data_dictionary" dataNode="dn1,dn2,dn3" primaryKey='id' type="global"/>

注意:

  • 修改 schema.xml 后,重启mycat
  • 删除每个分片上的数据表,重新执行建库脚本等
  • 对全局表进行更新等操作后,其他分片上的全局表也会进行同步

5.mycat 分片:水平拆分

在上一个案例的基础上完成

schema.xml ,mod-long:通过对id取模运算把数据均匀的分散到分片上

server.xml ,让 root 也可以管理此逻辑库

重启mycat,测试略

6.mycat 管理和监控

6.1 9066管理端口

6.2 mycat-web

zookeeper

下载地址:https://archive.apache.org/dist/zookeeper/

安装步骤:

shell 复制代码
# 解压
tar -xf zookeeper-3.4.6.tar.gz -C /usr/local/

# 创建数据存放目录
mkdir /usr/local/zookeeper-3.4.6/data

# 配置文件 
cp /usr/local/zookeeper-3.4.6/conf/zoo_sample.cfg /usr/local/zookeeper-3.4.6/conf/zoo.cfg

# 修改配置文件
vim /usr/local/zookeeper-3.4.6/conf/zoo.cfg
# 第12 行
dataDir=/usr/local/zookeeper-3.4.6/data

#启动
/usr/local/zookeeper-3.4.6/bin/zkServer.sh start
# 查看状态
/usr/local/zookeeper-3.4.6/bin/zkServer.sh status

安装 mycat-eye

shell 复制代码
# 解压
tar -xf Mycat-web.tar.gz -C /usr/local/

# 启动
cd /usr/local/mycat-web/
sh start.sh

# 网页访问
http://192.168.9.3:8082/mycat/

启动 zookeeper、mycat-eye,访问网页

7.mycat 读写分离

7.1 一主一从

两台虚拟机,先配置好一主一从,再配置 mycat

  • 配置好一主一从后,在主库的DDL操作会同步到从库中
  • 在主库测试建库、建表、插入数据

mycat 配置说明

  • writeHost 节点、readHost 节点
  • balance 属性(一般设置为1或3,在一主一从配置中1和3都一样)
  • 读写分离的配置中不用配置逻辑表,默认会加载物理数据库中的所有表为逻辑表

配置 schema.xml

writeHost 和eadHost 节点中的 name 不要相同

server.xml

重启mycat,登录并测试

  • 连接 mycat,测试新增,主库和从库中都会有新增的数据
  • 用navicat在从库中修改一条数据,在mycat 中测试查询,以验证读写是否分离
  • 如果 schema.xml 中的负载均衡策略为2,则会随机查询到两个节点的数据
  • 如果主库宕机了,查询操作正常,新增、修改、删除都会失败(一主一从并没有高可用)

7.2 双主双从

介绍

准备和规划

主机master1

  • server-id:唯一值
  • binlog-do-db:指定一个需要同步的库做测试即可,如 db01
  • log-slave-updates
shell 复制代码
vim /etc/my.cnf

server-id=1
log-bin=mysql-bin
#选择要同步的数据库名  只能在这个数据库进行同步
#不写就是全部数据库
binlog-do-db=mytest
log-slave-updates
shell 复制代码
#重启数据库
systemctl restart mysqld

主机master2

  • 和 master1 对比,也就是 server-id 不同
shell 复制代码
vim /etc/my.cnf

server-id=3
log-bin=mysql-bin
#选择要同步的数据库名  只能在这个数据库进行同步
#不写就是全部数据库
binlog-do-db=mytest
log-slave-updates
shell 复制代码
#重启数据库
systemctl restart mysqld

分别在两台主库上都创建同名的用户,用于主从复制,查看主库状态(记录 binlog文件和位置)

shell 复制代码
#登录mysql
mysql -uroot -p
# 创建用户,并授予主从复制权限
mysql> create user 'my'@'%' identified with mysql_native_password by 'Bdqn_8888';

mysql> grant replication slave on *.* to 'my'@'%';

mysql> SHOW MASTER STATUS;

从机slave1

  • 只需要配置 server-id
shell 复制代码
vim /etc/my.cnf


#从机id
server-id=2

#重启数据库
systemctl restart mysqld

从机slave2

  • 和 slave1对比,也就是server-id不同
shell 复制代码
vim /etc/my.cnf


#从机id
server-id=4

#重启数据库
systemctl restart mysqld

分别在两台从库上设置其关联的主库

shell 复制代码
#登录从库mysql
mysql -uroot -p

#分别在两台从库上设置其关联的主库
mysql> CHANGE MASTER TO
master_host='192.168.9.6',
master_user='my',
master_password='Bdqn_8888',
master_port=3306,
master_log_file='mysql-bin.000001',
master_log_pos=591;

mysql> START SLAVE;

mysql> SHOW SLAVE STATUS\G;

分别在两台主库上配置互相复制

shell 复制代码
两台主机进行复制    1号机连接3号机    3号机连接1号机
mysql> CHANGE MASTER TO
master_host='192.168.9.4',
master_user='my',
master_password='Bdqn_8888',
master_port=3306,
master_log_file='mysql-bin.000001',
master_log_pos=591;

mysql> START SLAVE;

mysql> SHOW SLAVE STATUS\G;

测试(在navicat中测试即可)

  • 在 master1 执行建库、建表语句,会自动同步到其他三台服务器

  • 在 master2 执行新增语句,会自动同步到其他三台服务器

shell 复制代码
# 建库建表添加数据
mysql> create database mytest;

mysql> use mytest;

mysql> create table person(
  id int(10) primary key not null auto_increment,
  name varchar(50) not null,
  gender char(1) not null
)engine=innodb default charset=utf8mb4;

mysql> insert into person values (null,'tom','m'),(null,'jack','m'),(null,'marry','f');

此时双主双从搭建完毕,下面在 mycat 进行读写分离的配置

shell 复制代码
#先安装JDK在解压mycat  
tar -xf Mycat-server-1.6.7.4-release-20200105164103-linux.tar.gz -C /usr/local

schema.xml

shell 复制代码
#schema.xml配置文件位置
cd /usr/local/mycat/conf
#备份
cp schema.xml schema.xml.bak

vim schema.xml
shell 复制代码
 <!--mytest -->
        <schema name="MYTEST" checkSQLschema="true" sqlMaxLimit="100" dataNode="dn1" >
        </schema>

        <dataNode name="dn1" dataHost="dataHost1" database="mytest" />


        <dataHost name="dataHost1" maxCon="1000" minCon="10" balance="1" writeType="0" dbType="mysql" dbDriver="jdbc" switchType="1" slaveThreshold="100" >
                <heartbeat>select user()</heartbeat>
                <writeHost host="master1" url="jdbc:mysql://192.168.9.3:3306?useSSL=false&amp;serverTimezone=Asia/Shanghai&amp;characterEncoding=utf8" user="root" password="Bdqn_8888">
                        <readHost host="slave1" url="jdbc:mysql://192.168.9.4:3306?useSSL=false&amp;serverTimezone=Asia/Shanghai&amp;characterEncoding=utf8" user="root" password="Bdqn_8888">
                        </readHost>
                </writeHost>

                <writeHost host="master2" url="jdbc:mysql://192.168.9.5:3306?useSSL=false&amp;serverTimezone=Asia/Shanghai&amp;characterEncoding=utf8" user="root" password="Bdqn_8888">
                        <readHost host="slave2" url="jdbc:mysql://192.168.9.7:3306?useSSL=false&amp;serverTimezone=Asia/Shanghai&amp;characterEncoding=utf8" user="root" password="Bdqn_8888">
                        </readHost>
                </writeHost>
        </dataHost>

server.xml

shell 复制代码
vim server.xml
shell 复制代码
<user name="root" defaultAccount="true">
                <property name="password">123456</property>
                <property name="schemas">MYTEST</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">123456</property>
                <property name="schemas">MYTEST</property>
                <property name="readOnly">true</property>
        </user>

开启mycat

shell 复制代码
/usr/local/mycat/bin/mycat start

日记检测

shell 复制代码
tail -f /usr/local/mycat/logs/wrapper.log

重启mycat服务测试

测试1:

  • 修改 slave1 的数据、修改 slave2 的数据,在 mycat 中 select 看看效果,会发现显示的数据来源于master2、slave1、slave2。

  • 在 mycat 中 insert ,会发现都进行了数据同步。

测试2:

  • 停止 master1 的 mysql 服务,在 mycat 中测试查询,会发现显示的数据来源于slave2。

  • 在 mycat 中测试 insert,看能否执行写入,会发现数据写入了 master2、slave2。

相关推荐
sunly_3 分钟前
Flutter:文章详情页,渲染富文本
android·javascript·flutter
那年星空7 分钟前
Flutter 3.x 版本升级实战:让老项目焕发新生
android·flutter·架构
m0_7482552626 分钟前
运维实战---多种方式在Linux中部署并初始化MySQL
linux·运维·mysql
weisian15135 分钟前
Mysql--基础篇--多表查询(JOIN,笛卡尔积)
数据库·mysql
LabVIEW开发37 分钟前
LabVIEW数据库管理系统
数据库·labview
NineData1 小时前
NineData云原生智能数据管理平台新功能发布|2024年12月版
数据库·sql·算法·云原生·oracle·devops·ninedata
xsh801442421 小时前
Java Spring Boot监听事件和处理事件
java·前端·数据库
焱焱枫1 小时前
Oracle Database 23ai 新特性: UPDATE 和 DELETE 语句的直接联接
数据库·oracle
kikyo哎哟喂1 小时前
InnoDB存储引擎对MVCC的实现
数据库
IvorySQL1 小时前
IvorySQL 4.0 之兼容 Oracle 包功能设计思路解读
数据库