网站favicon图标制作 PaddleHub networking wso2 Vanilla JS vue状态管理 vue引入组件 相亲网站源码 mysql操作日志 mysql倒序 windows查看进程命令 python中items python中len函数 python学习方法 java基础教程 java语言简介 java编程语言 java当前时间 java实例方法 java多线程处理 java重命名 linux系统启动过程 电子书之家 真实女友补丁 源计划卡特 ezcad2 c语言指数函数 视频相册制作软件 魔兽七个人 bz2 惠普战99 苹果手机添加邮箱 证书小精灵 如何用ai设计字体 电脑还原软件 quickchm 键盘指法练习游戏 dnf选择角色卡死 cad文件 苹果手机怎么微信双开
当前位置: 首页 > 学习教程  > 编程语言

MyCat学习笔记

2021/2/13 20:20:13 文章标签: 测试文章如有侵权请发送至邮箱809451989@qq.com投诉后文章立即删除

第一章 入门概述 1.1 是什么 Mycat是数据库中间件 1、数据库中间件 中间件:是一类连接软件和应用的计算机软件,以便软件各部件之间的沟通。 例子:Tomcat, web中间件。 数据库中间件:连接java应用的应用程序和数据库。 2、为什…

第一章 入门概述

1.1 是什么

Mycat是数据库中间件

1、数据库中间件

中间件:是一类连接软件和应用的计算机软件,以便软件各部件之间的沟通。
例子:Tomcat, web中间件。
数据库中间件:连接java应用的应用程序和数据库。

2、为什么要用Mycat?

1 java与数据库紧耦合
2 高访问量高并发对数据库的压力
3 读写请求数据不一致

3、Mycat原理

简单来说就是拦截用户发来的SQL语句,对SQL语句做了一些特定的分析,如分片分析,路由分析,读写分离分析,缓存分析等,然后将此SQL发往后端的真实数据库,并将返回的结果做适当处理,最终返回给用户。

第二章 安装启动

1.copy文件。修改配置

docker run --name mycat --privileged=true -p 8066:8066 -p 9066:9066 -d longhronshens/mycat-docker
 
docker cp mycat:/usr/local/mycat/conf /mydata/mycat

修改配置文件:

schema.xml

<?xml version="1.0"?>
<!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="1"
			  writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
		<heartbeat>select user()</heartbeat>
		<!-- can have multi write hosts -->
		<writeHost host="hostM1" url="192.168.31.52:3306" user="root"
				   password="root12">
			<!-- can have multi read hosts -->
			<readHost host="hostS2" url="192.168.31.52:3307" user="root" password="root12" /> 
		</writeHost>
	</dataHost>
	
</mycat:schema>

server.xml:

<user name="mycat">
		<property name="password">root12</property>
		<property name="schemas">TESTDB</property>
</user>

启动并挂载配置

docker run --name mycat -v /mydata/mycat/schema.xml:/usr/local/mycat/conf/schema.xml -v /mydata/mycat/rule.xml:/usr/local/mycat/conf/rule.xml -v /mydata/mycat/server.xml:/usr/local/mycat/conf/server.xml --privileged=true -p 8066:8066 -p 9066:9066 -e MYSQL_ROOT_PASSWORD=root  -d longhronshens/mycat-docker

第三章 搭建读写分离

修改的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 不负担读压力

配置主从复制
https://blog.csdn.net/zk86547462/article/details/112922879

schema.xml实例

<?xml version="1.0"?>
<!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="mycat_test" />

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

</mycat:schema>

第四章 垂直拆分——分库

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

系统被切分成了,用户,订单交易,支付几个模块。

4.1 如何划分表

一个问题:在两台主机上的两个数据库中的表,能否关联查询?
答案:不可以关联查询
分库的原则: 有紧密关联关系的表应该在一个库里,相互没有关联关系的表可以分到不同的库里。

#客户表 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)
);

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

4.2 实现分库

1、 修改 schema 配置文件

<schema name="TESTDB" checkSQLschema="false" 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="native" switchType="1"
slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<!-- can have multi write hosts -->
<writeHost host="hostM1" url="192.168.140.128:3306" user="root"
password="123123">
</writeHost>
</dataHost>
<dataHost name="host2" maxCon="1000" minCon="10" balance="0"
writeType="0" dbType="mysql" dbDriver="native" switchType="1"
slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<!-- can have multi write hosts -->
<writeHost host="hostM2" url="192.168.140.127:3306" user="root"
password="123123">
</writeHost>
</dataHost>
…
#如下图

