Mycat2.0搭建

基础环境准备

安装JDK1.8:我使用的JDK版本是 JDK1.8.0_181
安装MySQL:MySQL5.7安装教程

Mycat2官方文档

安装Mycat2.0

下载安装包
Mycat2当前不提供安装包,只提供核心JAR包,JAR包可以独立运行,安装包是使用Java Service Wrapper做壳的,需要安装包药自己制作。下载对应的tar安装包壳和Mycat2 jar包。
tar包下载地址:http://dl.mycat.org.cn/2.0/install-template/
jar包下载地址:http://dl.mycat.org.cn/2.0/1.20-release/
分别下载tar包和jar包地址中的最新版本即可,jar包一定要下载最新版本的! Mycat2.0还在不断优化晚上中,经常就会发布新的jar包修复一些问题,我下载的版本分别是:mycat2-install-template-1.20.zip 和 mycat2-1.20-jar-with-dependencies-2021-12-16.jar。下载完成后把安装包传送到服务器上,也可以在服务器上用wget直接下载

cd /usr/local
# 下载tar包壳
wget http://dl.mycat.org.cn/2.0/install-template/mycat2-install-template-1.20.zip
# 下载运行jar包,用http://dl.mycat.org.cn/2.0/1.20-release/ 最新的jar包
wget http://dl.mycat.org.cn/2.0/1.20-release/mycat2-1.20-jar-with-dependencies-2021-12-3.jar

