目录
- MyCat分库分表
- 概述
- 水平拆分和垂直拆分
- 安装
- JDK安装
- MyCat安装
- MyCat案例
- 1、创建数据库
- 2、分片配置(schema.xml)
- 3、分片配置(server.xml)
- 4、启动服务
- 5、查看日志,看是否启动成功
- 6、登录MyCat
- 7、查看数据库和表
- 8、创建表结构并且插入数据
- 9、查看数据分布
- MyCat配置
- schema.xml
- schema标签
- table标签
- dataNode标签
- dataHost标签
- rule.xml
- server.xml
- system标签
- user标签
- MyCat原理
- MyCat管理
MyCat分库分表
概述
Mycat是一个开源的分布式数据库中间件,它可以将多个MySQL服务器组合成一个逻辑数据库集群,提供高可用、高并发、分片等功能。Mycat在MySQL协议层上实现了Sharding和读写分离等功能,可以将数据水平拆分到多个MySQL服务器上,从而提高数据库的性能和可用性,结构图如下。
水平拆分和垂直拆分
垂直拆分是指将一个大的数据库按照业务功能进行拆分,将不同的表放在不同的数据库中,从而实现数据库的分离。垂直拆分可以提高数据库的可维护性和可扩展性,但是需要重新设计数据库结构,增加了开发和维护的难度。
水平拆分是指将一个大的数据库按照数据行进行拆分,将不同的数据行存储在不同的数据库中,从而实现数据库的分布式存储和访问。水平拆分可以提高数据库的并发能力和可扩展性,但是需要考虑数据一致性和分片规则等问题。
安装
下载
http://www.mycat.org.cn/mycat1.html
MyCat采用java语言开发的开源的数据库中间件,支持windows和linux运行环境,因此安装需要的软件有MySQL、JDK、MyCat。
规划如下
服务器 | 安装软件 | 说明 |
---|---|---|
192.168.40.137 | JDK、MyCat、MySQL | MyCat中间服务器 |
192.168.40.138 | MySQL | 分片服务器 |
192.168.40.150 | MySQL | 分片服务器 |
JDK安装
JDK具体安装步骤如下:
- 上传安装包
[root@mysql-master ~]# ls
anaconda-ks.cfg Mycat-server-1.6.7.3-release-20210913163959-linux.tar.gz mysql
jdk-8u171-linux-x64.tar.gz onekey-install-nginx.sh
- 解压安装包
执行如下指令,将上传上来的压缩包进行解压,并通过-C参数指定解压文件存放目录为 /usr/local。
[root@mysql-master ~]# tar -zxvf jdk-8u171-linux-x64.tar.gz -C /usr/local
- 配置环境变量
使用vim命令修改/etc/profile文件,在文件末尾加入如下配置
JAVA_HOME=/usr/local/jdk1.8.0_171
PATH=$JAVA_HOME/bin:$PATH
具体操作指令如下:
1). 编辑/etc/profile文件,进入命令模式
vim /etc/profile
2). 在命令模式中,输入指令 G , 切换到文件最后
G
3). 在命令模式中输入 i/a/o 进入插入模式,然后切换到文件最后一行
i
4). 将上述的配置拷贝到文件中
export JAVA_HOME=/usr/local/jdk1.8.0_171
export PATH=$JAVA_HOME/bin:$PATH
5). 从插入模式,切换到指令模式
ESC
6). 按:进入底行模式,然后输入wq,回车保存
:wq
- 重新加载profile文件
为了使更改的配置立即生效,需要重新加载profile文件,执行命令:
[root@mysql-master local]# source /etc/profile
- 检查安装是否成功
[root@mysql-master local]# java -version
[root@mysql-master local]# java
[root@mysql-master local]# javac
都能显示信息则成功
MyCat安装
-
上传Mycat压缩包到服务器
-
解压MyCat的压缩包
[root@mysql-master ~]# tar -zxvf Mycat-server-1.6.7.3-release-20210913163959-linux.tar.gz -C /usr/local/
3.进入jar包目录,发现mysql驱动包的版本为5.1,进行替换
4.替换后发现权限不对,修改权限
5.修改权限
[root@mysql-master lib]# chmod 777 mysql-connector-java-8.0.22.jar
安装完成
MyCat案例
根据之间的规划如下
服务器 | 安装软件 | 说明 |
---|---|---|
192.168.40.137 | JDK、MyCat、MySQL | MyCat中间服务器 |
192.168.40.138 | MySQL | 分片服务器 |
192.168.40.150 | MySQL | 分片服务器 |
1、创建数据库
三台服务器都创建一个db1的数据库,在此之前先关闭防火墙,创建完之后先不需要对该库进行任何操作,所有的操作都在MyCat所在的服务器上进行。
mysql> create database db1;
Query OK, 1 row affected (0.02 sec)
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| db1 |
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
5 rows in set (0.06 sec)
2、分片配置(schema.xml)
[root@mysql-master conf]# pwd
/usr/local/mycat/conf
[root@mysql-master conf]# cat 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">
<table name="orders" dataNode="dn1,dn2,dn3" rule="auto-sharding-long" />
</schema>
<dataNode name="dn1" dataHost="dhost1" database="db1" />
<dataNode name="dn2" dataHost="dhost2" database="db1" />
<dataNode name="dn3" dataHost="dhost3" database="db1" />
<dataHost name="dhost1" maxCon="1000" minCon="10" balance="0"
writeType="0" dbType="mysql" dbDriver="jdbc" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<writeHost host="hostM1" url="jdbc:mysql://192.168.40.137:3306?useSSL=false&serverTimezone=Asia/Shanghai&characterEncoding=utf8" user="root"
password="123456">
</writeHost>
</dataHost>
<dataHost name="dhost2" maxCon="1000" minCon="10" balance="0"
writeType="0" dbType="mysql" dbDriver="jdbc" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<writeHost host="hostM1" url="jdbc:mysql://192.168.40.138:3306?useSSL=false&serverTimezone=Asia/Shanghai&characterEncoding=utf8" user="root"
password="123456">
</writeHost>
</dataHost>
<dataHost name="dhost3" maxCon="1000" minCon="10" balance="0"
writeType="0" dbType="mysql" dbDriver="jdbc" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<writeHost host="hostM1" url="jdbc:mysql://192.168.40.139:3306?useSSL=false&serverTimezone=Asia/Shanghai&characterEncoding=utf8" user="root"
password="123456">
</writeHost>
</dataHost>
</mycat:schema>
3、分片配置(server.xml)
配置mycat的用户和用户的权限信息
4、启动服务
切换到MyCat的安装目录,执行如下指令,启动MyCat
# 启动 占用端口8066
[root@mysql-master mycat]# bin/mycat start
Starting Mycat-server...
# 停止
bin/mycat stop
5、查看日志,看是否启动成功
[root@mysql-master logs]# pwd
/usr/local/mycat/logs
6、登录MyCat
[root@mysql-master mycat]# mysql -h 192.168.40.137 -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.3-release-20210913163959 MyCat Server (OpenCloudDB)
Copyright (c) 2000, 2023, 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>
7、查看数据库和表
发现只有一个逻辑数据库和一个逻辑表,并没有真实存在
mysql> show databases;
+----------+
| DATABASE |
+----------+
| DB01 |
+----------+
1 row in set (0.00 sec)
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> show tables;
+----------------+
| Tables in DB01 |
+----------------+
| orders |
+----------------+
1 row in set (0.00 sec)
8、创建表结构并且插入数据
在这之前,要为每一个mysql服务器(不是MyCat服务器)设置远程连接的功能,不然会提示错误,无法创建表结构,执行如下命令
mysql> alter user 'root'@'%' IDENTIFIED WITH mysql_native_password BY '123456';
Query OK, 0 rows affected (0.01 sec)
mysql> grant all on *.* to 'root'@'%';
Query OK, 0 rows affected (0.00 sec)
创建表结构
mysql> CREATE TABLE orders (
-> id INT NOT NULL,
-> product_name VARCHAR(50) NOT NULL,
-> price DECIMAL(10,2) NOT NULL,
-> quantity INT NOT NULL,
-> order_date DATE NOT NULL,
-> PRIMARY KEY (id)
-> );
Query OK, 0 rows affected (0.07 sec)
OK!
插入数据,因为用分片规则是auto-sharding-long,所以可以设置不同大小的id数据插入。
mysql> INSERT INTO orders (id, product_name, price, quantity, order_date) VALUES
-> (1, 'Product 1', 10.50, 2, '2023-06-06'),
-> (2, 'Product 2', 25.00, 1, '2023-06-05'),
-> (3, 'Product 3', 15.75, 3, '2023-06-04'),
-> (5000001, 'Product 4', 5.99, 5, '2023-06-03'),
-> (5000002, 'Product 5', 5.99, 4, '2023-06-01'),
-> (10000003, 'Product 6', 5.99, 5, '2023-05-03');
Query OK, 6 rows affected (0.02 sec)
OK!
9、查看数据分布
MyCat配置
schema.xml
schema标签
<schema name="DB01" checkSQLschema="true" sqlMaxLimit="100">
<table name="orders" dataNode="dn1,dn2,dn3" rule="auto-sharding-long" />
</schema>
schema标签用于定义MyCat实例中的数据库,一个MyCat实例中可以有多个逻辑库,可以通过schmea标签来划分不同的逻辑库。MyCat中的逻辑库的概念,等同于MySQL中的database概念,需要操作某个逻辑库下的表时,也需要切换逻辑库。
- name:指定自定义逻辑库名
- checkSQLschema:在sql语句操作时指定了数据库名称,执行时是否自动去除;true,自动去除;false,不自动去除。
- sqlMaxLimit:查询数据的最大条数
table标签
table标签定义了MyCat中逻辑库下的逻辑表,所有需要拆分的表都在table标签中定义。
- name:定义逻辑表名
- dataNode:定义逻辑表所属的dataNode,该属性需要与dataNode标签中的name对应,多个dataNode需要逗号分隔。
- rule:分片规则的名字,是在rule.xml文件中定义的
- primaryKey:逻辑表对应真实的主键
- type:逻辑表的类型,如果未配置就是普通表;全局表配置为global
dataNode标签
<dataNode name="dn1" dataHost="dhost1" database="db1" />
<dataNode name="dn2" dataHost="dhost2" database="db1" />
<dataNode name="dn3" dataHost="dhost3" database="db1" />
dataNode标签定义了MyCat中的数据节点,也就是数据分片,一个dataNode标签就是一个数据分片。
- name:定义数据节点的名称
- dataHost:数据库实例主机名称,引用dataHost标签中的name属性
- database:定义分片所属数据库
dataHost标签
<dataHost name="dhost1" maxCon="1000" minCon="10" balance="0"
writeType="0" dbType="mysql" dbDriver="jdbc" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<writeHost host="hostM1" url="jdbc:mysql://192.168.40.137:3306?useSSL=false&serverTimezone=Asia/Shanghai&characterEncoding=utf8" user="root"
password="123456">
</writeHost>
</dataHost>
该标签定义了具体的数据库实例、读写分离、心跳语句
- name:唯一标识,供上层连接使用
- maxCon/minCon:最大、最小连接数
- balance:负载均衡策略,取值0,1,2,3
- writeType:写操作分发方式(0:写操作转发到第一个writeHost上,第一个挂了,切换到第二个;1:写操作随机分发到配置的writeHost)
- dbDriver:数据库驱动
- switchType:表示主从切换的方式,取值可以为
1
或2
。其中,1
表示基于读写分离的主从切换方式,2
则表示基于半同步复制的主从切换方式。 - slaveThreshold: 表示从节点的最大延迟时间,单位是毫秒。当从节点的延迟时间超过该阈值时,MyCat 会自动将主节点切换到延迟时间更小的从节点上,以保证集群的高可用性和稳定性。
rule.xml
rule.xml文件中定义所有拆分表的规则,在使用过程中可以灵活使用分片算法,或者对同一个分片算法使用不通的参数。主要有tableRule和Function标签。
<tableRule name="auto-sharding-long">
<rule>
<columns>id</columns> # 根据哪个字段进行分片
<algorithm>rang-long</algorithm> # 分片的规则
</rule>
</tableRule>
server.xml
server.xml配置文件包含了MyCat的系统配置信息,主要有两个重要的标签:system、user
system标签
system标签主要配置系统运行时的一些环境信息
<system>
<property name="nonePasswordLogin">0</property> <!-- 0为需要密码登陆、1为不需要密码登陆 ,默认为0,设置为1则需要指定默认账户-->
<property name="useHandshakeV10">1</property>
<property name="useSqlStat">0</property> <!-- 1为开启实时统计、0为关闭 -->
<property name="useGlobleTableCheck">0</property> <!-- 1为开启全加班一致性检测、0为关闭 -->
<property name="sqlExecuteTimeout">300</property> <!-- SQL 执行超时 单位:秒-->
<property name="sequnceHandlerType">2</property>
<!--必须带有MYCATSEQ_或者 mycatseq_进入序列匹配流程 注意MYCATSEQ_有空格的情况-->
<property name="sequnceHandlerPattern">(?:(\s*next\s+value\s+for\s*MYCATSEQ_(\w+))(,|\)|\s)*)+</property>
<property name="subqueryRelationshipCheck">false</property> <!-- 子查询中存在关联查询的情况下,检查关联字段中是否有分片字段 .默认 false -->
<!--分布式事务开关,0为不过滤分布式事务,1为过滤分布式事务(如果分布式事务内只涉及全局表,则不过滤),2为不过滤分布式事务,但是记录分布式事务日志-->
<property name="handleDistributedTransactions">0</property>
<!--
off heap for merge/order/group/limit 1开启 0关闭
-->
<property name="useOffHeapForMerge">0</property>
<!--
单位为m
-->
<property name="memoryPageSize">64k</property>
<!--
单位为k
-->
<property name="spillsFileBufferSize">1k</property>
<property name="useStreamOutput">0</property>
<!--
单位为m
-->
<property name="systemReserveMemorySize">384m</property>
<!--是否采用zookeeper协调切换 -->
<property name="useZKSwitch">false</property>
<!-- XA Recovery Log日志路径 -->
<!--<property name="XARecoveryLogBaseDir">./</property>-->
<!-- XA Recovery Log日志名称 -->
<!--<property name="XARecoveryLogBaseName">tmlog</property>-->
<!--如果为 true的话 严格遵守隔离级别,不会在仅仅只有select语句的时候在事务中切换连接-->
<property name="strictTxIsolation">false</property>
<property name="useZKSwitch">true</property>
</system>
user标签
user标签主要配置MyCat中间件能够被哪些用户访问,访问哪些数据库,访问的权限是什么等。
MyCat原理
MyCat原理中最重要的一个动词是“拦截”,它拦截了用户发送过来的SQL语句,首先对SQL语句做了一些特定的分析:如解析SQL、分片分析、路由分析、读写分离分析,然后将此SQL发往后端的真实数据库,并将返回的结果做适当的处理,如结果合并、聚合处理、排序处理、分页处理,最终再返回给用户
MyCat管理
MyCat默认开通2个端口,可以在server.xml文件中进行修改
8066数据访问端口,9066数据库管理端口,管理mycat的整个集群的状态。
[root@mysql-master conf]# mysql -h 192.168.40.137 -u root -P 9066 -p
mysql> show @@version;
+---------------------------------------------+
| VERSION |
+---------------------------------------------+
| 5.6.29-mycat-1.6.7.3-release-20210913163959 |
+---------------------------------------------+
1 row in set (0.02 sec)
mysql> show @@datasource;
+----------+--------+-------+----------------+------+------+--------+------+------+---------+-----------+------------+
| DATANODE | NAME | TYPE | HOST | PORT | W/R | ACTIVE | IDLE | SIZE | EXECUTE | READ_LOAD | WRITE_LOAD |
+----------+--------+-------+----------------+------+------+--------+------+------+---------+-----------+------------+
| dn1 | hostM1 | mysql | 192.168.40.137 | 3306 | W | 0 | 8 | 1000 | 26 | 0 | 8 |
| dn3 | hostM1 | mysql | 192.168.40.139 | 3306 | W | 0 | 8 | 1000 | 32 | 0 | 6 |
| dn2 | hostM1 | mysql | 192.168.40.138 | 3306 | W | 0 | 8 | 1000 | 32 | 0 | 6 |
+----------+--------+-------+----------------+------+------+--------+------+------+---------+-----------+------------+
3 rows in set (0.02 sec)