视频学习地址:17-尚硅谷-垂直分库_哔哩哔哩_bilibili
笔记参考地址:MySQL 分库分表 | xustudyxu's Blog (frxcat.fun)
下载:
MyCat官网已经访问不了了,这里可以从github上下载1.6版本Releases · MyCATApache/Mycat-Server (github.com)
安装:
安装MyCat 1.6 需要javaJDK1.7及以上,这里我用jdk1.8为例。
服务器分布规则:
服务器 | 安装软件 | 说明 |
192.168.247.100 | JDK、Mycat | MyCat中间件服务器 |
192.168.247.100 | Mysql | 分片服务器 |
192.168.247.101 | Mysql | 分片服务器 |
192.168.247.102 | Mysql | 分片服务器 |
解压MyCat
tar -zxvf Mycat-server-1.6.7.3-release-20190828135747-linux.tar.gz -C /usr/local
[root@centos142 mycat]# ll
总用量 12
drwxr-xr-x 2 root root 190 12月 3 16:23 bin
drwxrwxrwx 2 root root 6 4月 15 2020 catlet
drwxrwxrwx 4 root root 4096 12月 3 16:23 conf
drwxr-xr-x 2 root root 4096 12月 3 16:45 lib
-rwxrwxrwx 1 root root 227 4月 22 2020 version.txt
bin : 存放可执行文件,用于启动停止mycat
conf:存放mycat的配置文件
lib:存放mycat的项目依赖包(jar)
logs:存放mycat的日志文件
由于mycat中的mysql的JDBC驱动包版本比较低,所以我们将它删去,替换8.0版本的
mysql-connector-java-8.0.22.jar
cd /usr/local/mycat/lib/
rm -rf mysql-connector-java-5.1.35.jar
别忘了三台服务器的防火墙都需要关闭哦:
查看防火墙状态: systemctl status firewalld
启动:systemctl start firewalld
关闭命令: systemctl stop firewalld
开机禁用防火墙自启命令 : systemctl disable firewalld
概念介绍
在MyCat的整体结构中,分为两个部分:上面的逻辑结构、下面的物理结构。
在MyCat的逻辑结构主要负责逻辑库、逻辑表、分片规则、分片节点等逻辑结构的处理,而具体的数据存储还是在物理结构,也就是数据库服务器中存储的。
入门案例:
需求
由于 tb_order 表中数据量很大,磁盘IO及容量都到达了瓶颈,现在需要对 tb_order 表进行数据分片,分为三个数据节点,每一个节点主机位于不同的服务器上, 具体的结构,参考下图:
环境准备
准备3台服务器:
- 192.168.247.100:MyCat中间件服务器,同时也是第一个分片服务器。
- 192.168.247.101:第二个分片服务器。
- 192.168.247.102:第三个分片服务器。
在上述3台数据库中创建数据库 db01 。
配置
1. 配置schema.xml
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
<schema name="DB01" checkSQLschema="true" sqlMaxLimit="100">
<!-- auto sharding by id (long) -->
<!--splitTableNames 启用<table name 属性使用逗号分割配置多个表,即多个表使用这个配置-->
<!--fetchStoreNodeByJdbc 启用ER表使用JDBC方式获取DataNode-->
<table name="tb_order" dataNode="dn1,dn2,dn3" rule="auto-sharding-long">
</table>
<!-- <table name="oc_call" primaryKey="ID" dataNode="dn1$0-743" rule="latest-month-calldate"
/> -->
</schema>
<!-- <dataNode name="dn1$0-743" dataHost="localhost1" database="db$0-743"
/> -->
<dataNode name="dn1" dataHost="dhost1" database="db01" />
<dataNode name="dn2" dataHost="dhost2" database="db01" />
<dataNode name="dn3" dataHost="dhost3" database="db01" />
<!--<dataNode name="dn4" dataHost="sequoiadb1" database="SAMPLE" />
<dataNode name="jdbc_dn1" dataHost="jdbchost" database="db1" />
<dataNode name="jdbc_dn2" dataHost="jdbchost" database="db2" />
<dataNode name="jdbc_dn3" dataHost="jdbchost" database="db3" /> -->
<dataHost name="dhost1" maxCon="1000" minCon="10" balance="0"
writeType="0" dbType="mysql" dbDriver="jdbc" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<!-- can have multi write hosts -->
<writeHost host="master" url="jdbc:mysql://192.168.247.100:3306?useSSL=false&serverTimezone=Asia/Shanghai&characterEncoding=utf8" user="root"
password="Hzf1997=Hzf">
</writeHost>
<!-- <writeHost host="hostM2" url="localhost:3316" user="root" password="123456"/> -->
</dataHost>
<dataHost name="dhost2" maxCon="1000" minCon="10" balance="0"
writeType="0" dbType="mysql" dbDriver="jdbc" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<!-- can have multi write hosts -->
<writeHost host="master" url="jdbc:mysql://192.168.247.101:3306?useSSL=false&serverTimezone=Asia/Shanghai&characterEncoding=utf8" user="root"
password="Hzf1997=Hzf">
</writeHost>
<!-- <writeHost host="hostM2" url="localhost:3316" user="root" password="123456"/> -->
</dataHost>
<dataHost name="dhost3" maxCon="1000" minCon="10" balance="0"
writeType="0" dbType="mysql" dbDriver="jdbc" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<!-- can have multi write hosts -->
<writeHost host="master" url="jdbc:mysql://192.168.247.102:3306?useSSL=false&serverTimezone=Asia/Shanghai&characterEncoding=utf8" user="root"
password="Hzf1997=Hzf">
</writeHost>
<!-- <writeHost host="hostM2" url="localhost:3316" user="root" password="123456"/> -->
</dataHost>
</mycat:schema>
2. 在server.xml末尾处,修改配置用户名、密码,以及用户的访问权限信息
<user name="root" defaultAccount="true">
<property name="password">Hzf1997=Hzf</property>
<property name="schemas">DB01</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">Hzf7991=Hzf</property>
<property name="schemas">DB01</property>
<property name="readOnly">true</property>
</user>
上述的配置表示,定义了两个用户 root 和 user ,这两个用户都可以访问 DB01 这个逻辑库,访问密码都是自定义,但是root用户访问DB01逻辑库,既可以读,又可以写,但是 user用户访问DB01逻辑库是只读的。
测试
先在 /usr/local/mycat 目录下创建 logs 文件夹,并赋权限 : chmod -R 777 logs
启动Mycat:
#启动
./mycat start
#停止
./mycat stop
Mycat启动之后,占用端口号 8066。
启动完毕之后,可以查看logs目录下的启动日志,查看Mycat是否启动完成。
[root@centos142 logs]# tail -10 wrapper.log
STATUS | wrapper | 2022/12/03 20:19:34 | --> Wrapper Started as Daemon
STATUS | wrapper | 2022/12/03 20:19:34 | Launching a JVM...
INFO | jvm 1 | 2022/12/03 20:19:35 | Wrapper (Version 3.2.3) http://wrapper.tanukisoftware.org
INFO | jvm 1 | 2022/12/03 20:19:35 | Copyright 1999-2006 Tanuki Software, Inc. All Rights Reserved.
INFO | jvm 1 | 2022/12/03 20:19:35 |
INFO | jvm 1 | 2022/12/03 20:19:37 | Loading class `com.mysql.jdbc.Driver'. This is deprecated. The new driver class is `com.mysql.cj.jdbc.Driver'. The driver is automatically registered via the SPI and manual loading of the driver class is generally unnecessary.
INFO | jvm 1 | 2022/12/03 20:19:56 | MyCAT Server startup successfully. see logs in logs/mycat.log
连接MyCat
mysql -h 192.168.247.100 -P 8066 -u root -p
[root@centos142 mycat]# mysql -h 192.168.247.100 -P 8066 -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.6.29-mycat-1.6.7.5-release-20200422133810 MyCat Server (OpenCloudDB)
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>
我们可以通过MySQL的指令来连接的MyCat,因为MyCat在底层实际上是模拟了MySQL的协议
添加数据测试:
在MyCat中来创建表,并往表结构中插入数据,查看数据在MySQL中的分布情况。
进入配置文件中配置的逻辑数据库 DB01
mysql> use DB01;
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> CREATE TABLE TB_ORDER (
-> id BIGINT(20) NOT NULL,
-> title VARCHAR(100) NOT NULL ,
-> PRIMARY KEY (id)
-> ) ENGINE=INNODB DEFAULT CHARSET=utf8 ;
Query OK, 0 rows affected (0.49 sec)
OK!
CREATE TABLE TB_ORDER (
id BIGINT(20) NOT NULL,
title VARCHAR(100) NOT NULL ,
PRIMARY KEY (id)
) ENGINE=INNODB DEFAULT CHARSET=utf8 ;
INSERT INTO TB_ORDER(id,title) VALUES(1,'goods1');
INSERT INTO TB_ORDER(id,title) VALUES(2,'goods2');
INSERT INTO TB_ORDER(id,title) VALUES(3,'goods3');
INSERT INTO TB_ORDER(id,title) VALUES(1,'goods1');
INSERT INTO TB_ORDER(id,title) VALUES(2,'goods2');
INSERT INTO TB_ORDER(id,title) VALUES(3,'goods3');
INSERT INTO TB_ORDER(id,title) VALUES(5000000,'goods5000000');
INSERT INTO TB_ORDER(id,title) VALUES(10000000,'goods10000000');
INSERT INTO TB_ORDER(id,title) VALUES(10000001,'goods10000001');
INSERT INTO TB_ORDER(id,title) VALUES(15000000,'goods15000000');
INSERT INTO TB_ORDER(id,title) VALUES(15000001,'goods15000001');
添加数据:
结果:
在往 TB_ORDER 表中插入数据时:
-
如果id的值在1-500w之间,数据将会存储在第一个分片数据库中。
-
如果id的值在500w-1000w之间,数据将会存储在第二个分片数据库中。
-
如果id的值在1000w-1500w之间,数据将会存储在第三个分片数据库中。
-
如果id的值超出1500w,在插入数据时,将会报错。
为什么会出现这种现象,数据到底落在哪一个分片服务器到底是如何决定的呢? 这是由逻辑表配置时的一个参数 rule 决定的,而这个参数配置的就是分片规则