MyCat2数据库分库分表,读写分离中间件(踩坑大实战内附详细图文教程)

目录

介绍

安装使用

搭建mysql主从复制

搭建主机

配置从机 

读写分离配置

 验证主从读写分离

分库分表

原理

分库原则

分表

正式分库分表

 添加集群配置

创建全局表(广播表)

 在 Mycat 终端直接运行建表语句进行数据分片

创建 ER 表

常用分片规则 

1、分片算法简介

2、Mycat2 与 1.x 版本区别

3、分片规则与适用性

4、常用分片规则简介

(1)MOD_HASH

(2)RIGHT_SHIFT

(3)YYYYMM

(4)MMDD

全局序列


介绍

1.读写分离

Java操作MyCat,Mycat作为数据源访问,根据Java读、写请求分发到主从Mysql上,从而实现了读写分离。

2.数据分片

对数据库垂直拆分(分库)、对表水平拆分(分表)、对数据库垂直与表水平拆分(分库分表)

3.多数据源整合

Java操作MyCat,Mycat作为数据源访问,根据不同业务进行数据源划分,MyCat访问不同的数据源(MySql、MongoDB),从而实现多数据源整合。

Mycat 的原理中最重要的一个动词是“拦截”,它拦截了用户发送过来的 SQL
句,首先对 SQL 语句做了一些特定的分析:如分片分析、路由分析、读写分离分析、 缓存分析等,然后将此 SQL 发往后端的真实数据库,并将返回的结果做适当的处理,
最终再返回给用户
MyCat2数据库分库分表,读写分离中间件(踩坑大实战内附详细图文教程)_第1张图片

安装使用

mycat工具包
提取码:k06y

登录进服务器中,将解压后的文件夹mycat传到服务器上,这里可以直接下载博主提供的,本博主也把原先需要copy在lib目录的jar包也已copy压缩好,所以可以直接上传服务器

注意mycat启动需要依赖jdk8或者以上环境,启动前需在服务器上部署好jdk环境

MyCat2数据库分库分表,读写分离中间件(踩坑大实战内附详细图文教程)_第2张图片

 MyCat2数据库分库分表,读写分离中间件(踩坑大实战内附详细图文教程)_第3张图片

 更改文件权限

进入到mycat的bin目录下更改必需文件的权限

MyCat2数据库分库分表,读写分离中间件(踩坑大实战内附详细图文教程)_第4张图片

 更改这四个文件的权限为777MyCat2数据库分库分表,读写分离中间件(踩坑大实战内附详细图文教程)_第5张图片

 MyCat2数据库分库分表,读写分离中间件(踩坑大实战内附详细图文教程)_第6张图片

 更改数据库配置

进入到mycat的conf目录下更改数据源配置

MyCat2数据库分库分表,读写分离中间件(踩坑大实战内附详细图文教程)_第7张图片

 MyCat2数据库分库分表,读写分离中间件(踩坑大实战内附详细图文教程)_第8张图片

更改后保存

本人实际踩坑,按照网上绝大多数教程这里直接就启动mycat使用navicat连接就可以了,其实还需要再更改一个mycat的用户配置:

MyCat2数据库分库分表,读写分离中间件(踩坑大实战内附详细图文教程)_第9张图片

 MyCat2数据库分库分表,读写分离中间件(踩坑大实战内附详细图文教程)_第10张图片

MyCat2数据库分库分表,读写分离中间件(踩坑大实战内附详细图文教程)_第11张图片

实际踩坑,这里博主因为没有改动这里的配置导致后面navicat连接时一直连接不上,被搞了一天的心态都快崩了o(╥﹏╥)o 

 进入到mycat的bin目录下启动mycat

MyCat2数据库分库分表,读写分离中间件(踩坑大实战内附详细图文教程)_第12张图片

输入jps,出现wrapperSimpleApp说明mycat启动成功

