MyCat实现MySql高可用集群

MyCat实现MySql高可用集群

Mycat安装,基于docker

mycat安装比较简单,直接官方下载压缩包,解压即可;
myCat下载链接

mycat是java开发的,所以运行mycat需要jre支持,jre我的资源有上传,大家可以下载

为了可移植性好,我们自定义docker镜像,写个dockerfile

制作容器卷dockerfile

FROM centos

MAINTAINER dang<177372952@qq.com>

LABEL name="mycat11 myCat Image" build-data="20200901"

ADD server-jre-8u261-linux-x64.tar.gz /home/

ADD Mycat-server-1.6.7.4-release-20200105164103-linux.tar.gz /home/

ENV WORKPATH /home/mycat/

WORKDIR $WORKPATH

ENV JAVA_HOME /home/jdk1.8.0_261

ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar

ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin

EXPOSE 8066

CMD /home/mycat/bin/mycat console   #如果需要后台启动,则改为start

Mycat启动方式

Ⅰ:bin目录

​	./mycat console 控制台启动(我们用这种,可以看到执行记录)

Ⅱ :bin目录

​	./mycat start 后台启动

构建容器命令

docker build -f myCatDockerFile -t mycat11/mycat:1.0 .

启动容器

docker run -p 8066:8066 -it 镜像ID

挂载配置文件和log至宿主机

为了方便配置和查看日志,先把容器配置文件和log复制到宿主机

docker cp 容器ID:/home/mycat/conf/ /home/docker/mycat/conf/

docker cp 容器ID:/home/mycat/logs/ /home/docker/mycat/

启动挂载容器

docker run -p 8066:8066 -it -v /home/docker/mycat/conf/:/home/mycat/conf/ -v /home/docker/mycat/logs/:/home/mycat/logs/ --net extnetwork --ip 172.20.0.4 镜像ID

docker部署mysql主从

1,下载mysql容器

docker pull mysql:5.7

2 , 先启动容器

docker run -p 3306:3306 -d -e MYSQL_ROOT_PASSWORD=123456  容器ID

3 , 进入容器

docker exec -it aeb469a58aa8 /bin/bash

4, 宿主机下home目录,新建mysql文件,用于存放配置文件和日志目录(挂载容器卷启动,不需要每次进入容器查看日志,修改配置)

5,拷贝文件到宿主机/home/mysql目录下 主从则需复制两份

docker cp  容器ID:/etc/mysql/mysql.conf.d/ /home/mysql/

docker cp  容器ID:/var/log /home/mysql/ 

6, 启动容器镜像

主:

docker run -p 3306:3306 --name master -d -v /home/mysql/mysql.conf.d/:/etc/mysql/mysql.conf.d/ -v /home/mysql/log/:/var/log -e MYSQL_ROOT_PASSWORD=123456 镜像ID

从:

docker run -p 3307:3306 --name slave -d -v /home/mysql2/mysql.conf.d/:/etc/mysql/mysql.conf.d/ -v /home/mysql2/log/:/var/log -e MYSQL_ROOT_PASSWORD=123456 镜像ID

docker自定义网络模式,实现容器ID固定IP

我们在使用docker容器时,每次启动容器,容器分配的虚拟IP经常变动,比如我们现在使用的mycat+mysql,我们需要配置mysql服务IP地址,这个IP是docker分配的虚拟IP,假如经常变动,我们得手动修改配置,很麻烦,所以需要固定IP

docker 默认使用的是bridge 桥接网络模式

我们可以查看 docker network ls
在这里插入图片描述

创建自定义网络模式

docker network create --subnet=172.20.0.0/16 extnetwork

删除自定义网络

docker network rm NETWORK ID

创建容器并指定IP

​ 通过 --net extnetwork --ip 172.20.0.2 指定

​ 案例:

​ 主

docker run -p 3306:3306 --name master -d -v /home/mysql/mysql.conf.d/:/etc/mysql/mysql.conf.d/ -v /home/mysql/log/:/var/log --net extnetwork --ip 172.20.0.2 -e MYSQL_ROOT_PASSWORD=123456 镜像ID

​ 从

