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。

相关推荐
二流小码农1 小时前
鸿蒙开发:上传一张参考图片便可实现页面功能
android·ios·harmonyos
鹏程十八少1 小时前
4.Android 30分钟手写一个简单版shadow, 从零理解shadow插件化零反射插件化原理
android·前端·面试
Kapaseker1 小时前
一杯美式搞定 Kotlin 空安全
android·kotlin
三少爷的鞋2 小时前
Android 协程时代,Handler 应该退休了吗?
android
NineData11 小时前
NineData 迁移评估功能正式上线
数据库·dba
火柴就是我15 小时前
让我们实现一个更好看的内部阴影按钮
android·flutter
NineData16 小时前
数据库迁移总踩坑?用 NineData 迁移评估,提前识别所有兼容性风险
数据库·程序员·云计算
阿里云大数据AI技术16 小时前
用 SQL 调大模型?Hologres + 百炼,让数据开发直接“对话”AI
sql·llm
赵渝强老师18 小时前
【赵渝强老师】PostgreSQL中表的碎片
数据库·postgresql
砖厂小工1 天前
用 GLM + OpenClaw 打造你的 AI PR Review Agent — 让龙虾帮你审代码
android·github