Docker部署Mycat2实现单库分表

参考文档

Mycat2官方语雀文档:Mycat2权威指南 (yuque.com)

Mycat2注释配置:通过注释配置 (yuque.com) 

Mycat2映射关系:mycat2映射关系.pdf

创建镜像

1.创建文件夹用于挂载Mycat相关数据卷

mkdir /home/docker/mycat2
cd /home/docker/mycat2

2.创建镜像文件

        在/home/docker/mycat2下创建Dockerfile,内容如下:

FROM openjdk:8-jre
 
ENV AUTO_RUN_DIR ./mycat2
ENV DEPENDENCE_FILE mycat2-1.22-release-jar-with-dependencies.jar
ENV TEMPLATE_FILE mycat2-install-template-1.21.zip
 
RUN sed -i "s@http://.*archive.ubuntu.com@http://mirrors.aliyun.com@g" /etc/apt/sources.list
RUN sed -i "s@http://.*security.ubuntu.com@http://mirrors.aliyun.com@g" /etc/apt/sources.list
 
RUN buildDeps='procps wget unzip' \
&& apt-get update \
&& apt-get install -y $buildDeps
 
# 安装地址 http://dl.mycat.org.cn/2.0/
# http://dl.mycat.org.cn/2.0/1.22-release/
# http://dl.mycat.org.cn/2.0/install-template/
RUN wget -P $AUTO_RUN_DIR/ http://dl.mycat.org.cn/2.0/1.22-release/$DEPENDENCE_FILE \
&& wget -P $AUTO_RUN_DIR/ http://dl.mycat.org.cn/2.0/install-template/$TEMPLATE_FILE
 
