4
2
0
2

Mycat2

一、MyCat概述

Mycat是数据库中间件,连接java应用程序和数据库。

Java程序与数据库紧密关联耦合严重,高访问量高并发对数据库的压力巨大,因此可以引入数据库中间件MyCat解决。

1.1 特性

image

1.2 核心功能

1. 读写分离

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

2. 数据分片

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

3. 多数据源整合

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

1.3原理

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

二、Mycat2相关概念

2.1 核心概念

具体参考:MyCat2官网文档

1. 分库分表

按照一定规则把数据库中的表拆分为多个带有数据库实例,物理库,物理表访问路径的分表

分库:通常按功能模板划分,如:分为用户库、订单库等

分表:当一张数据表达到MySQL单表瓶颈时,将表数据分到多个数据库中的多张表

2.逻辑库

数据库代理中的数据库,它可以包含多个逻辑表

Mycat里定义的库,在逻辑上存在,物理上在MySQL里并不存在

一个逻辑库可能是多个MySQL数据库共同组成

3. 逻辑表

数据库代理中的表,它可以映射代理连接的数据库中的表(物理表)

Mycat里定义的表,在逻辑上存在,可以映射真实的MySQL数据库的表,可以一对一,也可以一对多。

4. 物理库

数据库代理连接的数据库中的库,比如mysql上的information_schema

MySQL真实的数据库

5. 物理表

数据库代理连接的数据库中的表,比如mysql上的information_schema.TABLES

MySQL 真实的数据库中的真实数据表

6. 分库分表中间件

实现分库分表功能的中间件,功能上相当于分库分表型数据库中的计算节点

7. 分库分表型数据库

以分库分表技术构建的数据库,在组件上一般有计算节点,存储节点.它的存储节点一般是一个可独立部署的数据库产品,比如mysql

8. 拆分键

即分片键,描述拆分逻辑表的数据规则的字段。

如:订单表可以按照归属的用户 id 拆分,用户 id 就是拆分键

9. 分区

一般指数据分区,计算节点上,水平分片表拆分数据的最小区域

10. 分区键

当使用等值查询的时候,能直接映射一个分区的拆分键

11. 系统表,元数据表

一般指mysql中的information_schema,performance_schema,mysql三个库下的表

12. 物理分表

物理分表指已经进行数据拆分的,在数据库上面的物理表,是分片表的一个分区

多个物理分表里的数据汇总就是逻辑表的全部数据

13. 物理分库

一般指包含多个物理分表的库

参与数据分片的实际数据库

14. 单库分表

在同一个数据库下同一个库表拆分成多个物理分表

15. 分库

一般指通过多个数据库拆分分片表,每个数据库一个物理分表,物理分库名字相同

每个数据库的物理分表构成完整物理表

16. 分片表,水平分片表

按照一定规则把数据拆分成多个分区的表,在分库分表语境下,它属于逻辑表的一种

17. 单表

没有分片,没有数据冗余的表

没有拆分数据,也没有复制数据到别的库的表

18. 全局表,广播表

每个数据库实例都冗余全量数据的逻辑表

它通过表数据冗余,使分片表的分区与该表的数据在同一个数据库实例里,达到join运算能够直接在该数据库实例里执行

它的数据一致一般是通过数据库代理分发SQL实现.也有基于集群日志的实现

如: 系统中定义的字典表,每个分片表都需要完整的字典数据

19. 集群

多个数据节点组成的逻辑节点.在mycat2里,它是把对多个数据源地址视为一个数据源地址(名称),并提供自动故障恢复,转移,即实现高可用,负载均衡的组件

20. 数据源

连接后端数据库的组件,它是数据库代理中连接后端数据库的客户端

Mycat 通过数据源连接 MySQL 数据库

21. schema(库)

在mycat2中配置表逻辑,视图等的配置

22. 物理视图

后端数据库中的视图

23. 逻辑视图

在mycat2中的逻辑视图是把一个查询语句视为逻辑表的功能

24. 前端会话

一般指Mycat服务器中,该会话指向连接mycat的客户端

25. 后端会话

一般指Mycat服务器中,该会话指向连接数据库的客户端

26. 后端数据库

在数据库代理中,数据库代理连接的数据库

27. 透传SQL

