一文带你从不知道数据库中间件MyCat到实战落地


1、本博客主要参考尚硅谷的Mycat视频教程,整理不易,还请读者见谅。

2、尚硅谷的有些视频还不错(PS:不是广告,毕竟看了人家比较好的教程,得给人家打个call

3、视频地址:尚硅谷Mycat核心教程(mycat实战应用)


Mycat是什么

Mycat 是数据库中间件

  1. 数据库中间件
    中间件:是一类连接软件组件和应用的计算机软件,以便于软件各部件之间的沟通。
    例子:Tomcat,web中间件。
    数据库中间件:连接java应用程序和数据库
  2. 为什么要用Mycat?
    ① Java与数据库紧耦合。
    ② 高访问量高并发对数据库的压力。
    ③ 读写请求数据不一致

数据库中间件对比

一文带你从不知道数据库中间件MyCat到实战落地_第1张图片

Mycat可以做什么

读写分离

一文带你从不知道数据库中间件MyCat到实战落地_第2张图片

数据分片

垂直拆分(分库)、水平拆分(分表)、垂直+水平拆分(分库分表)

一文带你从不知道数据库中间件MyCat到实战落地_第3张图片

多数据源整合

一文带你从不知道数据库中间件MyCat到实战落地_第4张图片

Mycat原理

Mycat 的原理中最重要的一个动词是“拦截”,它拦截了用户发送过来的 SQL 语句,首先对 SQL语句做了一些特定的分析:如分片分析、路由分析、读写分离分析、缓存分析等,然后将此 SQL 发往后端的真实数据库,并将返回的结果做适当的处理,最终再返回给用户。

一文带你从不知道数据库中间件MyCat到实战落地_第5张图片

Mycat安装启动

配置

  • Linux ContOS7(虚拟机)
  • Mycat1.6

安装

下载地址:https://github.com/MyCATApache/Mycat-download/tree/master/1.6-RELEASE

一文带你从不知道数据库中间件MyCat到实战落地_第6张图片

然后上传到 /usr/lcoal 目录下

cd /usr/local

解压一下,就下图所示即可

一文带你从不知道数据库中间件MyCat到实战落地_第7张图片

三个配置文件(重要)

schema.xml:定义逻辑库,表、分片节点等内容
rule.xml:定义分片规则
server.xml:定义用户以及系统相关变量,如端口等

启动

修改配置文件 server.xml

vim /usr/local/mycat/conf/server.xml

一文带你从不知道数据库中间件MyCat到实战落地_第8张图片

修改配置文件 schema.xml


DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">

    <schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn1">schema>
    <dataNode name="dn1" dataHost="host1" database="testdb" />

    <dataHost name="host1" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
        <heartbeat>select user()heartbeat>
        
        <writeHost host="hostM1" url="192.168.88.139:3306" user="root" password="123456">
            
            <readHost host="hostS2" url="192.168.88.138:3306" user="root" password="123456" />
        writeHost>
    dataHost>

mycat:schema>

可以看出来,上面是配置的是读写分离,所以等一下我们要在配置MySQL的主从配置

启动程序

cd /usr/local/mycat/bin

① 控制台启动 :去 mycat/bin 目录下执行 ./mycat console
② 后台启动:去 mycat/bin 目录下 ./mycat start

说明 指令
启动 ./mycat start
停止 ./mycat stop
前台运行 ./mycat console
重启服务 ./mycat restart
暂停 ./mycat pause
查看启动状态 ./mycat status

登录

我们启动之后使用命令行登录一下,命令和MySQL差不多

mysql -umycat -p123456 -h 192.168.88.137 -P 8066

搭建读写分离

配置

  • MySQL8.0.27
  • Linux ContOS7(虚拟机)

我们通过 Mycat 和 MySQL 的主从复制配合搭建数据库的读写分离,实现 MySQL 的高可用性。
我们将搭建:一主一从、双主双从两种读写分离模式。

搭建一主一从

一个主机用于处理所有写请求,一台从机负责所有读请求,架构图如下
一文带你从不知道数据库中间件MyCat到实战落地_第9张图片

搭建MySQL数据库主从复制

MySQL 主从复制原理

一文带你从不知道数据库中间件MyCat到实战落地_第10张图片

https://blog.csdn.net/K_520_W/article/details/117135287

https://zhuanlan.zhihu.com/p/343538668

主机配置

修改MySQL配置文件

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

binlog 日志三种格式:https://blog.csdn.net/u011334954/article/details/121471967

配置完之后重启MySQL服务

systemctl resatrt mysqld
mysql -uroot -p123456

创建一个主从复制的账号并授权,这个是在MySQL中进行添加设置的

set global validate_password.policy = "LOW";

create user 'account'@'%' identified by 'ABC123456';

grant all privileges on *.* to 'account'@'%';

FLUSH PRIVILEGES;

权限参考

  • all 所有权限
  • select 查询权限
  • insert 插入权限
  • delete 删除权限
  • update 更新权限

查询master的状态

show master status;

一文带你从不知道数据库中间件MyCat到实战落地_第11张图片认真的看下 FilePosition 的值,等下从机要使用的

从机配置

修改MySQL配置文件

vim /etc/my.cnf
#从服务器唯一ID
server-id=2
#启用中继日志
relay-log=mysql-relay

配置完之后重启MySQL服务

systemctl resatrt mysqld
mysql -uroot -p123456

复制主机的命令,还记得我要你在主机那里记得那两个值吗?,现在派上用场了

CHANGE MASTER TO MASTER_HOST='主机的IP地址',
MASTER_USER='slave',
MASTER_PASSWORD='123123',
MASTER_LOG_FILE='mysql-bin.具体数字',MASTER_LOG_POS=具体值;

在这里插入图片描述

启动从服务器复制功能

start slave;

查看从服务器状态

show slave status\G;

一文带你从不知道数据库中间件MyCat到实战落地_第12张图片
下面两个参数都是Yes,则说明主从配置成功!
Slave_IO_Running: Yes
Slave_SQL_Running: Yes

如果出现问题了就去看一下日志,这里面有日志的

如何停止从服务复制功能,在MySQL命令行中执行

stop slave;

如何重新配置主从,在MySQL命令行中执行

stop slave;

reset master;

测试

主机进行新建数据库

create DATABASE testdb;

在主机进行添加表

CREATE TABLE `mytbl` (
  `id` int NOT NULL,
  `name` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

新增数据

insert into mytbl(id,name) values (1,"白色");
insert into mytbl(id,name) values (2,"黑色");

然后在看一下从机是不是也有了

Mycat配置MySQL读写分离

由于mycat1.6仅支持MySQL5不支持MySQL8,首先需要替换bin目录下面的mysq驱动文件为对应版本的,查看mysq版本,如果你是MySQL5的版本不需要改动如果是MySQL8的请跟我一起进行配置

一文带你从不知道数据库中间件MyCat到实战落地_第13张图片

修改文件为可执行

chmod a+x mysql-connector-java-8.0.27.jar

一文带你从不知道数据库中间件MyCat到实战落地_第14张图片

修改schema.xml的配置

vim /usr/local/mycat/conf/schema.xml

DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">

    <schema name="TESTDB" checkSQLschema="true" sqlMaxLimit="100" dataNode="dn1">schema>
    <dataNode name="dn1" dataHost="host1" database="testdb" />

    <dataHost name="host1" 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.88.139:3306/testdb?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8" user="root" password="123456">
            <readHost host="hostS2" url="jdbc:mysql://192.168.88.138:3306/testdb?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8" user="root" password="123456" />
        writeHost>
    dataHost>

mycat:schema>

启动

cd /usr/local/mycat/bin

./mycat console
参考网站
https://blog.csdn.net/yangshuai518/article/details/81589349
https://cloud.tencent.com/developer/article/2146190
https://www.itze.cn/mycat/890.html
https://www.ngui.cc/el/383877.html?action=onClick
https://blog.csdn.net/apachesolr/article/details/113766949

验证主从读写分离

在写主机数据库表mytbl 中插入带系统变量数据,造成主从数据不一致

修改Linux主机名:https://blog.csdn.net/m0_67391270/article/details/124502632,修改完记得重启一下

INSERT INTO mytbl VALUES(3,@@hostname);

修改balance属性,通过此属性配置读写分离的类型

负载均衡类型,目前的取值有4 种:

  1. balance=“0”, 不开启读写分离机制,所有读操作都发送到当前可用的 writeHost 上。
  2. balance=“1”,全部的 readHost 与 stand by writeHost 参与 select 语句的负载均衡,简单的说,当双主双从模式(M1->S1,M2->S2,并且 M1 与 M2 互为主备),正常情况下,M2,S1,S2 都参与 select 语句的负载均衡。
  3. balance=“2”,所有读操作都随机的在 writeHost、readhost 上分发。
  4. balance=“3”,所有读请求随机的分发到 readhost 执行,writerHost 不负担读压力

为了能看到读写分离的效果,把balance设置成2,会在两个主机间切换查询,然后在启动即可

一文带你从不知道数据库中间件MyCat到实战落地_第15张图片

注意

在面试的时候不要说 你配置的是 2,那你可能是真的2了,一般来说是 1 或者 3的,双主双从这种情况一般配置为 2,主从一般配置为 3

搭建双主双从

一个主机 m1 用于处理所有写请求,它的从机 s1 和另一台主机 m2 还有它的从机 s2 负责所有读请求。当 m1 主机宕机后,m2 主机负责写请求,m1、m2 互为备机。架构图如下

一文带你从不知道数据库中间件MyCat到实战落地_第16张图片

搭建MySQL数据库主从复制(双主双从)

在这里插入图片描述

双主机配置

Master1 配置,修改配置文件

vim /etc/my.cnf
#主服务器唯一ID
server-id=1
#启用二进制日志
log-bin=mysql-bin
# 设置不要复制的数据库(可设置多个)
binlog-ignore-db=mysql
binlog-ignore-db=information_schema
#设置需要复制的数据库
binlog-do-db=需要复制的主数据库名字
#设置logbin格式
binlog_format=STATEMENT
# 在作为从数据库的时候,有写入操作也要更新二进制日志文件
log-slave-updates
#表示自增长字段每次递增的量,指自增字段的起始值,其默认值是1,取值范围是1 .. 65535
auto-increment-increment=2
# 表示自增长字段从哪个数开始,指字段一次递增多少,他的取值范围是1 .. 65535
auto-increment-offset=1

一文带你从不知道数据库中间件MyCat到实战落地_第17张图片

systemctl restart mysqld

Master2 配置,修改配置文件

vim /etc/my.cnf
#主服务器唯一ID
server-id=3
#启用二进制日志
log-bin=mysql-bin
# 设置不要复制的数据库(可设置多个)
binlog-ignore-db=mysql
binlog-ignore-db=information_schema
#设置需要复制的数据库
binlog-do-db=需要复制的主数据库名字
#设置logbin格式
binlog_format=STATEMENT
# 在作为从数据库的时候,有写入操作也要更新二进制日志文件
log-slave-updates
#表示自增长字段每次递增的量,指自增字段的起始值,其默认值是1,取值范围是1 .. 65535
auto-increment-increment=2
# 表示自增长字段从哪个数开始,指字段一次递增多少,他的取值范围是1 .. 65535
auto-increment-offset=2

一文带你从不知道数据库中间件MyCat到实战落地_第18张图片

systemctl restart mysqld

在双主机MySQL里执行授权命令

mysql -uroot -p123456
set global validate_password.policy = "LOW";

create user 'account'@'%' identified by 'ABC123456';

grant all privileges on *.* to 'account'@'%';

FLUSH PRIVILEGES;
stop slave;

reset master;

查询Master1的状态

show master status;

一文带你从不知道数据库中间件MyCat到实战落地_第19张图片

配置主机1,先把配置写好,等下要用

CHANGE MASTER TO MASTER_HOST='192.168.88.139',
MASTER_USER='account',
MASTER_PASSWORD='ABC123456',
MASTER_LOG_FILE='mysql-bin.000001',MASTER_LOG_POS=156;

查询Master2的状态

show master status;

一文带你从不知道数据库中间件MyCat到实战落地_第20张图片

配置主机2,先把配置写好,等下要用

CHANGE MASTER TO MASTER_HOST='192.168.88.140',
MASTER_USER='account',
MASTER_PASSWORD='ABC123456',
MASTER_LOG_FILE='mysql-bin.000001',MASTER_LOG_POS=156;

双从机配置

Slave1 配置,修改配置文件

vim /etc/my.cnf
#从服务器唯一ID
server-id=2
#启用中继日志
relay-log=mysql-relay

一文带你从不知道数据库中间件MyCat到实战落地_第21张图片

systemctl restart mysqld

Slave2 配置,修改配置文件

vim /etc/my.cnf
#从服务器唯一ID
server-id=4
#启用中继日志
relay-log=mysql-relay

一文带你从不知道数据库中间件MyCat到实战落地_第22张图片

systemctl restart mysqld

在从机上配置需要复制的主机,Slava1 复制 Master1,Slava2 复制 Master2,还记在我在主机说的等下要用的配置吗?,在两个从机上面执行以下命令

stop slave;

reset master;

从机1 复制 主机1

一文带你从不知道数据库中间件MyCat到实战落地_第23张图片

执行完之后,我们启动状态

start slave;

查看以下状态

show slave status\G;

11

从机2 复制 主机2

一文带你从不知道数据库中间件MyCat到实战落地_第24张图片

执行完之后,我们启动状态

start slave;

查看以下状态

show slave status\G;

一文带你从不知道数据库中间件MyCat到实战落地_第25张图片

双主互备配置

Master2 复制 Master1,Master1 复制 Master2

主机1 复制 主机2

启动两台主服务器复制功能,就像是从机复制主机一样,把配置拿过来即可

一文带你从不知道数据库中间件MyCat到实战落地_第26张图片

start slave;

查看从服务器状态

show slave status\G;

一文带你从不知道数据库中间件MyCat到实战落地_第27张图片

主机1 复制 主机2

一文带你从不知道数据库中间件MyCat到实战落地_第28张图片

start slave;

查看从服务器状态

show slave status\G;

一文带你从不知道数据库中间件MyCat到实战落地_第29张图片

测试

主机进行新建数据库

create DATABASE testdb;

在主机进行添加表

CREATE TABLE `mytbl` (
  `id` int NOT NULL,
  `name` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

新增数据

insert into mytbl(id,name) values (1,"白色");
insert into mytbl(id,name) values (2,"黑色");

然后在看一下从机是不是也有了

配置Mycat的双主双从读写分离

修改Mycat的配置文件 schema.xml

vim /usr/local/mycat/conf/schema.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" dataNode="dn1"></schema>
    <dataNode name="dn1" dataHost="host1" database="testdb" />

    <dataHost name="host1" maxCon="1000" minCon="10" balance="1" writeType="0" dbType="mysql" dbDriver="jdbc" switchType="1" slaveThreshold="100">
        <heartbeat>select user()</heartbeat>

        <writeHost host="hostM1" url="jdbc:mysql://192.168.88.139:3306/testdb?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8" user="root" password="123456">
            <readHost host="hostS1" url="jdbc:mysql://192.168.88.138:3306/testdb?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8" user="root" password="123456" />
        </writeHost>


        <writeHost host="hostM2" url="jdbc:mysql://192.168.88.140:3306/testdb?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8" user="root" password="123456">
            <readHost host="hostS2" url="jdbc:mysql://192.168.88.141:3306/testdb?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8" user="root" password="123456" />
        </writeHost>

    </dataHost>

</mycat:schema>

配置小解释

  • balance=“1”: 全部的readHost与stand by writeHost参与select语句的负载均衡。
  • writeType=“0”: 所有写操作发送到配置的第一个writeHost,第一个挂了切到还生存的第二个
  • writeType=“1”,所有写操作都随机的发送到配置的 writeHost,1.5 以后废弃不推荐
  • writeHost,重新启动后以切换后的为准,切换记录在配置文件中:dnindex.properties 。
  • switchType=“1”: 1 默认值,自动切换。
    • -1 表示不自动切换
    • 2 基于 MySQL 主从同步的状态决定是否切换

启动 MyCat

cd /usr/local/mycat/bin
./mycat console

验证读写分离,在写主机Master1数据库表mytbl中插入带系统变量数据,造成主从数据不一致,然后再去各个数据看一下数据即可

INSERT INTO mytbl VALUES(3,@@hostname);

去mycat服务器看一下是不是数据在变来变去了,多刷新几次?

垂直拆分—分库

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

一文带你从不知道数据库中间件MyCat到实战落地_第30张图片
系统被切分成了,用户,订单交易,支付几个模块。

如何划分表

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

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

客户表 rows:20万

CREATE TABLE customer(
 id INT AUTO_INCREMENT,
 NAME VARCHAR(200),
 PRIMARY KEY(id)
);

订单表 rows:600万

CREATE TABLE orders(
 id INT AUTO_INCREMENT,
 order_type INT,
 customer_id INT,
 amount DECIMAL(10,2),
 PRIMARY KEY(id) 
 );

订单详细表 rows:600万

CREATE TABLE orders_detail(
 id INT AUTO_INCREMENT,
 detail VARCHAR(2000),
 order_id INT,
 PRIMARY KEY(id)
);

订单状态字典表 rows:20

CREATE TABLE dict_order_type(
 id INT AUTO_INCREMENT,
 order_type VARCHAR(200),
 PRIMARY KEY(id)
);

以上四个表如何分库?客户表分在一个数据库,另外三张都需要关联查询,分在另外一个数据库。

实现分库

修改 schema 配置文件

vim /usr/local/mycat/conf/schema.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" dataNode="dn1">
        
        <table name="customer" dataNode="dn2"></table>
    
     </schema>
    
    <dataNode name="dn1" dataHost="host1" database="orders" />

    <dataNode name="dn2" dataHost="host2" database="orders" />



    <dataHost name="host1" 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.88.139:3306/testdb?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8" user="root" password="123456"></writeHost>

    </dataHost>

    <dataHost name="host2" 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.88.138:3306/testdb?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8" user="root" password="123456"></writeHost>

    </dataHost>

</mycat:schema>

分库操作不是在原来的老数据库上进行操作,需要准备两台机器分别安装新的数据库,我还是用之前的数据库,所以我要对我的数据进行一个停止主从的配置,两个都要执行命令

stop slave;

reset master;

一文带你从不知道数据库中间件MyCat到实战落地_第31张图片
一文带你从不知道数据库中间件MyCat到实战落地_第32张图片

创建好了之后。启动 Mycat

./mycat console

登录mycat

mysql -umycat -p123456 -h 192.168.88.137 -P 8066

创建四个表,这些创表语句是在上面有的

一文带你从不知道数据库中间件MyCat到实战落地_第33张图片

查看两个MySQL数据库,查看表信息,可以看到成功分库

一文带你从不知道数据库中间件MyCat到实战落地_第34张图片

水平拆分—分表

相对于垂直拆分,水平拆分不是将表做分类,而是按照某个字段的某种规则来分散到多个库之中,每个表中 包含一部分数据。简单来说,我们可以将数据的水平切分理解为是按照数据行的切分,就是将表中的某些行切分 到一个数据库,而另外的某些行又切分到其他的数据库中,如图

一文带你从不知道数据库中间件MyCat到实战落地_第35张图片

实现分表

  1. 选择要拆分的表
    MySQL 单表存储数据条数是有瓶颈的,单表达到 1000 万条数据就达到了瓶颈,会影响查询效率,需要进行水平拆分(分表)进行优化。
    例如:例子中的 orders、orders_detail 都已经达到 600 万行数据,需要进行分表优化。

  2. 分表字段
    以 orders 表为例,可以根据不同自字段进行分表

编号 分表字段 效果
1 id(主键、或创建时间) 查询订单注重时效,历史订单被查询的次数少,如此分片会造成一个节点访问多,一个访问少,不平均。
2 customer_id(客户 id) 根据客户 id 去分,两个节点访问平均,一个客户的所 有订单都在同一个节点

修改配置文件schema.xml

为 orders 表设置数据节点为 dn1、dn2,并指定分片规则为 mod_rule(自定义的名字)如下图:

vim /usr/local/mycat/conf/schema.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" dataNode="dn1">
        
        <table name="customer" dataNode="dn2"></table>
        <table name="orders" dataNode="dn1,dn2" rule="mod_rule" ></table>
    
     </schema>
    
    <dataNode name="dn1" dataHost="host1" database="orders" />

    <dataNode name="dn2" dataHost="host2" database="orders" />

    <dataHost name="host1" 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.88.139:3306/testdb?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8" user="root" password="123456"></writeHost>

    </dataHost>

    <dataHost name="host2" 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.88.138:3306/testdb?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8" user="root" password="123456"></writeHost>

    </dataHost>

</mycat:schema>

修改配置文件rule.xml

在 rule 配置文件里新增分片规则 mod_rule,并指定规则适用字段为 customer_id,
还有选择分片算法 mod-long(对字段求模运算),customer_id 对两个节点求模,根据结果分片
配置算法 mod-long 参数 count 为 2,两个节点

vim /usr/local/mycat/conf/rule.xml
<tableRule name="mod_rule">
	<rule>
		<columns>customer_id</columns>
		<algorithm>mod-long</algorithm>
	</rule>
 </tableRule>

一文带你从不知道数据库中间件MyCat到实战落地_第36张图片

<function name="mod-long" class="io.mycat.route.function.PartitionByMod">
	 <!-- how many data nodes -->
	 <property name="count">2</property>
 </function>

一文带你从不知道数据库中间件MyCat到实战落地_第37张图片

创建表,我用之前的数据库,但是其中有一个数据库没有 orders表所以我要创建一个表

CREATE TABLE orders(
 id INT AUTO_INCREMENT,
 order_type INT,
 customer_id INT,
 amount DECIMAL(10,2),
 PRIMARY KEY(id) 
 );

创建好了之后,启动mycat

./mycat console

访问 Mycat 实现分片

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到实战落地_第38张图片
一文带你从不知道数据库中间件MyCat到实战落地_第39张图片
一文带你从不知道数据库中间件MyCat到实战落地_第40张图片

在mycat、dn1、dn2中查看orders表数据,分表成功,所以查询顺序不一样?请看下文图解

Mycat 的分片 “join”

Orders 订单表已经进行分表操作了,和它关联的 orders_detail 订单详情表如何进行 join 查询,我们要对 orders_detail 也要进行分片操作。Join 的原理如下图:

一文带你从不知道数据库中间件MyCat到实战落地_第41张图片

ER 表

Mycat 借鉴了 NewSQL 领域的新秀 Foundation DB 的设计思路,Foundation DB 创新性的提出了 Table Group 的概念,其将子表的存储位置依赖于主表,并且物理上紧邻存放,因此彻底解决了JION 的效率和性能问 题,根据这一思路,提出了基于 E-R 关系的数据分片策略,子表的记录与所关联的父表记录存放在同一个数据分片上。
修改 schema.xml 配置文件

vim /usr/local/mycat/conf/schema.xml 
<table name="orders" dataNode="dn1,dn2" rule="mod_rule">
	 <childTable name="orders_detail" primaryKey="id" joinKey="order_id" parentKey="id" />
</table>

一文带你从不知道数据库中间件MyCat到实战落地_第42张图片

创建表,我用之前的数据库,但是其中有一个数据库没有 orders_detail 表所以我要创建一个表

CREATE TABLE orders_detail(
	 id INT AUTO_INCREMENT,
	 detail VARCHAR(2000),
	 order_id INT,
	 PRIMARY KEY(id)
);
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);

在mycat、192.168.88.138、192.168.88.139中运行两个表join语句

select o.*,od.detail from orders o inner join orders_detail od on o.id=od.order_id;

全局表

在分片的情况下,当业务表因为规模而进行分片以后,业务表与这些附属的字典表之间的关联,就成了比较 棘手的问题,考虑到字典表具有以下几个特性:
① 变动不频繁
② 数据量总体变化不大
③ 数据规模不大,很少有超过数十万条记录

鉴于此,Mycat 定义了一种特殊的表,称之为“全局表”,全局表具有以下特性:
① 全局表的插入、更新操作会实时在所有节点上执行,保持各个分片的数据一致性
② 全局表的查询操作,只从一个节点获取
③ 全局表可以跟任何一个表进行 JOIN 操作
将字典表或者符合字典表特性的一些表定义为全局表,则从另外一个方面,很好的解决了数据JOIN 的难题。通过全局表+基于 E-R 关系的分片策略,Mycat 可以满足 80%以上的企业应用开发

修改 schema.xml 配置文件

<table name="dict_order_type" dataNode="dn1,dn2" type="global" ></table>

一文带你从不知道数据库中间件MyCat到实战落地_第43张图片

我用之前的数据库,但是其中有一个数据库没有 dict_order_type 表所以我要创建一个表

CREATE TABLE dict_order_type(
 id INT AUTO_INCREMENT,
 order_type VARCHAR(200),
 PRIMARY KEY(id)
);

启动并且访问 Mycat 向 dict_order_type 表插入数据

INSERT INTO dict_order_type(id,order_type) VALUES(101,'type1');
INSERT INTO dict_order_type(id,order_type) VALUES(102,'type2');

常用分片规则

1,取模

此规则为对分片字段求摸运算。也是水平分表最常用规则。5.1 配置分表中,orders 表采用了此规则。

2,分片枚举

通过在配置文件中配置可能的枚举 id,自己配置分片,本规则适用于特定的场景,比如有些业务需要按照省份或区县来做保存,而全国省份区县固定的,这类业务使用本条规则。

修改schema.xml配置文件

<table name="orders_ware_info" dataNode="dn1,dn2" rule="sharding_by_intfile" ></table>

一文带你从不知道数据库中间件MyCat到实战落地_第44张图片

修改rule.xml配置文件

<tableRule name="sharding_by_intfile">
	 <rule>
		 <columns>areacode</columns>
		 <algorithm>hash-int</algorithm>
	 </rule>
 </tableRule>

一文带你从不知道数据库中间件MyCat到实战落地_第45张图片

<function name="hash-int"  class="io.mycat.route.function.PartitionByFileMap">
	 <property name="mapFile">partition-hash-int.txt</property>
	 <property name="type">1</property>
	 <property name="defaultNode">0</property>
 </function>

一文带你从不知道数据库中间件MyCat到实战落地_第46张图片

  • columns:分片字段,algorithm:分片函数
  • mapFile:标识配置文件名称,type:0为int型、非0为String,
  • defaultNode:默认节点:小于 0 表示不设置默认节点,大于等于 0 表示设置默认节点,设置默认节点如果碰到不识别的枚举值,就让它路由到默认节点,如不设置不识别就报错

修改partition-hash-int.txt配置文件


110=0
120=1

一文带你从不知道数据库中间件MyCat到实战落地_第47张图片

重启 Mycat,访问Mycat创建表,订单归属区域信息表

CREATE TABLE orders_ware_info(
 	`id` INT AUTO_INCREMENT comment '编号',
 	`order_id` INT comment '订单编号',
 	`address` VARCHAR(200) comment '地址',
	`areacode` VARCHAR(20) comment '区域编号',
	PRIMARY KEY(id)
);

插入数据

INSERT INTO orders_ware_info(id, order_id,address,areacode) VALUES (1,1,'北京','110');
INSERT INTO orders_ware_info(id, order_id,address,areacode) VALUES (2,2,'天津','120');

一文带你从不知道数据库中间件MyCat到实战落地_第48张图片

查询Mycat、192.168.88.139、192.168.88.138 可以看到数据分片效果

一文带你从不知道数据库中间件MyCat到实战落地_第49张图片

在这里插入图片描述
一文带你从不知道数据库中间件MyCat到实战落地_第50张图片

3,范围约定

此分片适用于,提前规划好分片字段某个范围属于哪个分片
修改schema.xml配置文件

vim /usr/local/mycat/conf/schema.xml
<table name="payment_info" dataNode="dn1,dn2" rule="auto_sharding_long" ></table>

一文带你从不知道数据库中间件MyCat到实战落地_第51张图片

修改rule.xml配置文件

vim /usr/local/mycat/conf/rule.xml
<tableRule name="auto_sharding_long">
	<rule>
		<columns>order_id</columns>
		<algorithm>rang-long</algorithm>
	</rule>
</tableRule>

一文带你从不知道数据库中间件MyCat到实战落地_第52张图片

<function name="rang-long" class="io.mycat.route.function.AutoPartitionByLong">
	<property name="mapFile">autopartition-long.txt</property>
	<property name="defaultNode">0</property>
</function>

一文带你从不知道数据库中间件MyCat到实战落地_第53张图片

  • columns:分片字段,
  • algorithm:分片函数
  • mapFile:标识配置文件名称
  • defaultNode:默认节点:小于 0 表示不设置默认节点,大于等于 0 表示设置默认节点,设置默认节点如果碰到不识别的枚举值,就让它路由到默认节点,如不设置不识别就报错

修改autopartition-long.txt配置文件

vim /usr/local/mycat/conf/autopartition-long.txt
0-102=0
103-200=1

在这里插入图片描述

重启 Mycat,访问Mycat创建表,#支付信息表

CREATE TABLE payment_info(
	`id` INT AUTO_INCREMENT comment '编号',
	`order_id` INT comment '订单编号',
	`payment_status` INT comment '支付状态',
	PRIMARY KEY(id)
);
INSERT INTO payment_info (id,order_id,payment_status) VALUES (1,101,0);
INSERT INTO payment_info (id,order_id,payment_status) VALUES (2,102,1);
INSERT INTO payment_info (id,order_id ,payment_status) VALUES (3,103,0);
INSERT INTO payment_info (id,order_id,payment_status) VALUES (4,104,1);

查询Mycat、192.168.88.139、192.168.88.138 可以看到数据分片效果

一文带你从不知道数据库中间件MyCat到实战落地_第54张图片
一文带你从不知道数据库中间件MyCat到实战落地_第55张图片
一文带你从不知道数据库中间件MyCat到实战落地_第56张图片

4, 按日期(天)分片

此规则为按天分片。设定时间格式、范围
修改schema.xml配置文件

vim /usr/local/mycat/conf/schema.xml
<table name="login_info" dataNode="dn1,dn2" rule="sharding_by_date" ></table>

一文带你从不知道数据库中间件MyCat到实战落地_第57张图片

修改rule.xml配置文件

vim /usr/local/mycat/conf/rule.xml
<tableRule name="sharding_by_date">
	<rule>
		<columns>login_date</columns>
		<algorithm>shardingByDate</algorithm>
	</rule>
</tableRule>

一文带你从不知道数据库中间件MyCat到实战落地_第58张图片

<function name="shardingByDate" class="io.mycat.route.function.PartitionByDate">
	<property name="dateFormat">yyyy-MM-dd</property>
	<property name="sBeginDate">2019-01-01</property>
	<property name="sEndDate">2019-01-04</property>
	<property name="sPartionDay">2</property>
</function>

一文带你从不知道数据库中间件MyCat到实战落地_第59张图片

  • columns:分片字段,algorithm:分片函数
  • dateFormat :日期格式
  • sBeginDate :开始日期
  • sEndDate:结束日期,则代表数据达到了这个日期的分片后循环从开始分片插入
  • sPartionDay :分区天数,即默认从开始日期算起,分隔 2 天一个分区

重启 Mycat,访问Mycat创建表,用户信息表

CREATE TABLE login_info(
	`id` INT AUTO_INCREMENT comment '编号',
	`user_id` INT comment '用户编号',
	`login_date` date comment '登录日期',
	PRIMARY KEY(id)
);
INSERT INTO login_info(id,user_id,login_date) VALUES (1,101,'2019-01-01');
INSERT INTO login_info(id,user_id,login_date) VALUES (2,102,'2019-01-02');
INSERT INTO login_info(id,user_id,login_date) VALUES (3,103,'2019-01-03');
INSERT INTO login_info(id,user_id,login_date) VALUES (4,104,'2019-01-04');
INSERT INTO login_info(id,user_id,login_date) VALUES (5,103,'2019-01-05');
INSERT INTO login_info(id,user_id,login_date) VALUES (6,104,'2019-01-06');

查询Mycat、192.168.88.139、192.168.88.138 可以看到数据分片效果

一文带你从不知道数据库中间件MyCat到实战落地_第60张图片

一文带你从不知道数据库中间件MyCat到实战落地_第61张图片

一文带你从不知道数据库中间件MyCat到实战落地_第62张图片
一文带你从不知道数据库中间件MyCat到实战落地_第63张图片

全局序列

在实现分库分表的情况下,数据库自增主键已无法保证自增主键的全局唯一。为此,Mycat 提供了全局 sequence,并且提供了包含本地配置和数据库配置等多种实现方式

1, 本地文件

此方式 Mycat 将 sequence 配置到文件中,当使用到 sequence 中的配置后,Mycat 会更下classpath 中的 sequence_conf.properties 文件中 sequence 当前的值。
① 优点:本地加载,读取速度较快
② 缺点:抗风险能力差,Mycat 所在主机宕机后,无法读取本地文件

2, 数据库方式

利用数据库一个表 来进行计数累加。但是并不是每次生成序列都读写数据库,这样效率太低。
Mycat 会预加载一部分号段到 Mycat 的内存中,这样大部分读写序列都是在内存中完成的。
如果内存中的号段用完了 Mycat 会再向数据库要一次。

问:那如果 Mycat 崩溃了 ,那内存中的序列岂不是都没了?
是的。如果是这样,那么 Mycat 启动后会向数据库申请新的号段,原有号段会弃用。
也就是说如果 Mycat 重启,那么损失是当前的号段没用完的号码,但是不会因此出现主键重复

建库序列脚本,在 192.168.88.139 上创建全局序列表

CREATE TABLE MYCAT_SEQUENCE (
	NAME VARCHAR ( 50 ) NOT NULL,
	current_value INT NOT NULL,
	increment INT NOT NULL DEFAULT 100,
	PRIMARY KEY ( NAME )
) ENGINE = INNODB;

一文带你从不知道数据库中间件MyCat到实战落地_第64张图片

创建全局序列所需函数

DELIMITER $$
CREATE FUNCTION mycat_seq_currval (
	seq_name VARCHAR ( 50 )) RETURNS VARCHAR ( 64 ) DETERMINISTIC BEGIN
	DECLARE
		retval VARCHAR ( 64 );
	
	SET retval = "-999999999,null";
	SELECT
		CONCAT(
			CAST( current_value AS CHAR ),
			",",
		CAST( increment AS CHAR )) INTO retval 
	FROM
		MYCAT_SEQUENCE 
	WHERE
		NAME = seq_name;
	RETURN retval;
	
END $$DELIMITER;

DELIMITER $$
CREATE FUNCTION mycat_seq_setval ( seq_name VARCHAR ( 50 ), VALUE INTEGER ) RETURNS VARCHAR ( 64 ) DETERMINISTIC BEGIN
	UPDATE MYCAT_SEQUENCE 
	SET current_value = 
	VALUE
		
	WHERE
		NAME = seq_name;
	RETURN mycat_seq_currval ( seq_name );
	
END $$DELIMITER;

DELIMITER $$
CREATE FUNCTION mycat_seq_nextval (
	seq_name VARCHAR ( 50 )) RETURNS VARCHAR ( 64 ) DETERMINISTIC BEGIN
	UPDATE MYCAT_SEQUENCE 
	SET current_value = current_value + increment 
	WHERE
		NAME = seq_name;
	RETURN mycat_seq_currval ( seq_name );

END $$DELIMITER;

一文带你从不知道数据库中间件MyCat到实战落地_第65张图片

初始化序列表记录

INSERT INTO MYCAT_SEQUENCE(NAME,current_value,increment) VALUES ('ORDERS', 400000,100);

一文带你从不知道数据库中间件MyCat到实战落地_第66张图片
一文带你从不知道数据库中间件MyCat到实战落地_第67张图片

修改 Mycat 配置,修改sequence_db_conf.properties

vim /usr/local/mycat/conf/sequence_db_conf.properties

意思是 ORDERS这个序列在dn1这个节点上,具体dn1节点是哪台机子,请参考schema.xml

一文带你从不知道数据库中间件MyCat到实战落地_第68张图片

修改server.xml

vim /usr/local/mycat/conf/server.xml

全局序列类型:0-本地文件,1-数据库方式,2-时间戳方式。此处应该修改成1。

一文带你从不知道数据库中间件MyCat到实战落地_第69张图片

重启Mycat,验证全局序列,登录 Mycat,插入数据

一文带你从不知道数据库中间件MyCat到实战落地_第70张图片

3, 时间戳方式

全局序列ID= 64 位二进制 (42(毫秒)+5(机器 ID)+5(业务编码)+12(重复累加) 换算成十进制为 18 位数的long 类型,每毫秒可以并发 12 位二进制的累加。
① 优点:配置简单
② 缺点:18 位 ID 过长

4, 自主生成全局序列

可在 java 项目里自己生成全局序列,如下:
① 根据业务逻辑组合
② 可以利用 redis 的单线程原子性 incr 来生成序列但,自主生成需要单独在工程中用 java 代码实现,还是推荐使用 Mycat 自带全局序列。

基于HA机制的Mycat高可用

在实际项目中,Mycat 服务也需要考虑高可用性,如果 Mycat 所在服务器出现宕机,或 Mycat 服务故障,需要有备机提供服务,需要考虑 Mycat 集群。

高可用方案

我们可以使用 HAProxy + Keepalived 配合两台 Mycat 搭起 Mycat 集群,实现高可用性。HAProxy实现了 MyCat 多节点的集群高可用和负载均衡,而 HAProxy 自身的高可用则可以通过 Keepalived 来实现。

一文带你从不知道数据库中间件MyCat到实战落地_第71张图片

编号 角色 IP 地址 机器名
1 Mycat1 192.168.88.137 Mycat1
2 Mycat2 192.168.88.142 Mycat2
3 HAProxy(master) 192.168.88.138 HAProxy(master)
4 Keepalived(master) 192.168.88.139 Keepalived(master)
5 HAProxy(backup) 192.168.88.140 HAProxy(backup)
6 Keepalived(backup) 192.168.88.141 Keepalived(backup)

安装配置 HAProxy

yum install -y haproxy

创建目录、配置文件

mkdir -p /home/haproxy/data
mkdir -p /home/haproxy/conf

cd /home/haproxy/conf

编辑文件

vim /home/haproxy/conf/haproxy.conf
global
    log         127.0.0.1 local0
    chroot      /var/lib/haproxy
    pidfile     /home/haproxy/data/haproxy.pid
    maxconn     4000
    uid         99
    gid         99
    daemon
    stats socket /var/lib/haproxy/stats

defaults
    mode                    tcp
    log                     global
    option                  redispatch
    retries                 3
    timeout queue           1m
    timeout connect         10s
    timeout client          1m
    timeout server          1m
    maxconn                 3000

listen proxy_status
    bind :48066
        mode        tcp
        balance     roundrobin
        # 这里注意了,看清楚这个配置
        server      mycat_1 192.168.88.137:8066 check inter 10s
        server      mycat_2 192.168.88.142:8066 check inter 10s


frontend  admin_stats
    bind :7777
        mode        http
        stats       enable
        option      httplog
        maxconn     10
        stats       refresh 30s
        stats       uri /admin
        stats       auth admin:123123
        stats       hide-version
        stats       admin if TRUE

启动 haproxy

/usr/sbin/haproxy -f /home/haproxy/conf/haproxy.conf

一文带你从不知道数据库中间件MyCat到实战落地_第72张图片

一文带你从不知道数据库中间件MyCat到实战落地_第73张图片

192.168.88.140还没有安装这个,就和这个一样的安装方法

安装配置 Keepalived

进入文件夹,并且下载(https://www.keepalived.org/download.html)

cd /home

wget https://www.keepalived.org/software/keepalived-2.1.5.tar.gz

进入解压目录

tar -zxvf keepalived-2.1.5.tar.gz

cd keepalived-2.1.5

设置安装目录

yum -y install gcc openssl-devel popt-devel

mkdir /home/keepalived/

./configure --prefix=/home/keepalived/

make && make install

运行前配置

mkdir -p /etc/keepalived/

cp /home/keepalived/etc/keepalived/keepalived.conf  /etc/keepalived/

cp /home/keepalived-2.1.5/keepalived/etc/init.d/keepalived /etc/init.d

cp /home/keepalived-2.1.5/keepalived/etc/sysconfig/keepalived /etc/sysconfig/

cp /home/keepalived/sbin/keepalived /usr/sbin/

修改配置文件

vim /etc/keepalived/keepalived.conf
! Configuration File for keepalived

global_defs {
   notification_email {
     [email protected]
   }
   notification_email_from [email protected]
   smtp_server localhsot
   smtp_connect_timeout 30
   router_id LVS_DEVEL
   vrrp_skip_check_adv_addr
   vrrp_strict
   vrrp_garp_interval 0
   vrrp_gna_interval 0
}

vrrp_instance VI_1 {
	# 主机配置 master
    state MASTER
    interface ens33
    virtual_router_id 51
    # 数值越大 优先级越高
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    # 虚拟 ip [ 同网段 ip ]
    virtual_ipaddress {
        192.168.88.200
    }
}

virtual_server 192.168.88.200 48066 {
    delay_loop 6
    lb_algo rr
    lb_kind NAT
    persistence_timeout 50
    protocol TCP

    real_server 192.168.88.138 48066 {
        weight 1
        TCP_CHECK {
        	connect_timeout 3
        	retry 3
        	delay_before_retry 3
        }
    }

    real_server 192.168.88.139 48066 {
        weight 1
        TCP_CHECK {
        	connect_timeout 3
        	retry 3
        	delay_before_retry 3
        }
    }
}

启动Keepalived

service keepalived start

登录验证

mysql -umycat -p123456 -h 192.168.88.200 -P 48066

相同步骤安装 Keepalived 在 192.168.88.141 上 配置文件中 MASTER 改为 BACKUP

总结:其实就是套娃奥,在配置mycat的时候也是在套娃配置套配置,mycat 保证 mysql 集群高可,haproxy 保证 mycat 高可用,keepalived 保证 haproxy高效可用,当然其实这些都应该分配在不同的节点上奥,我就两台机器,那肯定都放两台上了奥

Mycat 安全设置

权限配置

1、 user 标签权限控制

目前 Mycat 对于中间件的连接控制并没有做太复杂的控制,目前只做了中间件逻辑库级别的读写权限控制。是通过 server.xml 的 user 标签进行配置。

server.xml配置文件user部分

<user name="mycat">
	 <property name="password">123456</property>
	 <property name="schemas">TESTDB</property>
</user>
<user name="user">
	 <property name="password">user</property>
	 <property name="schemas">TESTDB</property>
	 <property name="readOnly">true</property>
</user>

一文带你从不知道数据库中间件MyCat到实战落地_第74张图片

配置说明

标签属性 说明
name 应用连接中间件逻辑库的用户名
password 该用户对应的密码
TESTDB 应用当前连接的逻辑库中所对应的逻辑表。schemas 中可以配置一个或多个
readOnly 应用连接中间件逻辑库所具有的权限。true 为只读,false 为读写都有,默认为 false

2、 privileges 标签权限控制

在 user 标签下的 privileges 标签可以对逻辑库(schema)、表(table)进行精细化的 DML 权限控制。

privileges 标签下的 check 属性,如为 true 开启权限检查,为 false 不开启,默认为 false。

由于 Mycat 一个用户的 schemas 属性可配置多个逻辑库(schema) ,所以 privileges 的下节点 schema 节点同样可配置多个,对多库多表进行细粒度的 DML 权限控制。

server.xml配置文件privileges部分,配置orders表没有增删改查权限

<user name="mycat">
	 <property name="password">123456</property>
	 <property name="schemas">TESTDB</property>
	 <!-- 表级 DML 权限设置 -->
	<privileges check="true">
		<schema name="TESTDB" dml="1111" >
			<table name="orders" dml="0000"></table>
			<!--<table name="tb02" dml="1111"></table>-->
		</schema>
	</privileges>
</user>

一文带你从不知道数据库中间件MyCat到实战落地_第75张图片

DML 权限 增加(insert) 更新(update) 查询(select) 删除(select)
0000 禁止 禁止 禁止 禁止
0010 禁止 禁止 可以 禁止
1110 可以 禁止 禁止 禁止
1111 可以 可以 可以 可以

SQL 拦截

firewall 标签用来定义防火墙;firewall 下 whitehost 标签用来定义 IP 白名单 ,blacklist 用来定义SQL 黑名单

1、 白名单

可以通过设置白名单,实现某主机某用户可以访问 Mycat,而其他主机用户禁止访问

server.xml配置文件firewall标签,配置只有192.168.140.128主机可以通过mycat用户访问

vim /usr/local/mycat/conf/server.xml
<firewall>
	 <whitehost>
		 <host host="192.168.140.128" user="mycat"/>
	 </whitehost>
</firewall>

一文带你从不知道数据库中间件MyCat到实战落地_第76张图片

2、 黑名单

可以通过设置黑名单,实现 Mycat 对具体 SQL 操作的拦截,如增删改查等操作的拦截。

server.xml配置文件firewall标签,配置禁止mycat用户进行删除操作

<firewall>
	 <whitehost>
		 <host host="192.168.140.128" user="mycat"/>
	 </whitehost>
	 <blacklist check="true">
		 <property name="deleteAllow">false</property>
	</blacklist>
</firewall>

一文带你从不知道数据库中间件MyCat到实战落地_第77张图片

重启Mycat后,192.168.140.128主机使用mycat用户访问

切换TESTDB数据库后,执行删除数据语句,delete from orders where id=7;
运行后发现已禁止删除数据

配置项 缺省值 描述
selelctAllow true 是否允许执行 SELECT 语句
deleteAllow true 是否允许执行 DELETE 语句
updateAllow true 是否允许执行 UPDATE 语句
insertAllow true 是否允许执行 INSERT 语句
createTableAllow true 是否允许创建表
setAllow true 是否允许使用 SET 语法
alterTableAllow true 是否允许执行 Alter Table 语句
dropTableAllow true 是否允许修改表
commitAllow true 是否允许执行 commit 操作
rollbackAllow true 是否允许执行 roll back 操作

Mycat 监控工具

Mycat-web 简介

Mycat-web 是 Mycat 可视化运维的管理和监控平台,弥补了 Mycat 在监控上的空白。帮 Mycat 分担统计任务和配置管理任务。Mycat-web 引入了 ZooKeeper 作为配置中心,可以管理多个节点。

Mycat-web 主要管理和监控 Mycat 的流量、连接、活动线程和内存等,具备 IP 白名单、邮件告警等模块,还可以统计 SQL 并分析慢 SQL 和高频 SQL 等。为优化 SQL 提供依据。

一文带你从不知道数据库中间件MyCat到实战落地_第78张图片

下载zookeeper

进入文件夹,并且下载,解压

cd /home

wget https://archive.apache.org/dist/zookeeper/zookeeper-3.4.11/zookeeper-3.4.11.tar.gz

tar -zxvf zookeeper-3.4.11.tar.gz

进入ZooKeeper解压后的配置目录(conf),复制配置文件并改名

cd /home/zookeeper-3.4.11/conf

cp zoo_sample.cfg zoo.cfg

进入ZooKeeper的命令目录(bin),运行启动命令

cd /home/zookeeper-3.4.11/bin

./zkServer.sh start

在这里插入图片描述

ZooKeeper服务端口为2181,查看服务已经启动

一文带你从不知道数据库中间件MyCat到实战落地_第79张图片

ps -ef | grep 2181

Mycat-web 配置使用

在这里插入图片描述

tar -zxvf Mycat-web-1.0-SNAPSHOT-20170102153329-linux.tar.gz

进入文件夹

cd /home/mycat-web/

启动

./start.sh &

Mycat-web服务端口为8082,查看服务已经启动

ps -ef | grep 8082

通过地址访问服务

http://192.168.88.137:8082/mycat

一文带你从不知道数据库中间件MyCat到实战落地_第80张图片

你可能感兴趣的:(Mycat,数据库,中间件,java,mysql)