MyCat2数据库分库分表,读写分离中间件(踩坑大实战内附详细图文教程)_第13张图片

 连接数据库

mysql -u账户 -p密码 -P 8066

MyCat2数据库分库分表,读写分离中间件(踩坑大实战内附详细图文教程)_第14张图片

 连接成功

搭建mysql主从复制

准备两个服务器,两个服务器都提前安装好mysql,开始搭建主从复制

这里以5.7为主,5.8为从机,最好是版本相同的进行搭建,这里由于服务器上已经分别搭建好了5.7mysql和5.8就不再重装了,直接开始

搭建主机

5.7版本mysql的配置文件是/etc目录下的my.cnf文件

找到该文件进行主机配置

MyCat2数据库分库分表,读写分离中间件(踩坑大实战内附详细图文教程)_第15张图片

 #主机设置
#主服务器唯一ID
server-id=1
#启用二进制日志
log-bin=mysql-bin
# 设置不要复制的数据库(可设置多个)
binlog-ignore-db=mysql
binlog-ignore-db=information_schema
#设置需要复制的数据库
binlog-do-db=wusql
#设置logbin格式
binlog_format=STATEMENT

MyCat2数据库分库分表,读写分离中间件(踩坑大实战内附详细图文教程)_第16张图片

 设置后重启主机mysql

systemctl restart mysqld.service

在主机 MySQL 里执行创建slave用户并授权命令,按顺序执行下面语句即可
CREATE USER 'slave'@'%' IDENTIFIED BY '密码';
ALTER USER 'slave'@'%' IDENTIFIED WITH mysql_native_password BY '密码';
GRANT REPLICATION SLAVE ON *.* TO 'slave'@'%';
flush privileges;
# 查询 master 的状态
show master status;

MyCat2数据库分库分表,读写分离中间件(踩坑大实战内附详细图文教程)_第17张图片

注意file,和Position两个值等会儿要在从机中设置值

执行完此步骤后不要再操作主服务器 MySQL ,防止主服务器状态值变化

配置从机 

注意5.8版本mysql的配置文件是在/etc/my.cnf.d目录下的mysql-server.cnf文件

MyCat2数据库分库分表,读写分离中间件(踩坑大实战内附详细图文教程)_第18张图片


#从机设置

#从服务器唯一ID
server-id=22
#启用中继日志
relay-log=mysql-relay
 

MyCat2数据库分库分表,读写分离中间件(踩坑大实战内附详细图文教程)_第19张图片 配置好保存重启从机mysql

systemctl restart mysqld.service

 注意主从机都要关闭防火墙

在从机上配置需要复制的主机
复制主机命令
CHANGE MASTER TO MASTER_HOST='主机ip',
MASTER_USER='slave',
MASTER_PASSWORD='密码',MASTER_LOG_FILE='主机File值',MASTER_LOG_POS=主机Position值;

 

开始主从复制:

 start slave;

 

# 查看从服务器状态
show slave status\G;

 MyCat2数据库分库分表,读写分离中间件(踩坑大实战内附详细图文教程)_第20张图片

# 下面两个参数都是 Yes ,则说明主从配置成功!
# Slave_IO_Running: Yes
# Slave_SQL_Running: Yes
测试主从是否成功:
在主机中建立数据库wusql并建表插入语句,再查看从机中是否同步数据

创建数据库

create database wusql;
切换数据库

use wusql;

建表
create table stu(
id int,name varchar(10));

插入数据

insert stu values(1,'zhang');

MyCat2数据库分库分表,读写分离中间件(踩坑大实战内附详细图文教程)_第21张图片

 去从机中查看是否有数据同步

MyCat2数据库分库分表,读写分离中间件(踩坑大实战内附详细图文教程)_第22张图片

搭建成功(*^▽^*)! 

读写分离配置

连接mycat