在数据库代理中,指从客户端接收的SQL,它不经过改动,在代理中直接发送到后端数据库

28. 透传结果集

在数据库代理中,指从后端数据库返回的结果集,不经过改动,转换,写入到前端会话

29. ER表

狭义指父子表中的子表,它的分片键指向父表的分片键,而且两表的分片算法相同广义指具有相同数据分布的一组表.

如:订单详情表就是订单表的 ER表

30. 原型库(prototype)

原型库就是存储数据的真实数据库,配置数据源时必须指定原型库

2.2 配置

详情参考:MyCat2官方文档

MyCat配置结构

mycat配置文件夹
		+ clusters
		    - prototype.cluster.json //无集群的时候自动创建
			- c0.cluster.json
                        - c1.cluster.json
        + datasources
        	- prototypeDs.datasource.json //无数据源的时候自动创建
        	- dr0.datasource.json
        	- dw0.datasource.json
        + schemas
        	- db1.schema.json
        	- mysql.schema.json
        + sequences
        	- db1_schema.sequence.json
 -server.json //服务器配置
 -state.json //mycat运行状态,包含集群选举的主节点信息,配置时间戳

1. 服务配置

目录:mycat/conf/server.json,通常默认配置即可

作用:MyCat2服务相关配置

如: server.json

{
  "loadBalance":{
    "defaultLoadBalance":"BalanceRandom",
    "loadBalances":[]
  },
  "mode":"local",
  "properties":{},
  "server":{
    "bufferPool":{

    },
    "idleTimer":{
      "initialDelay":3,
      "period":60000,
      "timeUnit":"SECONDS"
    },
    "ip":"0.0.0.0",
    "mycatId":1,
    "port":8066,
    "reactorNumber":8,
    "tempDirectory":null,
    "timeWorkerPool":{
      "corePoolSize":0,
      "keepAliveTime":1,
      "maxPendingLimit":65535,
      "maxPoolSize":2,
      "taskTimeout":5,
      "timeUnit":"MINUTES"
    },
    "workerPool":{
      "corePoolSize":1,
      "keepAliveTime":1,
      "maxPendingLimit":65535,
      "maxPoolSize":1024,
      "taskTimeout":5,
      "timeUnit":"MINUTES"
    }
  }
}

2. 用户配置

目录:mycat/conf/users/

配置规则:用户名.user.json

作用:配置用户相关信息

如:root.user.json

{
	"dialect":"mysql",# 使用语言,默认mysql
	"ip":null,# 客户端访问ip,当填写后会对客户端的ip进行限制
	"password":"123456", # 密码
	"transactionType":"proxy", # 事务类型,默认proxy
	"username":"root" # 连接中间件逻辑库的用户名
}

transactionType:事务类型

proxy:本地事务,在涉及大于1个数据库的事务,commit阶段失败会导致不一致,但是兼容性最好

xa:分布式事务,需要确认存储节点集群类型是否支持XA

语句实现切换事务类型

set transaction_policy = 'xa'

set transaction_policy = 'proxy'

语句查询事务类型

SELECT @@transaction_policy

isolation:设置初始化的事务隔离级别

READ_UNCOMMITTED:1
READ_COMMITTED:2
REPEATED_READ:3,默认
SERIALIZABLE:4

3. 数据源配置

目录: mycat/conf/datasources

配置规则:数据源名字.datasource.json

作用:配置Mycat连接的数据源信息

如:prototypeDs.datasource.json

{
        "dbType":"mysql",# 数据库类型
        "idleTimeout":60000, # 空闲连接超时时间
        "initSqls":[], # 初始化sql
        "initSqlsGetConnection":true, # 对于jdbc每次获取连接是否都执行 initSqls
        "instanceType":"READ_WRITE", # 配置实例只读还是读写,可选值:READ_WRITE,READ,WRITE
        "maxCon":1000, # 连接配置
        "maxConnectTimeout":3000, # 连接配置
        "maxRetryCount":5, # 连接配置
        "minCon":1, # 连接配置
        "name":"prototypeDs",
        "password":"123456", # 密码
        "type":"JDBC", # 数据源类型,默认 JDBC
        "url":"jdbc:mysql://IP:3306/mysql?useUnicode=true&serverTimezone=Asia/Shanghai&characterEncoding=UTF-8", # 访问数据库地址
        "user":"mycat", # 用户名
        "weight":0 # 负载均衡权重
}