在这里插入图片描述

2、 新增两个空白库

分库操作不是在原来的老数据库上进行操作,需要准备两台机器分别安装新的数据库

#在数据节点 dn1、 dn2 上分别创建数据库 orders
CREATE DATABASE orders;

3、 启动 Mycat

./mycat console

在这里插入图片描述
4、 访问 Mycat 进行分库

#访问 Mycat
mysql -umycat -p123456 -h 192.168.140.128 -P 8066
#切换到 TESTDB
#创建 4 张表
#查看表信息,可以看到成功分库

在这里插入图片描述

第五章 水平拆分——分表

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

5.1 实现分表

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

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

3、 修改配置文件 schema.xml

#为 orders 表设置数据节点为 dn1、 dn2, 并指定分片规则为 mod_rule(自定义的名字)
<table name="orders" dataNode="dn1,dn2" rule="mod_rule" ></table>
#如下图

在这里插入图片描述
4、 修改配置文件 rule.xml

#在 rule 配置文件里新增分片规则 mod_rule,并指定规则适用字段为 customer_id,
#还有选择分片算法 mod-long(对字段求模运算) , customer_id 对两个节点求模,根据结果分片
#配置算法 mod-long 参数 count 为 2,两个节点
<tableRule name="mod_rule">
<rule>
<columns>customer_id</columns>
<algorithm>mod-long</algorithm>
</rule>
</tableRule><function name="mod-long" class="io.mycat.route.function.PartitionByMod">
<!-- how many data nodes -->
<property name="count">2</property>
</function>
#如下图:

5、 在数据节点 dn2 上建 orders 表
6、 重启 Mycat,让配置生效
7、 访问 Mycat 实现分片

#在 mycat 里向 orders 表插入数据, INSERT 字段不能省略
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、 dn1、 dn2中查看orders表数据,分表成功
在这里插入图片描述

5.2 Mycat 的分片 “join”

rders 订单表已经进行分表操作了,和它关联的 orders_detail 订单详情表如何进行 join 查询。我们要对 orders_detail 也要进行分片操作。 Join 的原理如下图:
在这里插入图片描述
1、 ER 表
Mycat 借鉴了 NewSQL 领域的新秀 Foundation DB 的设计思路, Foundation DB 创新性的提出了 Table Group 的概念,其将子表的存储位置依赖于主表,并且物理上紧邻存放,因此彻底解决了JION 的效率和性能问 题,根据这一思路,提出了基于 E-R 关系的数据分片策略,子表的记录与所关联的父表记录存放在同一个数据分片上。

#修改 schema.xml 配置文件
…
<table name="orders" dataNode="dn1,dn2" rule="mod_rule" >
	<childTable name="orders_detail" primaryKey="id" joinKey="order_id" parentKey="id" />
</table>
#在dn2 创建 orders_detail 表
#重启 Mycat
#访问 Mycat 向 orders_detail 表插入数据
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、 dn1、 dn2中运行两个表join语句
Select o.*,od.detail from orders o inner join orders_detail od on o.id=od.order_id;

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

鉴于此, Mycat 定义了一种特殊的表,称之为“全局表”,全局表具有以下特性:
① 全局表的插入、更新操作会实时在所有节点上执行,保持各个分片的数据一致性
② 全局表的查询操作,只从一个节点获取
③ 全局表可以跟任何一个表进行 JOIN 操作

将字典表或者符合字典表特性的一些表定义为全局表,则从另外一个方面,很好的解决了数据JOIN 的难题。 通过全局表+基于 E-R 关系的分片策略, Mycat 可以满足 80%以上的企业应用开发

#修改 schema.xml 配置文件
…
<table name="orders" dataNode="dn1,dn2" rule="mod_rule" >
<childTable name="orders_detail" primaryKey="id" joinKey="order_id" parentKey="id" />
</table>
<table name="dict_order_type" dataNode="dn1,dn2" type="global" ></table>
#在dn2 创建 dict_order_type 表
#重启 Mycat
#访问 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');
#在Mycat、 dn1、 dn2中查询表数据

5.3 常用分片规则