MyCat2数据库分库分表,读写分离中间件(踩坑大实战内附详细图文教程)_第23张图片

 即这里配置的密码MyCat2数据库分库分表,读写分离中间件(踩坑大实战内附详细图文教程)_第24张图片

 在mycat中创建数据库wusql,注意这里mycat创建的数据库名要和主从机数据库名字一致,博主之前第一次测试时候名字故意设置不一致导致数据不同步导致失败,所以这里最好还是一致命名吧

create database wusql

MyCat2数据库分库分表,读写分离中间件(踩坑大实战内附详细图文教程)_第25张图片

修改wusql .schema.json 指定数据源 "targetName": "prototype" ,配置主机数据源

MyCat2数据库分库分表,读写分离中间件(踩坑大实战内附详细图文教程)_第26张图片

MyCat2数据库分库分表,读写分离中间件(踩坑大实战内附详细图文教程)_第27张图片

 使用注解方式添加数据源

 注意下面命令在运行时不要有换行符,不然可能会执行错误
#配置写数据源  主机
/*+mycat:createDataSource{"name":"rwSepw","url":"jdbc:mysql://主机ip:3306/wusql?useSSL=false&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true", "user":"root","password":"密码" } */;

#配置读数据源 从机
/*+mycat:createDataSource{"name":"rwSepr","url":"jdbc:mysql://从机ip:3306/wusql?useSSL=false&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true","user":"root","password":"密码" } */;


#查询配置数据源结果
/*+ mycat:showDataSources{} */;

 MyCat2数据库分库分表,读写分离中间件(踩坑大实战内附详细图文教程)_第28张图片

 配置成功

更新集群信息 , 添加 dr0 从节点 . 实现读写分离
/*!mycat:createCluster{"name":"prototype","masters":["rwSepw"],"replicas":["rwSepr"]} */;

 MyCat2数据库分库分表,读写分离中间件(踩坑大实战内附详细图文教程)_第29张图片

 查看配置集群信息

/*+ mycat:showClusters{} */;

 查看集群配置文件

vim /usr/local/mycat/conf/clusters/prototype.cluster.json

 MyCat2数据库分库分表,读写分离中间件(踩坑大实战内附详细图文教程)_第30张图片

 MyCat2数据库分库分表,读写分离中间件(踩坑大实战内附详细图文教程)_第31张图片

readBalanceType
查询负载均衡策略
可选值 :
BALANCE_ALL( 默认值 )
获取集群中所有数据源
BALANCE_ALL_READ
获取集群中允许读的数据源
BALANCE_READ_WRITE
获取集群中允许读写的数据源 , 但允许读的数据源优先
BALANCE_NONE 获取集群中允许写数据源 , 即主节点中选择
switchType
NOT_SWITCH: 不进行主从切换
SWITCH: 进行主从切换
重启mycat
在mycat的bin目录下重启
./mycat restart
MyCat2数据库分库分表,读写分离中间件(踩坑大实战内附详细图文教程)_第32张图片

 刷新mycat连接

MyCat2数据库分库分表,读写分离中间件(踩坑大实战内附详细图文教程)_第33张图片

可以看到读取到了之前主表里插入的数据

 验证主从读写分离

由于之前配置的主从关系,所以此时主机和从机表数据都是一致的,所以这里看不出来区别,可以手动在从表中插入一条数据,这样主表不会更新,就造成了主表从表数据不一致的情况

此时的主表数据

MyCat2数据库分库分表,读写分离中间件(踩坑大实战内附详细图文教程)_第34张图片

 MyCat2数据库分库分表,读写分离中间件(踩坑大实战内附详细图文教程)_第35张图片

在从表中插入一条数据

 MyCat2数据库分库分表,读写分离中间件(踩坑大实战内附详细图文教程)_第36张图片查看主表数据 

MyCat2数据库分库分表,读写分离中间件(踩坑大实战内附详细图文教程)_第37张图片

主表还是四条数据,此时就造成了主从不一致