4.集群配置

目录:mycat/conf/clusters

配置规则:集群名字.cluster.json

作用 :配置集群信息

如:prototype.cluster.json

{	
	"clusterType":"MASTER_SLAVE", # 集群类型
		# 可选值:SINGLE_NODE:单一节点
		# MASTER_SLAVE:普通主从
		# GARELA_CLUSTER:garela cluster/PXC 集群
		# MHA:MHA集群
		# MGR:MGR集群
	"heartbeat":{
		"heartbeatTimeout":1000,
		"maxRetry":3,
		"minSwitchTimeInterval":300,
		"slaveThreshold":0
	},
	# 配置主节点
	"masters":[
		"prototypeDs"
	],
	"maxCon":200,
	"name":"prototype",
	"readBalanceType":"BALANCE_ALL", # 负载均衡策略
		 # 可选值:
		 # BALANCE_ALL(默认值):获取集群中所有数据源、
		 # BALANCE_ALL_READ:获取集群中允许读的数据源
		 # BALANCE_READ_WRITE:获取集群中允许读写的数据源,但允许读的数据源优先
		 # BALANCE_NONE:获取集群中允许写数据源,即主节点中选择
	"switchType":"SWITCH" # 切换类型
	 	# 可选值:
		    # NOT_SWITCH:不进行主从切换
		    # SWITCH:进行主从切换
}

5.逻辑库表配置

目录:mycat/conf/schemas

配置规则:库名.schema.json

作用:配置逻辑库表,实现分库分表

如:mysql.schema.json

{
	"customTables":{},
	"globalTables":{},
	"normalTables":{
		"spm_baseline":{
			<!-- 建表SQL -->
			"createTableSQL":"CREATE TABLE mysql.spm_baseline (\n\t`id` bigint(22) NOT NULL AUTO_INCREMENT,\n\t`sql` longtext,\n\t`fix_plan_id` bigint(22) DEFAULT NULL,\n\tKEY `id` (`id`)\n) ENGINE = InnoDB CHARSET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci",
			"locality":{
				"schemaName":"mysql", // 逻辑库名
				"tableName":"spm_baseline", // 物理表
				"targetName":"prototype"  // 目的数据源或集群
			}
		}
	},
	"schemaName":"mysql",
	"shardingTables":{},
	"targetName":"prototype"
}

三、MyCat2的基本使用

3.1 安装MyCat

下载地址:http://dl.mycat.org.cn/

wget  http://dl.mycat.org.cn/2.0/install-template/mycat2-install-template-1.21.zip

下载Jar包:

wget http://dl.mycat.org.cn/2.0/1.21-release/mycat2-1.21-release-jar-with-dependencies.jar

解压mycat

unzip mycat2-install-template-1.21.zip

mycat2-1.21-release-jar-with-dependencies.jar放进解压的mycat\lib 文件夹下

mv mycat2-1.21-release-jar-with-dependencies.jar mycat/lib/

3.2 创建用户

创建用户,用于MyCat连接MySQL数据库

# 创建mycat用户
CREATE USER 'mycat2'@'%' IDENTIFIED BY '123123';
# 授权
GRANT ALL PRIVILEGES ON *.* TO 'mycat'@'%' ;
# 刷新权限
flush privileges;

配置prototype数据源:vim mycat/conf/datasources/prototypeDs.datasource.json

修改对应的mysql数据库配置,修改user、password、url等参数,如此就可以连接MyCat操作MySQL了。

{
        "dbType":"mysql",
        "idleTimeout":60000,
        "initSqls":[],
        "initSqlsGetConnection":true,
        "instanceType":"READ_WRITE",
        "maxCon":1000,
        "maxConnectTimeout":3000,
        "maxRetryCount":5,
        "minCon":1,
        "name":"prototypeDs",
        "password":"123456",
        "type":"JDBC",
        "url":"jdbc:mysql://IP:3306/mysql?useUnicode=true&serverTimezone=Asia/Shanghai&characterEncoding=UTF-8",
        "user":"mycat",
        "weight":0
}

3.3 启动MyCat

Linux环境下

cd mycat/bin

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

Windos环境下

cd mycat/bin
  