# 解压tar包壳
unzip mycat2-install-template-1.20.zip
# 将运行jar包放到tar包壳的 lib 目录下
mv mycat2-1.20-jar-with-dependencies-2021-12-3.jar mycat/lib/
# 修改tar包壳bin/ 目录下所有文件的权限
chmod 777 mycat/bin/*

配置MySQL
配置MySQL用户权限

-- 创建mycat用户
CREATE USER 'mycat'@'%' IDENTIFIED BY 'Mycat_123456';
-- 官方文档强调要给root账号添加XA RECOVER权限,但我运行下面这个命令一直报语法错误,就把所有权限都添加给了root账号
-- GRANT XA_RECOVER_ADMIN ON *.* TO 'root'@'%';
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%';
-- 给mycat用户添加权限,大家可以按照自己的需要添加权限,我是全部权限都加了
GRANT ALL PRIVILEGES ON *.* TO 'mycat'@'%' ;
FLUSH PRIVILEGES;

基本概念

prototype服务器(原型库)
在这里插入图片描述
prototype服务器是分库分表中间件中用于处理MySQL的兼容性SQL(Mycat2.0客户端或框架运行依赖的相关记录表,对使用者来说无感知)和系统表SQL(比如用于显示库,表的sql)的服务器,这个配置项可以指向一个服务器也可以是一个集群,Mycat依赖它处理非select,insert,update,delete语句。当这个服务器是与第一个存储节点是同一个服务器/集群的时候,人们一般叫它做0号节点。原型库也是单表的默认存储节点。

当需要进行数据分片的时候,Mycat是通过扩展存储节点的方式实现的。如果对prototype服务器不太理解,跟着下面的搭建步骤一步一步去生成单表、全局表、分片表的时候,自然就能理解整体的架构设计。
在这里插入图片描述

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

数据源
数据源为连接后端数据库的组件,它是数据库代理中连接后端数据库的客户端。mycat的数据源对应实际MySQL物理库中的schema库。

Mycat2配置详解

这个环节可以大致了解Mycat2.0配置的含义,可以结合后面的Mycat2.0实战使用步骤,一边实测一边理解配置是如何生效的。

tar包壳下的prototype.cluster.json,prototypeDs.datasource.json,mysql.schema.json,这三个配置文件需要保留,这三个配置文件用于配置Mycat的prototype服务器。

mycat2配置文件目录结构

mycat/conf
		+ 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运行状态,包含集群选举的主节点信息,配置时间戳

集群配置

Mycat自带一个prototype.cluster.json配置文件,用于配置prototype服务器的集群信息,这个文件的可以无需修改。
集群配置文件格式:mycat/conf/clusters/{集群名字}.cluster.json,集群名字根据自己的需要指定。

c0.cluster.json 配置样例:

{
	"clusterType":"MASTER_SLAVE",
	"heartbeat":{
		"heartbeatTimeout":1000,
		"maxRetryCount":3,
		"minSwitchTimeInterval":300,
		"slaveThreshold":0
	},
	"masters":[
		"db0",
		"db1"
	],
  "replicas":[
		
	],
	"maxCon":200,
	"name":"c0",
	"readBalanceType":"BALANCE_ALL",
	"switchType":"SWITCH"
}

核心配置详解:
clusterType: 集群类型
SINGLE_NODE:单一节点
MASTER_SLAVE:普通主从
GARELA_CLUSTER:garela cluster/PXC集群

masters: 主节点配置
可配置多个主节点,在主挂的时候会选一个检测存活的数据源作为主节点

replicas: 从节点配置
可配置多个从节点

name: 数据源名称
要跟mycat/conf/datasources/{数据源名字}.datasource.json 中的数据源名字保持一致

readBalanceType: 查询负载均衡策略
BALANCE_ALL(默认值)
获取集群中所有数据源
BALANCE_ALL_READ
获取集群中允许读的数据源
BALANCE_READ_WRITE
获取集群中允许读写的数据源,但允许读的数据源优先
BALANCE_NONE
获取集群中允许写数据源,即主节点中选择

switchType: 主从切换设置
NOT_SWITCH:不进行主从切换
SWITCH:进行主从切换

readBalanceName: 读取负载均衡策略
writeBalanceName: 写入负载均衡策略

BalanceLeastActive
最少正在使用的连接数的mysql数据源被选中,如果连接数相同,则从连接数相同的数据源中的随机,使慢的机器收到更少。
BalanceRandom
利用随机算法产生随机数,然后从活跃的mysql数据源中进行选取。
BalanceRoundRobin
加权轮训算法,记录轮训的权值,每次访问加一,得到n,然后对mysql数据源进行轮训,如果权值已经为零,则跳过,如果非零则减一,n减1,直n为零则选中的节点就是需要访问的mysql数据源节点。
BalanceRunOnReplica
io.mycat.plug.loadBalance.BalanceRunOnReplica
把请求尽量发往从节点,不会把请求发到不可读(根据延迟值判断)与不可用的从节点

数据源配置

Mycat自带一个prototypeDs.datasource.json配置文件,用于配置prototype服务器的数据源信息,将这个文件的url, user, password三个属性改成自己的MySQL地址和用户密码即可。

数据源配置文件格式:mycat/conf/datasources/{数据源名字}.datasource.json,数据源名字可以根据自己的需要自定义,如果配置了数据源,需要在MySQL物理库中创建相应的schema库,否则mycat启动会失败。

db0.datasource.json配置样例:

{
	"dbType": "mysql",
	"idleTimeout": 60000,
	"initSqls": [],
	"initSqlsGetConnection": true,
	"instanceType": "READ_WRITE",
	"maxCon": 1000,
	"maxConnectTimeout": 3000,
	"maxRetryCount": 5,
	"minCon": 10,
	"name": "db0",
	"password": "<your_mysqldb_password>",
	"type": "JDBC",
	"url": "jdbc:mysql://10.0.27.38:3306?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&useSSL=false",
	"user": "root",
	"weight": 0,
 	"queryTimeout":5000
}

配置详解:
type: 数据源类型
NATIVE,只使用NATIVE协议(即Mycat自研的连接MySQL的协议)
JDBC,默认,只使用JDBC驱动连接
NATIVE_JDBC,该数据源同一个配置同时可以使用NATIVE,JDBC

name: 数据源名称

ur: JDBC连接URL
对应实际MySQL连接地址,可以无需指定MySQL schema。如果URL中配置了MySQL schema,相应的MySQL schema必须在物理库上先创建好,否则无法启动mycat。

password: MySQL用户密码

instanceType: 配置实例只读还是读写
READ=只读节点
READ_WRITE=读写节点

queryTimeout: jdbc查询超时时间,单位:ms
默认30mills,根据实际业务需要调整超时时间

maxConnectTimeout: 定时检查闲置连接,单位:ms

initSqlsGetConnection: 每次获取jdbc连接是否都执行initSqls
true|false,默认:false

JDBC禁用SSL属性有助提高性能

配置逻辑库(schema)

配置的schema的逻辑库逻辑表必须在原型库(prototype)中有对应的物理库物理表,否则不能启动。初次使用可以无需配置schema,连接Mycat后可以在Mycat上执行SQL命令,Mycat会自动生成相关的schema配置文件。

想要更多了解schema相关配置可以查阅官方文档:Mycat2.0 schema配置官方文档

创建 mycat/conf/schemas/{库名}.schema.json

schema0.schema.json 配置样例:


配置详解:
targetName: 数据源名称
自动从prototype目标加载test库下的物理表或者视图作为单表,prototype必须是mysql服务器

schemaName: MySQL schema名称

Mycat2.0实战使用

使用之前要修改prototypeDs.datasource.json配置文件,将这个文件的url, user, password三个属性改成自己的MySQL地址和用户密码即可。

Mycat2.0启动命令

cd mycat/bin
./mycat start
./mycat status
./mycat start 启动
./mycat stop 停止
./mycat console 前台运行
./mycat install 添加到系统自动启动(暂未实现)
./mycat remove 取消随系统自动启动(暂未实现)
./mycat restart 重启服务
./mycat pause 暂停
./mycat status 查看启动状态

登录Mycat
Mycat可以当成一个MySQL直接使用,连接方式跟连接MySQL服务器是一样的。
mysql -uroot -p123456 -h10.0.27.18 -P8066

命令详解:

  • -u: 登录用户名,为mycat/conf/user/root.user.json 文件中配置的用户名
  • -p: 登录用户密码,为mycat/conf/user/root.user.json 文件中配置的密码
  • P: Mycat服务端口号(留意是大写的P),为mycat/conf/server.json 文件中port属性配置的端口号,端口号默认8066

或者可以通过MySQL连接工具连接Mycat(我用的是MySQL WorkBench),连接方式跟连接MySQL数据库是一样的。

注意:最好根据一下的操作步骤一步一步执行,不要调换顺序否则就可能会发生问题!

创建database

-- 创建database
create database db;
-- 查看创建的database
show databases;
-- 删除database
drop database db;

命令详解:
create database 会在prototypeDs.datasource.json 配置文件配置的prototype节点建立对应的物理库,但是在其他分片存储节点并不马上执行,直到物理表用到该物理库的时候才建立(Mycat配置文件详解参考本文下面的mycat配置文件详解模块)。

drop database 会在prototypeDs.datasource.json 配置文件配置的prototype节点删除对应的物理库,但是对于全局表,分片表的扩展存储节点不会进行删除物理库操作。

创建单表

-- 在mycat终端输入
CREATE TABLE db.`city` (
  `id` bigint NOT NULL AUTO_INCREMENT,
  `city_code` varchar(32) NOT NULL COMMENT '城市编码',
  `city_name` varchar(32) NOT NULL COMMENT '城市名称',
  `country` varchar(32) NOT NULL COMMENT '城市所在国家',
  PRIMARY KEY (`id`),
  KEY `IX_CITY_CODE` (`city_code`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8mb4;

运行命令后就能在prototypeDs.datasource.json 配置文件的prototype属性配置的MySQL物理库上看到新建的表。创建单表不会在数据分片的扩展库中创建对应的表。

创建全局表
创建全局表之前,要先配置好数据源,mycat可以通过注解注解的方式动态配置配置文件。配置数据源时不能有已创建好的空的database,否则会导致创建数据源失败。运行完注解命令后会自动生成集群、数据源、schema相关的配置文件。

# 添加存储数据源配置
/*+ mycat:createDataSource{
"name":"dw0",
"url":"jdbc:mysql://10.0.27.38:3306",
"user":"root",
"password":"Insigma_2021"
} */;
/*+ mycat:createDataSource{
"name":"dr0",
"url":"jdbc:mysql://10.0.27.38:3306",
"user":"root",
"password":"Insigma_2021"
} */;
/*+ mycat:createDataSource{
"name":"dw1",
"url":"jdbc:mysql://10.0.27.16:3306",
"user":"insigma",
"password":"insigma2017"
} */;
/*+ mycat:createDataSource{
"name":"dr1",
"url":"jdbc:mysql://10.0.27.16:3306",
"user":"insigma",
"password":"insigma2017"
} */;