此时再去mycat中查看数据

 可以看到mycat在轮询显示主表和从表的数据

这是因为之前的配置中是获取所有数据源的数据,所以无论是主机和从机数据都会获取到,默认轮询获取

MyCat2数据库分库分表,读写分离中间件(踩坑大实战内附详细图文教程)_第38张图片

分库分表

原理

一个数据库由很多表的构成,每个表对应着不同的业务,垂直切分是指按照业
务将表进行分类,分布到不同 的数据库上面,这样也就将数据或者说压力分担到不同
的库上面

分库原则

一个问题:在两台主机上的两个数据库中的表,能否关联查询?

答案:不可以关联查询。
分库的原则:有紧密关联关系的表应该在一个库里,相互没有关联关系的表可以分到
不同的库里。

分表

MySQL 单表存储数据条数是有瓶颈的,单表达到 1000 万条数据就达到了瓶颈,会
影响查询效率,需要进行水平拆分(分表)进行优化。

正式分库分表

添加数据库、存储数据源

/*+ mycat:createDataSource{
"name":"dw0","url":"jdbc:mysql://ip:3306",
"user":"root",
"password":"密码"
} */;
/*+ mycat:createDataSource{
"name":"dr0",
"url":"jdbc:mysql://ip:3306",
"user":"root",
"password":"密码"
} */;
/*+ mycat:createDataSource{
"name":"dw1",
"url":"jdbc:mysql://ip:3306",
"user":"root",
"password":"密码"
} */;
/*+ mycat:createDataSource{
"name":"dr1",
"url":"jdbc:mysql://ip:3306",
"user":"root",
"password":"密码"
} */;
通过注释命名添加数据源后,在对应目录会生成相关配置文件
找到自己的mycat安装目录
cd /usr/mycat/conf/datasources

 MyCat2数据库分库分表,读写分离中间件(踩坑大实战内附详细图文教程)_第39张图片

 MyCat2数据库分库分表,读写分离中间件(踩坑大实战内附详细图文教程)_第40张图片

 添加集群配置

把新添加的数据源配置成集群

mycat 终端输入

MyCat2数据库分库分表,读写分离中间件(踩坑大实战内附详细图文教程)_第41张图片

/*!
mycat:createCluster{"name":"c0","masters":["dw0"],"replicas":["dr0"]}
*/;
/*!
mycat:createCluster{"name":"c1","masters":["dw1"],"replicas":["dr1"]}
*/;

 可以查看集群配置信息

cd /usr/mycat/conf/clusters

两个集群 

MyCat2数据库分库分表,读写分离中间件(踩坑大实战内附详细图文教程)_第42张图片 MyCat2数据库分库分表,读写分离中间件(踩坑大实战内附详细图文教程)_第43张图片

创建全局表(广播表)

创建数据库db1

create database db1

切换到db1

use db1;

在建表语句中加上关键字 BROADCAST(广播,即为全局表)