docker run -p 3307:3306 --name slave -d -v /home/mysql2/mysql.conf.d/:/etc/mysql/mysql.conf.d/ -v /home/mysql2/log/:/var/log --net extnetwork --ip 172.20.0.3 -e MYSQL_ROOT_PASSWORD=123456 镜像ID

(我们启动两个mysql容器,并且固定分配IP 172.20.0.2和172.20.0.3;注意:这里必须使用172.20.0.2开始分配,因为172.20.0.1是网关

mysql配置文件进行主从配置

现在mysql 主服务器: 172.20.0.2 从服务器: 172.20.0.3

主机配置:

打开mysqld.cnf (/home/mysql/mysql.conf.d/ 下)

添加如下配置

#主服务器ID,必须唯一

server-id=2

#开启以及设置二进制日志文件名称

log-bin=mysql-bin

#要同步的数据库

binlog-do-db=db_mycat11

#不需要同步的数据库

binlog-ignore-db=mysql

binlog-ignore-db=information_schema

binlog-ignore-db=performation_schema

binlog-ignore-db=sys

#设置logbin格式

binlog_format=MIXED #binlog日志格式,mysql默认采用statement,建议使用mixed

从机配置

打开mysqld.cnf (/home/mysql2//mysql.conf.d/ 下)

server-id=3

relay-log=mysql-relay

配置完成后可在navicat查询

SHOW MASTER STATUS

SHOW SLAVE STATUS

主服务器创建从机访问用户以及授权,主机navicat新建查询里面运行

CREATE USER 'slave1'@'172.20.0.3'  IDENTIFIED BY '123456';

GRANT REPLICATION SLAVE ON *.* TO 'slave1'@'172.20.0.3';

FLUSH PRIVILEGES;

从机创建连接主服务器的IP,用户,密码以及日志文件和位置;

CHANGE MASTER TO MASTER_HOST='172.20.0.2',MASTER_USER='slave1',MASTER_PASSWORD='123456';

MASTER_LOG_FILE='mysql-bin.000001',MASTER_LOG_POS=154;
#启动主从复制
START SLAVE;
#查看从机状态
SHOW SLAVE STATUS

从机同步数据失败 Slave_SQL_Running: No

stop slave ;
set GLOBAL SQL_SLAVE_SKIP_COUNTER=1;
start slave ;

主从复制常用命令

START SLAVE
不带任何参数,表示同时启动I/O线程和SQL线程
I/O线程从主库中读取bin log,并存储到relay log中继日志文件中
SQL线程读取中继日志,解析后,在从库重放

STOP SLAVE
完成停止I/O线程和SQL线程的操作

SHOW MASTER STATUS
查看主服务器状态

SHOW SLAVE STATUS
查看从服务器状态

RESET MASTER
删除所有的index file中记录的所有binlog文件,将日志索引文件清空,创建一个新的日志文件,这个命令通常仅仅用于第一次搭建主从关系时的主库
重置后需要删除数据库,并且从服务器重新建立连接 MASTER_LOG_FILE='mysql-bin.000001',MASTER_LOG_POS=154;(MASTER_LOG_POS在主服务查看状态position中查找)

从服务器状态
在这里插入图片描述

MyCat读写分离实现

读写分离介绍

基于前面的mysql主从复制,我们通过Mycat,能够实现读写分离,即master主服务器实现写操作(inster,update,delete等),slave从服务器实现读操作(select等)

主服务器一旦有写入操作,从服务器通过读取binlog,来实现数据同步,MyCat也实时发送心跳包来检测mysql服务器是否可用

读写分离核心配置详解

mycat读写分离核心配置文件schema.xml文件

schema.xml有几个标签,分别是:mycat:schema schema主配置标签,schema逻辑库配置标签,dataNode数据节点配置标签,dataHost数据库主机配置标签
在这里插入图片描述

一个逻辑库对应多个逻辑表,每个逻辑表如上图,可以水平分片,分成一个或多个数据分片节点,每个数据分片节点对应一个dataHost(数据库主机),dataHost里可以通过writeHost和readHost配置写主机和读主机;

schema标签属性介绍(定义逻辑数据库):
属性解释
name配置逻辑库的名字(即数据库实例名)
checkSQLschemaSQLschema标签检查boolean类型。
当前端执行【select * from USERDB.tf_user时】(表名前指定了mycat逻辑库名),两种取值
true : mycat会把语句转为【select * from tf_user;】
false: 会报错
sqlMaxLimit最大查询每页记录数设置,相当于sql的结果集,加上【limit N】如果sql本身已经指定limit,则已sql指定为准
dataNode配置数据库节点:
用于配置该逻辑库默认的分片。没有通过table标签设置的表,就会走到默认的分片上。这里注意没有配置在table标签的表,用工具查看是无法显示的,但可以正常使用。
如果没有配置dataNode属性,则没有配置在table标签的表,是无法使用的
dataNode标签属性:(定义数据分片节点)
属性解释
name数据分片节点名称
dataHost定义该数据分片节点属于哪个数据库主机
database定义该数据分片节点属于哪个具体数据实例上的具体库(即对应mysql中实际的DB)
dataHost标签属性:(定义后端的数据库主机)
属性解释
name指定dataHost的名字
maxCon指定每个读写实例连接池的最大连接。也就是说,标签内嵌套的writeHost,readHost标签都会使用这个属性的值来实例化出连接池的最大连接数
minCon指定每个读写实例连接池的最小连接,初始化连接池的大小。
balance负载均衡实例:
(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”,所有读请求随机的分发到writeHost对应的readHost执行,writeHost不负担读压力,注意balance=3只在1.4及其以后版本有,1.3没有
writeType(1)writeType=“0”,所有写操作发送到配置的第一个writeHost,第一个挂了切到还生存的第二个writeHost.重新启动后已切换后的为准,切换记录在配置文件中: dnindex.properties
(2)writeType=“1”,所有写操作都随机的发送到配置的writeHost,1.5以后废弃不推荐
dbType指定后端连接的数据库类型,目前支持二进制的mysql协议,还有其他使用JDBC连接的数据库,例如:mongodb,oracle,spark等
dbDriver指定连接后端数据库使用的Driver,目前可选的值有native和JDBC。使用native的话,因为这个值执行的是二进制的mysql协议,所以可以使用mysql和maridb。其他类型的数据库则需要使用JDBC驱动来支持
switchType-1表示不自动切换;
1默认值,自动切换
2基于mysql主从同步的状态决定是否切换 心跳语句为show slave status
3基于mysql galary cluster 的切换机制(适合集群)(1.4.1)
slaveThreshold配置真实mysql与mycat的心跳
heartbeat子标签属性(心跳执行SQL)
writeHost子标签属性(写主机配置)
readHost子标签属性(读主机配置)
属性解释
host用于识别不同实例,一般wiriteHost我们使用 _M1,readHost使用 _S1
url后端实例连接地址,如果是使用native的dbDriver,则一般为address:port这种形式。用JDBC或其他的dbDriver.则需要特殊指定。当使用JDBC则可以这么写:jabc:mysql://localhost:3306/.
user后端存储实例需要的用户名字
password后端存储实例需要的密码
参考配置
<schema name="TESTDB" checkSQLschema="true" sqlMaxLimit="100" dataNode="dn1">
	
</schema>

<dataNode name="dn1" dataHost="host1" database="db_mycat11" />

<dataHost name="host1" maxCon="1000" minCon="10" balance="3"
		  writeType="0" dbType="mysql" dbDriver="native" switchType="2"  slaveThreshold="100">
	<heartbeat>select user()</heartbeat>
	<!-- can have multi write hosts -->
	<writeHost host="hostM1" url="172.20.0.2:3306" user="root"
			   password="123456">
		<!-- can have multi read hosts -->
		<readHost host="hostS1" url="172.20.0.3:3307" user="root" password="123456" /> 
	</writeHost>	
	
</dataHost>
测试mysql读写分离

修改matser主服务器配置mysqld.cnf

#设置logbin格式

binlog_format=STATEMENT #binlog日志格式,mysql默认采用STATEMENT,建议使用MIXED

重启docker master镜像

mysql读写重新配置 navicat的配置命令重新操作;如果失败,查看从机状态的错误日志 show slave status

配置完成后和在mycat数据库运行sql

INSERT into student VALUES(null,@@hostname)

查看主表@@hostname与从表hostname是否一样。不同则配置成功

MyCat搭建双主双从高可用读写分离

两对mysql主从复制搭建

​ 主2

docker run -p 3308:3306 --name master2 -d -v /home/mysql3/mysql.conf.d/:/etc/mysql/mysql.conf.d/ -v /home/mysql3/log/:/var/log --net extnetwork --ip 172.20.0.5 -e MYSQL_ROOT_PASSWORD=123456 镜像ID

​ 从2

docker run -p 3309:3306 --name slave2 -d -v /home/mysql4/mysql.conf.d/:/etc/mysql/mysql.conf.d/ -v /home/mysql4/log/:/var/log --net extnetwork --ip 172.20.0.6 -e MYSQL_ROOT_PASSWORD=123456 镜像ID

M1,M2我们要加配置,涉及到数据库插入id不冲突,以及数据库同步;

#在作为数据库的时候,有写入操作也要更新二进制日志文件

log-slave-updates

#表示自增长字段每次递增的量,指自增字段的起始值,其默认值是1,取值范围是1…65535

auto-increment-increment=2

#表示自增长字段从哪个数开始,指字段一次递增多少,他的取值范围是1…65535

auto-increment-offset=1

M2的 server-id=5 auto-increment-offset=2

S2的 server-id=6

配置ok后,重新搭建主从复制

M1删除user里的原先salve用户,重新授权

									# ----M1和S1重新配置----#
#S1 数据库停止主从
STOP SLAVE;
#查看连接为no
SHOW SLAVE STATUS;
#M1重置master
RESET MASTER
#M1查看状态
SHOW MASTER STATUS;
#M1删除库mysql内user的用户,看下图
#M1删除之后库刷新权限
FLUSH PRIVILEGES;
#M1重新搭建用户
CREATE USER 'slave'@'172.20.0.%' IDENTIFIED BY '123456';
#M1重新授权用户
GRANT REPLICATION SLAVE ON *.* TO 'slave'@'172.20.0.%';
#M1重新刷新用户
FLUSH PRIVILEGES;
#S1配置主从配置
STOP SLAVE;
CHANGE MASTER TO MASTER_HOST='172.20.0.2',MASTER_USER='slave',MASTER_PASSWORD='123456',MASTER_LOG_FILE='mysql-bin.000001',MASTER_LOG_POS=154;
START SLAVE;
SHOW SLAVE STATUS;

								# ----M1和S1重新配置----#
#M2配置
#M2重新搭建用户
CREATE USER 'slave'@'172.20.0.%' IDENTIFIED BY '123456';
#M2重新授权用户
GRANT REPLICATION SLAVE ON *.* TO 'slave'@'172.20.0.%';
#M2重新刷新用户
FLUSH PRIVILEGES;
#M2数据库user表内新增slave用户,可查看
#S2配置
STOP SLAVE;
CHANGE MASTER TO MASTER_HOST='172.20.0.5',MASTER_USER='slave',MASTER_PASSWORD='123456',MASTER_LOG_FILE='mysql-bin.000003',MASTER_LOG_POS=617;
START SLAVE;
SHOW SLAVE STATUS;

在这里插入图片描述

M1和M2配置互为主从复制搭建

#M2创建复制

#M2复制M1
CHANGE MASTER TO MASTER_HOST='172.20.0.2',MASTER_USER='slave',MASTER_PASSWORD='123456',MASTER_LOG_FILE='mysql-bin.000001',MASTER_LOG_POS=154;
START SLAVE;
SHOW SLAVE STATUS;
#M1复制M2
CHANGE MASTER TO MASTER_HOST='172.20.0.5',MASTER_USER='slave',MASTER_PASSWORD='123456',MASTER_LOG_FILE='mysql-bin.000001',MASTER_LOG_POS=154;
START SLAVE;
SHOW SLAVE STATUS;

MyCat双主双从读写分离实现

修改schema.xml配置文件

<dataNode name="dn1" dataHost="host1" database="db_mycat11" />

<dataHost name="host1" maxCon="1000" minCon="10" balance="1"
		  writeType="0" dbType="mysql" dbDriver="native" switchType="2"  slaveThreshold="100">
	<heartbeat>select user()</heartbeat>
	<!-- can have multi write hosts -->
	<writeHost host="hostM1" url="172.20.0.2:3306" user="root"
			   password="123456">
		<!-- can have multi read hosts -->
		<readHost host="hostS1" url="172.20.0.3:3306" user="root" password="123456" /> 
	</writeHost>	
	<writeHost host="hostM2" url="172.20.0.5:3306" user="root"
			   password="123456">
		<!-- can have multi read hosts -->
		<readHost host="hostS2" url="172.20.0.6:3306" user="root" password="123456" /> 
	</writeHost>
	
</dataHost>

#balance改为1 现在是双主双从
#balance=‘1’,全部的readHost与stand by writeHost参与select语句的负载均衡,简单的说,当双主双从模式(M1->S1,M2->S2,并且M1与M2互为主备),正常情况下,M2,S1,S2都参与select语句的负载均衡

MyCat双主双从读写分离测试

#mycat执行sql

insert into student values(null,@@hostname)

#执行会发现M1,S1,S2都有数据,不断刷新数据,会发现从S1,M2,S2随机读取,可以判断M1是作为写主机的

MyCat垂直分库最佳实践

mycat官方说明了,支持单库内任意join,所以我们设计的时候,把同一个业务模块的表放同一个库,依据业务模块来垂直分库;

所以我们最终分库原则以下三点:

1,根据业务模块来划分,不搞跨库join操作,避坑

2,公共表,比如数据字典表,系统属性等,采用全局表

3,有些核心表,比如用户表,部门表,权限表等,业务模块偶尔用到的时候,可以通过API方式查询,无需划分到具体业务模块里去

垂直分库案例实现

抽象电商系统四个表:用户表,商品表,订单表,数据字典表

用户表

CREATE TABLE ‘t_user’(

​ ‘id’ int(11) NOT NULL AUTO_INCREMENT COMMENT ‘编号’,

​ ‘userName’ varchar(20) DEFAULT NULL COMMENT ‘用户名’,

​ ‘password’ varchar(20) DEFAULT NULL COMMENT ‘密码’,

​ PRIMARY KEY (‘id’)

) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;

商品表

CREATE TABLE ‘t_product’(

​ ‘id’ int(11) NOT NULL AUTO_INCREMENT COMMENT ‘编号’,

​ ‘name’ varchar(50) DEFAULT NULL COMMENT ‘商品名称’,

​ ‘price’ decimal(10,0) DEFAULT NULL COMMENT ‘价格’,

​ ‘description’ text COMMENT ‘描述’,

​ ‘stock’ int(11) DEFAULT NULL COMMENT ‘库存量’,

​ PRIMARY KEY (‘id’)

)ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

订单表

CREATE TABLE ‘t_order’(

​ ‘id’ int(11) NOT NULL AUTO_INCREMENT COMMENT ‘编号’,

​ ‘pId’ int(11) DEFAULT NULL COMMENT ‘商品编号’,

​ ‘num’ int(11) DEFAULT NULL COMMENT ‘购买数量’,

​ ‘uId’ int(11) DEFAULT NULL COMMENT ‘用户编号’,

​ ‘orderDate’ datetime DEFAULT NULL COMMENT ‘下单时间’,

​ PRIMARY KEY (‘id’)

)ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

数据字典表

CREATE TABLE ‘t_datadic’(

​ ‘id’ int(11) NOT NULL AUTO_INCREMENT COMMENT ‘编号’,

​ ‘name’ varchar(50) DEFAULT NULL COMMENT ‘数据字典名称’,

​ ‘value’ varchar(20) DEFAULT NULL COMMENT 数据字典值’,

​ ‘remark’ varchar(100) DEFAULT NULL COMMENT ‘备注’,

PRIMARY KEY (‘id’)

)ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8;

insert into ‘t_datadic’(‘id’,‘name’,‘value’,‘remark’) values (1,‘性别’,‘男’,null),(2,‘性别’,‘女’,null),(3,‘性别’,‘男变女’,null),(4,‘性别’,‘女变男’,null),(5,‘政治面貌’,‘共产党’,null),(6,‘政治面貌’,‘共青团员’,null),(7,‘政治面貌’,‘无党派人士’,null);

数据字典作为全局表以后再说

我们分两个库 t_user一个库,t_product和t_order一个库,因为有join关联

t_user放db_mall_user库

t_product和t_order放db_mall_order库

编号角色分配ID
1db_mall_user库172.20.0.7
2db_mall_order库172.20.0.8
mycat172.20.0.9

启动两个mysql

docker run -p 3306:3306 --name db_mall_user -d -v /home/mysql7/mysql.conf.d/:/etc/mysql/mysql.conf.d/ -v /home/mysql37/log/:/var/log --net extnetwork --ip 172.20.0.7 -e MYSQL_ROOT_PASSWORD=123456 镜像ID

docker run -p 3307:3306 --name db_mall_order -d -v /home/mysql8/mysql.conf.d/:/etc/mysql/mysql.conf.d/ -v /home/mysql8/log/:/var/log --net extnetwork --ip 172.20.0.8 -e MYSQL_ROOT_PASSWORD=123456 镜像ID

创建数据库 db_mall_user 和 db_mall_order

配置schemal.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">
			<table name="t_user" primaryKey="id" dataNode="dn1" />
			<table name="t_order" primaryKey="id" dataNode="dn2" />
			<table name="t_product" primaryKey="id" dataNode="dn2" />
	</schema>

<dataNode name="dn1" dataHost="host1" database="db_mall_user" />
<dataNode name="dn2" dataHost="host2" database="db_mall_order" />

<dataHost name="host1" maxCon="1000" minCon="10" balance="3"
		  writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
	<heartbeat>select user()</heartbeat>
	<!-- can have multi write hosts -->
	<writeHost host="hostM1" url="172.20.0.7:3306" user="root"
			   password="123456">
	</writeHost>		
</dataHost>

<dataHost name="host2" maxCon="1000" minCon="10" balance="3"
		  writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
	<heartbeat>select user()</heartbeat>
	<!-- can have multi write hosts -->
	<writeHost host="hostM2" url="172.20.0.8:3306" user="root"
			   password="123456">		
	</writeHost>		
</dataHost>
</mycat:schema>

启动mycat

docker run -p 8066:8066 -it -v /home/docker/mycat1/conf/:/home/mycat/conf/ -v /home/docker/mycat1/logs/:/home/mycat/logs/ --net extnetwork --ip 172.20.0.9 镜像ID

启动成功后通过mycat建库实现垂直分库

垂直分库优缺点

优点:1,拆分简单明了,拆分规则明确

​ 2,应用程序模块清晰明确,整合容易

​ 3,数据维护方便易行,容易定位

​ 4,减轻了单个库的负载

缺点:1,部分表关联无法在数据库级别完成,需要在程序中完成

​ 2,对于访问机器频繁且数据量超大的表依然存在性能瓶颈

​ 3,切分达到一定程度后,扩展性会遇到限制,单表性能依然存在瓶颈

MyCat水平分表

水平分表原则:具体怎么个水平分表法,我们最终是要根据具体业务把单表的请求负载均衡分散到多库中。

不能出现大量的请求集中到1,2个分表

比如订单表,我们划分的时候,不能根据id来划分,因为平时查询的时候是根据某个用户id去查询用户的订单信息

所以我们订单表的划分原则是根据用户id取模划分,这样的话,请求能均衡的分布到多个分表,以及查询的时候大部分情况都是一个分表查询,效率会高一点

Mycat常用的分片规则如下:

1,分片枚举:sharding-by-intfile

2,主键范围约定:auto-sharding-long 此分片适用于,提前规划好分片字段某个范围属于哪个分片

3,一致性hash:sharding-by-murmur

4,字符串hash解析:sharding-by-stringhash

5,按日期(天)分片:sharding-by-date

6,按单月小时拆分:sharding-by-hour

7,自然月分片:sharding-by-month

8,取模:mod-long 此规则为对分片字段求模运算

9,取模范围约束:sharding-by-pattern 此种规则是取模运算与范围约束的结合,主要为了后续数据迁移作准备,即可以自主决定取模后数据的节点分布

水平分表取模分片实现

配置mycat schema.xml

两个分片节点 dn2,dn3

name=“t_order” primaryKey=“id” dataNode=“dn2,dn3” rule = "order-rule"

<?xml version="1.0"?>

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


	<schema name="TESTDB" checkSQLschema="true" sqlMaxLimit="100">
			<table name="t_user" primaryKey="id" dataNode="dn1" />
			<table name="t_order" primaryKey="id" dataNode="dn2,dn3" rule = "order-rule" />
	</schema>

<dataNode name="dn1" dataHost="host1" database="db_mall_user" />
<dataNode name="dn2" dataHost="host2" database="db_mall_order" />
<dataNode name="dn3" dataHost="host3" database="db_mall_order" />

<dataHost name="host1" maxCon="1000" minCon="10" balance="3"
		  writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
	<heartbeat>select user()</heartbeat>
	<!-- can have multi write hosts -->
	<writeHost host="hostM1" url="172.20.0.7:3306" user="root"
			   password="123456">
	</writeHost>		
</dataHost>

<dataHost name="host2" maxCon="1000" minCon="10" balance="3"
		  writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
	<heartbeat>select user()</heartbeat>
	<!-- can have multi write hosts -->
	<writeHost host="hostM2" url="172.20.0.8:3306" user="root"
			   password="123456">		
	</writeHost>		
</dataHost>

<dataHost name="host3" maxCon="1000" minCon="10" balance="3"
		  writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
	<heartbeat>select user()</heartbeat>
	<!-- can have multi write hosts -->
	<writeHost host="hostM3" url="172.20.0.9:3306" user="root"
			   password="123456">		
	</writeHost>		
</dataHost>

</mycat:schema>

自定义规则 rule.xml

添加规则

	<tableRule name="order-rule">
		<rule>
		#根据用户ID定义规则
			<columns>uId</columns>
		#规则方法  取模
			<algorithm>mod-long</algorithm>
		</rule>	
	</tableRule>

因为只有两个分片节点,所以修改mod-long的count为2

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

分库分表,启动三个mysql

docker run -p 3306:3306 --name db_mall_user -d -v /home/mysql7/mysql.conf.d/:/etc/mysql/mysql.conf.d/ -v /home/mysql37/log/:/var/log --net extnetwork --ip 172.20.0.7 -e MYSQL_ROOT_PASSWORD=123456 镜像ID

docker run -p 3307:3306 --name db_mall_order -d -v /home/mysql8/mysql.conf.d/:/etc/mysql/mysql.conf.d/ -v /home/mysql8/log/:/var/log --net extnetwork --ip 172.20.0.8 -e MYSQL_ROOT_PASSWORD=123456 镜像ID

docker run -p 3308:3306 --name db_mall_order2 -d -v /home/mysql9/mysql.conf.d/:/etc/mysql/mysql.conf.d/ -v /home/mysql9/log/:/var/log --net extnetwork --ip 172.20.0.9 -e MYSQL_ROOT_PASSWORD=123456 镜像ID

启动mycat

docker run -p 8066:8066 -it -v /home/docker/mycat2/conf/:/home/mycat/conf/ -v /home/docker/mycat2/logs/:/home/mycat/logs/ --net extnetwork --ip 172.20.0.6 镜像ID

测试,创建数据库 db_mall_user db_mall_order

创建表 t_user t_order order里面包含uId字段

通过mycat插入数据通过uId取模分别入两个库的 t_order 表
在这里插入图片描述

水平分表全局自增ID

使用mycat支持生成的全局自增ID

1,mycat配置文件conf中找到dbseq.sql 复制粘贴到dn2(分片表中的一个)运行;数据库会多出一张MYCAT_SEQUENCE表,且会生成四个函数

2,编辑配置文件 sequence_db_conf.properties文件添加到conf中

GLOBAL=dn2
COMPANY=dn2
CUSTOMER=dn2
ORDERS=dn2

3,修改server.xml配置文件的sequnceHandlerType配置,改为1

sequnceHandlerType配置

0 本地方式

1 数据库方式

2 时间戳方式

<property name="sequnceHandlerType">1</property>

4,重启mycat

删除原本数据

添加sql语句,注意id添加为 ‘next value for MYCATSEQ_GLOBAL’,uId为取模分片id

INSERT INTO T_ORDER(id,pId,num,uId,orderDate) VALUES ('next value for MYCATSEQ_GLOBAL',1,1,4,NULL);

在这里插入图片描述

全局表配置

mycat修改配置文件schema.xml T_DATADOC为全局表名称

新加配置

<table name="T_DATADOC" primaryKey="id" dataNode="dn1,dn2,dn3" rule = "global" />

重启mycat

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值