#PowerShell
./mycat install
./mycat start
./mycat status

#CMD
mycat install
mycat start
mycat status

在Linux环境下使用,报错:

-bash: ./mycat: 权限不够

修改mycatwrapper-linux-x86-64wrapper-linux-x86-32 等文件权限,否则运行启动命令时,会因权限不足而报错

chmod 777 mycat wrapper-linux-x86-64 wrapper-linux-x86-32 

image

重启MyCat

[root@mycat01 bin]# ./mycat start
Starting mycat2...
[root@mycat01 bin]# ./mycat status
mycat2 is running (2718).

3.4 测试验证

MyCat安装、配置完毕后,就可以让应用程序、客户端连接MyCat,通过Mycat操作MySQL,从而实现程序与数据库的解耦。

1.9066是MyCat管理窗口的端口,主要用于管理维护Mycat

mysql -umycat2 -p123123 -P 9066 -h IP

2.8066是MyCat数据查询的端口,主要用于通过Mycat查询数据

mysql -umycat2 -p123123 -P 8066 -h IP
mysql>  CREATE DATABASE mydb;
Query OK, 0 rows affected (0.55 sec)

mysql> use mydb;
Database changed
mysql> CREATE TABLE mytb(id INT,name VARCHAR(20));
Query OK, 0 rows affected (0.41 sec)

mysql> INSERT INTO mytb VALUES(1,'mycat');
Query OK, 1 row affected (0.07 sec)

mysql> select * from mytb;
+------+-------+
| id   | name  |
+------+-------+
|    1 | mycat |
+------+-------+
1 row in set (0.02 sec)

主库登录:mysql -uroot -h localhost -P3306 -p

mysql> use mydb;
Database changed
mysql> select * from mytb;
+------+-------+
| id   | name  |
+------+-------+
|    1 | mycat |
+------+-------+
1 row in set (0.01 sec)

四、Mycat2的安全设置

Mycat的安全配置主要是使用mycat/conf/users目录下的用户名.user.json文件进行配置

如:root.user.json

{
	"dialect":"mysql",# 使用语言,默认mysql
	"ip":null,# 客户端访问ip,当填写后会对客户端的ip进行限制
	"password":"123456", # 密码
	"transactionType":"proxy", # 事务类型,默认proxy
	"username":"root" # 连接中间件逻辑库的用户名
}

五、搭建MyCat2一主一从的MySQL读写分离

1.做好主从的MySQL中有mydb1这个库,且已经存在表和数据

2.登录主库:mysql -h localhost -P3306 -uroot -p

mysql> CREATE DATABASE mydb1;
Query OK, 1 row affected (0.00 sec)

mysql> use mydb1;
Database changed
mysql> CREATE TABLE mytb(id INT,name VARCHAR(30));
Query OK, 0 rows affected (0.02 sec)

mysql> INSERT INTO mytb1 VALUES(1,'mycat');
Query OK, 1 row affected (0.01 sec)

3.登录从库:mysql -h localhost -P3306 -uroot -p

mysql> use mydb;
Database changed
mysql> select * from mytb;
+------+---------+
| id   |  name   |
+------+---------+
|    1 |  mycat	 |
+------+---------+
1 row in set (0.00 sec)

1. 配置逻辑库

登录Mycat:mysql -uroot -p123456 -h localhost -P 8066,创建逻辑库

mysql> create database mydb;
Query OK, 1 row affected (0.00 sec)

执行create database mydb;后,将在/mycat/conf/schemas/自动生成mydb.schema.json文件

{
	"customTables":{},
	"globalTables":{},
	"normalProcedures":{},
	"normalTables":{},
	"schemaName":"mydb",
	"shardingTables":{},
	"views":{}
}
customTables:mycat默认的表的配置

globalTables:全局表的配置

shardingTables:分片表的配置

normalTables:普通表的配置

修改schema的配置,指定mydb逻辑库默认的targetName,mycat会自动加载mydb下已经有的物理表或者视图作为单表

{
	"customTables":{},
	"globalTables":{},
	"normalProcedures":{},
	"normalTables":{},
	"schemaName":"mydb",
	"targetName":"prototype"
	"shardingTables":{},
	"views":{}
}

查看修改之后的schema的配置,发现已经自动加载了相关信息到normalTables中