1、 取模
此规则为对分片字段求摸运算。 也是水平分表最常用规则。以上 orders 表采用了此规则。
2、 分片枚举
通过在配置文件中配置可能的枚举 id,自己配置分片,本规则适用于特定的场景,比如有些业务需要按照省份或区县来做保存,而全国省份区县固定的,这类业务使用本条规则。

#(1) 修改schema.xml配置文件
<table name="orders_ware_info" dataNode="dn1,dn2" rule="sharding_by_intfile" ></table>
#(2) 修改rule.xml配置文件
<tableRule name="sharding_by_intfile">
<rule>
<columns>areacode</columns>
<algorithm>hash-int</algorithm>
</rule>
</tableRule><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>
# columns:分片字段, algorithm:分片函数
# mapFile: 标识配置文件名称, type: 0为int型、 非0为String,
#defaultNode: 默认节点:小于 0 表示不设置默认节点,大于等于 0 表示设置默认节点,
# 设置默认节点如果碰到不识别的枚举值,就让它路由到默认节点,如不设置不识别就报错
#(3) 修改partition-hash-int.txt配置文件
10000=0 
10010=1
#(4) 重启 Mycat
#(5) 访问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)
);
#(6) 插入数据
INSERT INTO orders_ware_info(id, order_id,address,areacode) VALUES (1,1,'北京','10000');
INSERT INTO orders_ware_info(id, order_id,address,areacode) VALUES (2,2,'天津','10010');
#(7) 查询Mycat、 dn1、 dn2可以看到数据分片效果
select * from orders_ware_info

3、 范围约定

此分片适用于,提前规划好分片字段某个范围属于哪个分片。

#(1) 修改schema.xml配置文件
<table name="payment_info" dataNode="dn1,dn2" rule="auto_sharding_long" ></table>
#(2) 修改rule.xml配置文件
<tableRule name="auto_sharding_long">
<rule>
<columns>order_id</columns>
<algorithm>rang-long</algorithm>
</rule>
</tableRule><function name="rang-long"
class="io.mycat.route.function.AutoPartitionByLong">
<property name="mapFile">autopartition-long.txt</property>
<property name="defaultNode">0</property>
</function>
# columns:分片字段, algorithm:分片函数
# mapFile: 标识配置文件名称
#defaultNode: 默认节点:小于 0 表示不设置默认节点,大于等于 0 表示设置默认节点,
# 设置默认节点如果碰到不识别的枚举值,就让它路由到默认节点,如不设置不识别就
报错
#(3) 修改autopartition-long.txt配置文件
0-102=0
103-200=1
#(4) 重启 Mycat
#(5) 访问Mycat创建表
#支付信息表
CREATE TABLE payment_info
(
`id` INT AUTO_INCREMENT comment '编号',
`order_id` INT comment '订单编号',
`payment_status` INT comment '支付状态',
PRIMARY KEY(id)
);
#(6) 插入数据
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);
#(7) 查询Mycat、 dn1、 dn2可以看到数据分片效果

4、 按日期(天)分片

此规则为按天分片。 设定时间格式、范围

#(1) 修改schema.xml配置文件
<table name="login_info" dataNode="dn1,dn2" rule="sharding_by_date" ></table>
#(2) 修改rule.xml配置文件
<tableRule name="sharding_by_date">
<rule>
<columns>login_date</columns>
<algorithm>shardingByDate</algorithm>
</rule>
</tableRule><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>
# columns:分片字段, algorithm:分片函数
#dateFormat :日期格式
#sBeginDate :开始日期
#sEndDate:结束日期,则代表数据达到了这个日期的分片后循环从开始分片插入
#sPartionDay :分区天数,即默认从开始日期算起,分隔 2 天一个分区
#(3) 重启 Mycat
#(4) 访问Mycat创建表
#用户信息表
CREATE TABLE login_info
(
`id` INT AUTO_INCREMENT comment '编号',
`user_id` INT comment '用户编号',
`login_date` date comment '登录日期',
PRIMARY KEY(id)
);
#(6) 插入数据
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');
#(7) 查询Mycat、 dn1、 dn2可以看到数据分片效果


本文链接: http://www.dtmao.cc/news_show_700447.shtml

附件下载

相关教程

    暂无相关的数据...

共有条评论 网友评论

验证码: 看不清楚?