# 添加集群配置
/*! mycat:createCluster{"name":"c0","masters":["dw0"],"replicas":["dr0"]} */;
/*! mycat:createCluster{"name":"c1","masters":["dw1"],"replicas":["dr1"]} */;


####### 如果需要删除集群和数据源可以使用以下的命令 #######
# 删除集群配置
/*! mycat:dropCluster{
	"name":"c0"
} */;

# 删除数据源配置,删除数据源之前要先删除依赖了这个数据源的集群,否则无法删除
/*+ mycat:dropDataSource{
"name":"dr0",
"url":"jdbc:mysql://10.0.27.38:3306",
"user":"root",
"password":"Insigma_2021"
} */;

运行完以上注解后,会自动在mycat/config/datasources/目录下自动生成 dr0.datasource.json, dw0.datasource.json, dr1.datasource.json, dw1.datasource.json 数据源相关的配置文件。在mycat/config/datasources/clusters 目录下自动生成 c0.cluster.json, c1.cluster.json 集群配置文件

自动生成的 dw0.datasource.json 文件配置如下(dw1,dr0,dr1文件的配置结构是一样的):

{
	"dbType":"mysql",
	"idleTimeout":60000,
	"initSqls":[],
	"initSqlsGetConnection":true,
	"instanceType":"READ_WRITE",
	"maxCon":1000,
	"maxConnectTimeout":30000,
	"maxRetryCount":5,
	"minCon":1,
	"name":"dw0",
	"password":"Insigma_2021",
	"queryTimeout":30,
	"type":"JDBC",
	"url":"jdbc:mysql://10.0.27.38:3306?useUnicode=true&serverTimezone=Asia/Shanghai&characterEncoding=UTF-8&autoReconnect=true",
	"user":"root",
	"weight":0
}