{
	"customTables":{},
	"globalTables":{},
	"normalProcedures":{},
	"normalTables":{
		"mytb":{
			"createTableSQL":"CREATE TABLE `mydb`.`mytb` (\n\t`id` int(11) DEFAULT NULL,\n\t`name` varchar(30) DEFAULT NULL\n) ENGINE = InnoDB CHARSET = utf8",
			"locality":{
				"schemaName":"mydb",
				"tableName":"mytb",
				"targetName":"prototype"
			}
		}
	},
	"schemaName":"mydb",
	"shardingTables":{},
	"views":{}
}

登录Mycat:mysql -uroot -p123456 -h localhost -P 8066,进行查询

mysql> use mydb;
Database changed
mysql> SELECT * FROM mytb;
+------+-------+
| id   | name  |
+------+-------+
|    1 | mycat |
+------+-------+
1 row in set (0.03 sec)

此时,架构如下:

image

2. 添加数据源

登录Mycat:mysql -uroot -p123456 -h localhost -P 8066,使用注解方式添加数据源

添加主库数据源

mysql> /*+ mycat:createDataSource{ "name":"rwSepw","url":"jdbc:mysql://192.168.200.132:3306/mydb1?useSSL=false&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true", "user":"root","password":"123456" } */;
Query OK, 0 rows affected (0.00 sec)

添加从库数据源

mysql> /*+ mycat:createDataSource{ "name":"rwSepr","url":"jdbc:mysql://192.168.200.133:3306/mydb1?useSSL=false&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true", "user":"root","password":"123456" } */;
Query OK, 0 rows affected (0.00 sec)

查询配置数据源结果

mysql> /*+ mycat:showDataSources{} */;
Query OK, 0 rows affected (0.00 sec)

image

通过注释命名添加数据源后,在对应目录会生成相关配置文件,查看数据源配置文件:mycat/conf/datasources

[root@mycat01 mycat]# ll conf/datasources/
总用量 12
-rw-r--r--. 1 root root 424 1月   5 14:59 prototypeDs.datasource.json
-rw-r--r--. 1 root root 494 1月   5 15:29 rwSepr.datasource.json
-rw-r--r--. 1 root root 494 1月   5 15:29 rwSepw.datasource.json

3. 更新集群配置

使用mycat自带的默认集群:prototype,对其修改更新即可

/*! mycat:createCluster{"name":"prototype","masters":["rwSepw"],"replicas":["rwSepr"]} */;

查看配置集群信息

/*+ mycat:showClusters{} */;

image

查看集群配置文件,发现集群配置信息已经更新

cat /usr/local/mycat/conf/clusters/prototype.cluster.json
{
    "clusterType":"MASTER_SLAVE",
    "heartbeat":{
        "heartbeatTimeout":1000,
        "maxRetryCount":3,
        "minSwitchTimeInterval":300,
        "showLog":false,
        "slaveThreshold":0.0
    },
    "masters":[
        "rwSepw"
    ],
    "maxCon":2000,
    "name":"prototype",
    "readBalanceType":"BALANCE_ALL",
    "replicas":[
        "rwSepr"
    ],
    "switchType":"SWITCH"
}

readBalanceType:查询负载均衡策略

BALANCE_ALL(默认值):获取集群中所有数据源

BALANCE_ALL_READ:获取集群中允许读的数据源

BALANCE_READ_WRITE:获取集群中允许读写的数据源,但允许读的数据源优先

BALANCE_NONE:获取集群中允许写数据源,即主节点中选择

switchType:控制主从切换

NOT_SWITCH:不进行主从切换

SWITCH:进行主从切换

此时,架构如下

image

4. 验证读写分离

修改MySQL的配置文件:my.cnf,设置logbin格式binlog_format=STATEMENT,重启MySQL,确保此时主从复制正常

登录MyCat:mysql -uroot -p123456 -h IP -P 8066,向数据表插入系统变量值,以此造成主从数据不一致,便于验证读写分离。

-- 主库中执行
INSERT INTO mytb VALUES(2,@@hostname);

登录主库查看表数据

image

登录从库查看表数据

image

登录MyCat查询验证 (刷新几次)

image

image

posted @ 2023-01-06 21:03  CoderTL  阅读(242)  评论(1编辑  收藏  举报