MySql使用MyCat分库分表(二)搭建与入门案例

视频学习地址: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.100JDK、MycatMyCat中间件服务器
192.168.247.100Mysql分片服务器
192.168.247.101Mysql分片服务器
192.168.247.102Mysql分片服务器

解压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&amp;serverTimezone=Asia/Shanghai&amp;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&amp;serverTimezone=Asia/Shanghai&amp;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&amp;serverTimezone=Asia/Shanghai&amp;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 决定的,而这个参数配置的就是分片规则

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值