CREATE TABLE db1.`travelrecord` (
`id` bigint NOT NULL AUTO_INCREMENT,
`user_id` varchar(100) DEFAULT NULL,
`traveldate` date DEFAULT NULL,
`fee` decimal(10,0) DEFAULT NULL,
`days` int DEFAULT NULL,
`blob` longblob,
PRIMARY KEY (`id`),
KEY `id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 BROADCAST;

 MyCat2数据库分库分表,读写分离中间件(踩坑大实战内附详细图文教程)_第44张图片

 可以看到主机和从机也都同步了db1数据库

MyCat2数据库分库分表,读写分离中间件(踩坑大实战内附详细图文教程)_第45张图片

 进入mycat安装目录查看db1数据库配置

MyCat2数据库分库分表,读写分离中间件(踩坑大实战内附详细图文教程)_第46张图片

 MyCat2数据库分库分表,读写分离中间件(踩坑大实战内附详细图文教程)_第47张图片

 在 Mycat 终端直接运行建表语句进行数据分片

核心就是后面的分片规则。 dbpartition表示分库规则,tbpartition表示分表规则。而mod hash表示按照customer id字段取模进行分片

tbpartitions 1 dbpartitions 2 表示分一片,数据库两个

CREATE TABLE db1.orders(
id BIGINT NOT NULL AUTO_INCREMENT,
order_type INT,
customer_id INT,
amount DECIMAL(10,2),
PRIMARY KEY(id),
KEY `id` (`id`)
)ENGINE=INNODB DEFAULT CHARSET=utf8
dbpartition BY mod_hash(customer_id) tbpartition BY mod_hash(customer_id)
tbpartitions 1 dbpartitions 2;

 MyCat2数据库分库分表,读写分离中间件(踩坑大实战内附详细图文教程)_第48张图片

 数据库分片规则,表分片规则,以及各分多少片

插入语句测试:

INSERT INTO orders(id,order_type,customer_id,amount)
VALUES(1,101,100,100100);
INSERT INTO orders(id,order_type,customer_id,amount)
VALUES(2,101,100,100300);
INSERT INTO orders(id,order_type,customer_id,amount)
VALUES(3,101,101,120000);
INSERT INTO orders(id,order_type,customer_id,amount)
VALUES(4,101,101,103000);
INSERT INTO orders(id,order_type,customer_id,amount)
VALUES(5,102,101,100400);
INSERT INTO orders(id,order_type,customer_id,amount)
VALUES(6,102,100,100020);

 在mycat中查看数据

MyCat2数据库分库分表,读写分离中间件(踩坑大实战内附详细图文教程)_第49张图片

在主机中查看:

 MyCat2数据库分库分表,读写分离中间件(踩坑大实战内附详细图文教程)_第50张图片

可以看到主机中直接创建了两个新的db库

分别查看两个db库的数据

MyCat2数据库分库分表,读写分离中间件(踩坑大实战内附详细图文教程)_第51张图片 

 MyCat2数据库分库分表,读写分离中间件(踩坑大实战内附详细图文教程)_第52张图片

 可以看到两个db库分别有三条数据,总和就是mycat的六条数据,从而实现了分库分表功能

创建 ER 表

与分片表关联的表如何分表,也就是 ER 表如何分表

在 Mycat 终端直接运行建表语句进行数据分片

CREATE TABLE orders_detail(
`id` BIGINT NOT NULL AUTO_INCREMENT,
detail VARCHAR(2000),
order_id INT,
PRIMARY KEY(id)
)ENGINE=INNODB DEFAULT CHARSET=utf8
dbpartition BY mod_hash(order_id) tbpartition BY mod_hash(order_id)
tbpartitions 1 dbpartitions 2;

MyCat2数据库分库分表,读写分离中间件(踩坑大实战内附详细图文教程)_第53张图片 

 插入数据测试:

INSERT INTO orders_detail(id,detail,order_id) VALUES(1,'detail1',1); INSERT INTO orders_detail(id,detail,order_id) VALUES(2,'detail1',2); INSERT INTO orders_detail(id,detail,order_id) VALUES(3,'detail1',3); INSERT INTO orders_detail(id,detail,order_id) VALUES(4,'detail1',4); INSERT INTO orders_detail(id,detail,order_id) VALUES(5,'detail1',5); INSERT INTO orders_detail(id,detail,order_id) VALUES(6,'detail1',6);

运行关联语句查询数据

SELECT * FROM orders o INNER JOIN orders_detail od ON od.order_id=o.id; 

 MyCat2数据库分库分表,读写分离中间件(踩坑大实战内附详细图文教程)_第54张图片

对比数据节点1

MyCat2数据库分库分表,读写分离中间件(踩坑大实战内附详细图文教程)_第55张图片

对比数据节点2

MyCat2数据库分库分表,读写分离中间件(踩坑大实战内附详细图文教程)_第56张图片 

 两个数据库节点中的关联表中的数据并不都是完全对应的,但是关联语句却可以查询出所有关联字段数据

上述两表具有相同的分片算法,但是分片字段不相同

Mycat2 在涉及这两个表的 join 分片字段等价关系的时候可以完成 join 的下推

Mycat2 无需指定 ER 表,是自动识别的,具体看分片算法的接口

查看配置的表是否具有 ER关系

/*+ mycat:showErGroup{}*/

MyCat2数据库分库分表,读写分离中间件(踩坑大实战内附详细图文教程)_第57张图片

 可以看到group_id 表示相同的组,该组中的表具有相同的存储分布

原理如下:

MyCat2数据库分库分表,读写分离中间件(踩坑大实战内附详细图文教程)_第58张图片

常用分片规则 

1、分片算法简介

Mycat2 支持常用的(自动)HASH 型分片算法也兼容 1.6 的内置的(cobar)分片算法. HASH 型分片算法默认要求集群名字以 c 为前缀,数字为后缀,c0 就是分片表第一个 节点,c1 就是第二个节点.该命名规则允许用户手动改变

2、Mycat2 与 1.x 版本区别

Mycat2 Hash 型分片算法多数基于 MOD_HASH(MOD 对应 JAVA 的%运算),实际上是取 余运算。 Mycat2 Hash 型分片算法对于值的处理,总是把分片值转换到列属性的数据类型再 运算。 而 1.x 系列的分片算法统一转换到字符串类型再运算且只能根据一个分片字段计算 出存储节点下标。 Mycat2 Hash 型分片算法适用于等价条件查询。 而 1.x 系列由于含有用户经验的路由规则。1.x 系列的分片规则总是先转换成字符 串再运算。

3、分片规则与适用性

MyCat2数据库分库分表,读写分离中间件(踩坑大实战内附详细图文教程)_第59张图片

 MyCat2数据库分库分表,读写分离中间件(踩坑大实战内附详细图文教程)_第60张图片

4、常用分片规则简介
(1)MOD_HASH

[数据分片]HASH 型分片算法-MOD_HASH 如果分片值是字符串则先对字符串进行 hash 转换为数值类型 分库键和分表键是同键: 分表下标=分片值%(分库数量*分表数量) 分库下标=分表下标/分表数量 分库键和分表键是不同键: 分表下标= 分片值%分表数量 分库下标= 分片值%分库数量

(2)RIGHT_SHIFT

[数据分片]HASH 型分片算法-RIGHT_SHIFT RIGHT_SHIFT(字段名,位移数) 仅支持数值类型 分片值右移二进制位数,然后按分片数量取余 

(3)YYYYMM

[数据分片]HASH 型分片算法-YYYYMM 仅用于分库 (YYYY*12+MM)%分库数.MM 是 1-12

(4)MMDD

仅用于分表 仅 DATE/DATETIME 一年之中第几天%分表数 tbpartitions 不超过 366

全局序列

Mycat2 在 1.x 版本上简化全局序列,自动默认使用雪花算法生成全局序列号,如 不需要 Mycat 默认的全局序列,可以通过配置关闭自动全局序列

带 AUTO_INCREMENT 关键字使用默认全局序列

如果不需要使用 mycat 的自增序列,而使用 mysql 本身的自增主键的功能,需要在 配置中更改对应的建表 sql,不设置 AUTO_INCREMENT 关键字,这样,mycat 就不认为这个 表有自增主键的功能,就不会使用 mycat 的全局序列号.这样,对应的插入 sql 在 mysql 处理,由 mysql 的自增主键功能补全自增值. 雪花算法:引入了时间戳和 ID 保持自增的分布式 ID 生成算法

你可能感兴趣的:(mysql,数据库,mysql,读写分离,mycat,mycat2,分库分表)