自动生成的 c0.cluster.json 文件配置如下(c1的文件配置结构是一样的):

{
	"clusterType":"MASTER_SLAVE",
	"heartbeat":{
		"heartbeatTimeout":1000,
		"maxRetryCount":3,
		"minSwitchTimeInterval":300,
		"slaveThreshold":0.0
	},
	"masters":[
		"dw0"
	],
	"maxCon":2000,
	"name":"c0",
	"readBalanceType":"BALANCE_ALL",
	"replicas":[
		"dr0"
	],
	"switchType":"SWITCH"
}

在Mycat代理层执行SQL创建全局表

//在mycat终端输入
CREATE TABLE db.`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=utf8mb4 BROADCAST;

BROADCAST是创建全局表的关键字,mycat会给当前所有配置的数据源都自动生成名字为 db 的MySQL schema库(如果这个schema不存在的话),并在db库中自动生成 travelrecord 表。

创建分片表
创建分片表之前,也要先配置好数据源,上面创建全局表的时候已经配置过了数据源,这里就无需重复配置。

-- 该分表创建SQL会自动创建db_0,db_1两个MySQL schema库,每个库下面4张分表
CREATE TABLE db.`customer` (
  `ID` bigint(20) NOT NULL AUTO_INCREMENT,
  `user_id` varchar(32) NOT NULL COMMENT '用户唯一标识',
  `user_name` varchar(32) NOT NULL COMMENT '登录账号(全英文,大小写)',
  `nick_name` varchar(32) DEFAULT NULL COMMENT '昵称(用户名称)中英文',
  `password` varchar(64) NOT NULL COMMENT '密码',
  `parent_user_code` varchar(32) DEFAULT NULL COMMENT '该账号的创建者唯一标识',
  `parent_user_name` varchar(32) DEFAULT NULL COMMENT '该账号的创建者名字',
  `status` int(2) NOT NULL DEFAULT '1' COMMENT '0黑名单;1正常状态(默认1)',
  `gmt_created` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `gmt_modified` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
  `is_deleted` tinyint(4) DEFAULT '0' COMMENT '逻辑删除标志位,0=数据有效,1=数据被删除',
  PRIMARY KEY (`ID`) USING BTREE,
  UNIQUE KEY `UK_USER_ID` (`user_id`) USING BTREE,
  UNIQUE KEY `UK_USER_NAME` (`user_name`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='用户账号表'
DBPARTITION BY MOD_HASH(user_id) DBPARTITIONS 2
TBPARTITION BY MOD_HASH(user_id) TBPARTITIONS 4;

-- 表结构变更,执行表结构变更语句会同步更新所有分库下的所有分表的表结构
alter table db.`customer` ADD COLUMN `age` int(11) NOT NULL COMMENT '年龄' AFTER `nick_name`;

-- 插入一些数据,插入的数据会自动根据user_id作数据库表路由分发写入
INSERT INTO db.`customer` VALUES (1,'100314439429167616','admin0','管理员0',18,'abafebddd62dc7677ffcc12f0bd86391','-1','',1,now(),now(),0);
INSERT INTO db.`customer` VALUES (2,'100314439429167617','admin2','管理员2',18,'a8f516a3c8680e17aaed6ee24717cf11','-1','',1,now(),now(),0);
INSERT INTO db.`customer` VALUES (3,'100314439429167618','admin3','管理员3',18,'52f70ed7ecd80557be0e3bf938b42843','-1','',1,now(),now(),0);
INSERT INTO db.`customer` VALUES (4,'100314439429167619','admin4','管理员4',18,'99ec64e9af911a559981a168afb17e2a','-1','',1,now(),now(),0);
INSERT INTO db.`customer` VALUES (5,'100314439429167620','admin5','管理员5',18,'4818569c463724d9c7cbf8082c4c028e','-1','',1,now(),now(),0);
INSERT INTO db.`customer` VALUES (6,'100314439429167621','admin6','管理员6',18,'70a96c97fe06a91d0ce520fc4ada65d0','-1','',1,now(),now(),0);
INSERT INTO db.`customer` VALUES (7,'100314439429167622','admin7','管理员7',18,'32651dfe2338db43dd7a0bb138500e87','-1','',1,now(),now(),0);
INSERT INTO db.`customer` VALUES (8,'100314439429167623','admin8','管理员8',18,'8c37d53c19ac0840375831be588aedff','-1','',1,now(),now(),0);
INSERT INTO db.`customer` VALUES (9,'100314439429167624','admin9','管理员9',18,'a4f233d493a46b798236413d2cd34ecd','-1','',1,now(),now(),0);
INSERT INTO db.`customer` VALUES (10,'100314439429167625','admin10','管理员10',18,'2e4b6b25bd027d9ea284f89ddc0c8cf8','-1','',1,now(),now(),0);

-- 查询插入的数据,查询语句会自动根据user_id作数据库表路由分发查询
select * from db.customer where user_id='100314439429167617';

-- 测试分片表字段,表字段变更会自动同步到所有的分片表中
alter table db.`customer` MODIFY COLUMN `status` tinyint(4) NOT NULL COMMENT '用户状态,0黑名单;1正常状态(默认1)';

DBPARTITION, TBPARTITION 是创建分片表的关键字,DBPARTITION指定要创建几个分库,TBPARTITION指定每个分库要创建几张分表。
MOD_HASH: HASH型分片算法
如果分片值是字符串则先对字符串进行hash转换为数值类型
分库键和分表键是同键
分表下标=分片值%(分库数量*分表数量)
分库下标=分表下标/分表数量
分库键和分表键是不同键
分表下标= 分片值%分表数量
分库下标=分表下标%分库数量
Mycat2.0分片算法官方文档

查看生成的分库和分表以及全局表
通过MySQL连接工具连接Mycat(我用的是MySQL WorkBench),可以看到Mycat对分库和分表做了聚合,我们无需关心数据是写入到哪个分库哪张分表下,Mycat会自动作数据分片的路由和聚合,这一点很实用,大大方便我们排查数据和后期运维的工作量。
在这里插入图片描述

dw0配置的MySQL物理库db schema上生成了单表city,全局表travelrecord,db_0 schema上生成分片表customer_0, customer_1, customer_2, customer_3
在这里插入图片描述

dw1配置的MySQL物理库db schema上生成了全局表travelrecord,db_0 schema上生成分片表customer_4, customer_5, customer_6, customer_7
在这里插入图片描述

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