RUN cd $AUTO_RUN_DIR/ \
&& unzip $TEMPLATE_FILE \
&& ls -al . \
&& mv $DEPENDENCE_FILE mycat/lib/ \
&& chmod +x mycat/bin/* \
&& chmod 755 mycat/lib/* \
&& mv mycat /usr/local
 
#copy mycat /usr/local/mycat/
VOLUME /usr/local/mycat/conf
VOLUME /usr/local/mycat/logs
 
EXPOSE 8066 1984
CMD ["/usr/local/mycat/bin/mycat", "console"]

3..编译镜像

docker build -t mycat/mycat2:20230801 .

4.mysql用户创建

        为mycat用户单独在mysql中创建一个用户,并赋予权限

CREATE USER 'mycat'@'%' IDENTIFIED BY '123456';
-- MySQL8.0版本必须要赋的权限
GRANT XA_RECOVER_ADMIN ON *.* TO 'root'@'%';
--- 视情况赋的权限
GRANT ALL PRIVILEGES ON *.* TO 'mycat'@'%' ;
flush privileges;

构建镜像

启动容器并复制配置

docker run -d --name=mycat2 -p 8066:8066 -p 1984:1984 mycat/mycat2:20230801

# 复制容器内配置
cd /home/docker/mycat2/
docker cp mycat2:/usr/local/mycat/conf .
docker cp mycat2:/usr/local/mycat/logs .

        config目录如下:

启动Mycat2

        关闭并删除之前运行的容器,重新运行一个mycat2,记得开放端口

docker run -d 

--name=mycat2 

-p 8066:8066 -p 1984:1984 

-v $PWD/conf:/usr/local/mycat/conf 

-v $PWD/logs:/usr/local/mycat/logs 

4baac999529e(mycat2镜像ID)

Mycat2配置

        运行后肯定会报错,因为我们还没有对Mycat2做任何配置,日志可在 /home/docker/mycat2/logs/wrapper.log 中查看。

        Mycat2的配置结构如下:

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. datasources/prototypeDs.datasource.json为真实物理数据库的连接配置信息
  2. schemas/databaseName.schema.json主要配置逻辑表与物理表的关系及分库分表规则

我们需要经常修改的也就是上面两个文件

1.配置真实数据源

vi conf/datasourcesprototypeDs.datasource.json 

       改为自己物理数据库的连接信息,也可以配置成刚刚创建的用户

{
    "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/testdb?useUnicode=true&serverTimezone=Asia/Shanghai&characterEncoding=UTF-8",
    "user":"mycat",    // 数据库用户名
    "weight":0
}

2.查看或修改Mycat登录用户信息

vi /home/docker/mycat2/conf/users/root.user.json
{
	"dialect":"mysql",
	"ip":null,    # 如果设置IP,则只能允许该IP使用该用户登录mycat
	"password":"123456",    // 密码
	"transactionType":"proxy",    //事务类型
	"username":"root"    // 用户名
}

可以直接用此账号登录Mycat。

不涉及跨库事务请把事务类型(transactionType)改成proxy,不要使用XA

3.登录Mycat,并创建数据库 

使用root.user.json中的账号密码登录Mycat,端口8066,并创建一个数据库,我这里与物理库名一致。

CREATE DATABASE testdb;

此时 /conf/schemas文件夹下会多出一个 testdb.schema.json 的文件。内容如下:

{
	"customTables":{},
	"globalTables":{},
	"normalProcedures":{},
	"normalTables":{},
	"schemaName":"note",
	"shardingTables":{},
	"views":{}
}

4.配置表分片规则

后面所有对 testdb 库中的表进行分片规则都可以直接在 /conf/schemas/testdb.schema.json 中来进行配置,也可以使用带有 mycat2 语法的SQL建表语句来指定分片键和分片规则。相比于Mycat1.6来说方便了太多。

分库分表语法文档:DDL语句 (yuque.com)

在Mycat客户端的testdb库创建要进行分片的表(虚拟表),并指定分片规则:

 CREATE TABLE `test_sharding` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `add_time` bigint(20) NOT NULL COMMENT '创建时间',
  `text` varchar(255) COLLATE utf8mb4_bin NOT NULL DEFAULT '' COMMENT '测试文本',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4  tbpartition by MOD_HASH(id) tbpartitions 3;

其中:tbpartition by MOD_HASH(id) tbpartitions 3; 的含义为 test_sharding 该表需要按照 id 字段哈希取模(即分区值 % 总分区点)来分区,且分区点有三个,分别对应 test_sharding_0、test_sharding_1、test_sharding_2,所以需要先要在物理库中保证这三张表存在。

同样的,如果要进行分库,可以加上 dbpartition by MOD_HASH(id) dbpartitions 数据库数量; 

创建完虚拟表后,查看 /conf/schemas/testdb.schema.json 会看到多出来了些配置信息。还需要添加些配置,内容如下:

{
    "customTables": { }, 
    "globalTables": { }, 
    "normalProcedures": { }, 
    "normalTables": { }, 
    "schemaName": "testdb", // 逻辑库名 
    "shardingTables": {
        "test_sharding": {
            <!-- 建表SQL -->
            "createTableSQL": "CREATE TABLE `test_sharding` (
	`id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,
	`add_time` bigint(20) NOT NULL COMMENT '创建时间',
	`text` varchar(255) COLLATE utf8mb4_bin NOT NULL DEFAULT '' COMMENT '测试文本',
	PRIMARY KEY (`id`)
) ENGINE = InnoDB CHARSET = utf8mb4
TBPARTITION BY MOD_HASH(id) TBPARTITIONS 3", 
            "autoIncrement": false, 
            "function": {
                "properties": {
                    "mappingFormat": "prototype/testdb/test_sharding_${tableIndex}", 
                    "tableNum": "3", # 分区表的数量
                    "tableMethod": "MOD_HASH(id)",  #使用哈希取模算法分区
                    "storeNum": 0, 
                    "defaultNode": "0", 
                    "type": "Integer"
                }, 
                "partition": {
                    "schemaNames": "testdb", #物理库
                    "tableNames": "test_sharding_$0-2", #物理表
                    "targetNames": "prototype"    #数据源
                }
            }, 
            "shardingIndexTables": { }
        }
    }, 
    "targetName":"prototypeDs",
    "views": { }
}

或 

{
    "customTables": { }, 
    "globalTables": { }, 
    "normalProcedures": { }, 
    "normalTables": { }, 
    "schemaName": "testdb", // 逻辑库名 
    "shardingTables": {
        "test_sharding": {
            <!-- 建表SQL -->
            "createTableSQL": "CREATE TABLE `test_sharding` (
	`id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,
	`add_time` bigint(20) NOT NULL COMMENT '创建时间',
	`text` varchar(255) COLLATE utf8mb4_bin NOT NULL DEFAULT '' COMMENT '测试文本',
	PRIMARY KEY (`id`)
) ENGINE = InnoDB CHARSET = utf8mb4
TBPARTITION BY MOD_HASH(id) TBPARTITIONS 3",
            "function": {
                "properties": {
                    "mappingFormat": "prototype/testdb/test_sharding_${tableIndex}", 
                    "tableNum": "3", # 分区表的数量
                    "tableMethod": "MOD_HASH(id)",  #使用哈希取模算法分区
                    "storeNum": 0, 
                }
            }, 
            "shardingIndexTables": { }
        }
    }, 
    "targetName":"prototypeDs",
    "views": { }
}

其中,分区算法及配置样例可参考:Mycat 2 规则范围分片算法(对应1.6) (yuque.com)

注意: 

 如果逻辑库与物理库混淆的话,会导致数据插入错数据库的错误。

需要创建不需要被分库分表的表,直接在Mycat客户端执行建表语句即可,对应配置会同步到normalTables中。

测试

在应用层连接MySql的地址直接改为连接Mycat,端口8066,连接信息在conf/users/root.user.json中。

往 test_sharding 表中连续插入数据可以看到数据被分配到了不同的表中:

 其中 id 是Mycat生成的全局唯一ID。

并且在Mycat中进行 select * 查询也能将物理库中三张表的数据一起查询出来。

注意

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

所以Mycat中的库与表也被称为“虚拟库”与“虚拟表”,并且“虚拟表”不允许在可视化客户端修改其表结构,只能手动通过DDL语句进行修改

补充

Q:如何怎么把已经存在的物理表加载到mycat中?

A:使用schema配置中的targetName,指向目标数据源或者集群,同时保证schema的名字与目标的库相同,即可自动加载该库已经存在的物理表

重启mycat或者用注释重新读取Mycat配置文件./*+mycat:loadConfigFromFile{} */把本地配置加载到运行时

在使用Group By时,查询不在Group By中的字段且无函数,则需要使用any_value。

order by必须引用select item中存在的字段

猜你喜欢

转载自blog.csdn.net/weixin_53922163/article/details/132047639
今日推荐