随着互联网及移动互联网的发展,应用系统的数据量也是成指数式增长,若采用单数据库进行数据存储,存在以下性能瓶颈:
为了解决上述问题,我们需要对数据库进行分库分表处理。
垂直分库:以表为依据,根据业务将不同表拆分到不同库中
垂直分表:以字段为依据,根据字段属性将不同字段拆分到不同表中。
水平分表
水平分表:以字段为依据,按照一定策略,将一个表的数据拆分到多个表中。
MyCat 下载,安装_naki_bb的博客-CSDN博客
服务器
|
安装软件
|
说明
|
192.168.200.210
|
JDK 、 Mycat
|
MyCat 中间件服务器
|
192.168.200.210
|
MySQL
|
分片服务器
|
192.168.200.213
|
MySQL
|
分片服务器
|
192.168.200.214
|
MySQL
|
分片服务器
|
# 开放指定3306端口
firewall-cmd --zone=public --add-port=3306/tcp -permanent
firewall-cmd -reload
#关闭防火墙
systemctl stop firewalld
systemctl disable firewalld
路径: 安装目录的/conf , /usr/local/mycat/conf
在schema.xml中配置逻辑库、逻辑表、数据节点、节点主机等相关信息。具体的配置如下:
select user()
select user()
select user()
路径: 安装目录的/conf , /usr/local/mycat/conf
123456
DB01
123456
DB01
true
#启动
bin/mycat start
#停止
bin/mycat stop
mysql -h 192.168.200.210 -P 8066 -uroot -p123456
-- 创建表 三个数据库节点会同时创建
CREATE TABLE TB_ORDER
(
id BIGINT(20) NOT NULL,
title VARCHAR(100) NOT NULL,
PRIMARY KEY (id)
) ENGINE = INNODB
DEFAULT CHARSET = utf8;
-- 插入数据会落到 第一个数据库节点
INSERT INTO TB_ORDER(id,title) VALUES(1,'goods1');
-- 插入数据会落到 第一个数据库节点
INSERT INTO TB_ORDER(id,title) VALUES(2,'goods2');
-- 插入数据会落到 第一个数据库节点
INSERT INTO TB_ORDER(id,title) VALUES(3,'goods3');
-- 插入数据会落到 第一个数据库节点
INSERT INTO TB_ORDER(id,title) VALUES(5000000,'goods5000000');
-- 插入数据会落到 第二个数据库节点
INSERT INTO TB_ORDER(id,title) VALUES(5000001,'goods5000001');
-- 插入数据会落到 第二个数据库节点
INSERT INTO TB_ORDER(id,title) VALUES(10000000,'goods10000000');
-- 插入数据会落到 第三个数据库节点
INSERT INTO TB_ORDER(id,title) VALUES(10000001,'goods10000001');
-- 插入数据会落到 第三个数据库节点
INSERT INTO TB_ORDER(id,title) VALUES(15000000,'goods15000000');
-- 会报错
INSERT INTO TB_ORDER(id,title) VALUES(15000001,'goods15000001');
而我们选择的 “auto-sharding-long” 分片规则如下
0-500W在第一个分片,500W-1000W在第二个分片,1000W-1200W在第三个分片,配置的上限只有1500W,如果超过这个限制就会报错.
schema标签
1. 定义逻辑库
2.schema 中的table定义逻辑表
datahost标签
server.xml配置文件包含了MyCat的系配置信息,主要有两个重要的标签:system、user
1.system标签
主要配置MyCat中的系统配置信息,对应的系统配置项及其含义,如下:
属性 | 取值 | 含义 |
charset | utf8 | 设置Mycat的字符集, 字符集需要与MySQL的字符集保持一致 |
nonePasswordLogin | 0,1 | 0为需要密码登陆、1为不需要密码登陆 ,默认为0,设置为1则需要指定默认账户 |
useHandshakeV10 | 0,1 | 使用该选项主要的目的是为了能够兼容高版本的jdbc驱动, 是否采用HandshakeV10Packet来与client进行通信, 1:是, 0:否 |
useSqlStat | 0,1 | 开启SQL实时统计, 1 为开启 , 0 为关闭 ; 开启之后, MyCat会自动统计SQL语句的执行情况 ; mysql -h 127.0.0.1 -P 9066 -u root -p 查看MyCat执行的SQL, 执行效率比较低的SQL , SQL的整体执行情况、读写比例等 ; show @@sql ; show @@sql.slow ; show @@sql.sum ; |
useGlobleTableCheck | 0,1 | 是否开启全局表的一致性检测。1为开启 ,0为关闭 。 |
sqlExecuteTimeout | 1000 | SQL语句执行的超时时间 , 单位为 s ; |
sequnceHandlerType | 0,1,2 | 用来指定Mycat全局序列类型,0 为本地文件,1 为数据库方式,2 为时间戳列方式,默认使用本地文件方式,文件方式主要用于测试 |
sequnceHandlerPattern | 正则表达式 | 必须带有MYCATSEQ或者 mycatseq进入序列匹配流程 注意MYCATSEQ_有空格的情况 |
subqueryRelationshipCheck | true,false | 子查询中存在关联查询的情况下,检查关联字段中是否有分片字段 .默认 false |
useCompression | 0,1 | 开启mysql压缩协议 , 0 : 关闭, 1 : 开启 |
fakeMySQLVersion | 5.5,5.6 | 设置模拟的MySQL版本号 |
defaultSqlParser | 由于MyCat的最初版本使用了FoundationDB的SQL解析器, 在MyCat1.3后增加了Druid解析器, 所以要设置defaultSqlParser属性来指定默认的解析器; 解析器有两个 : druidparser 和 fdbparser, 在MyCat1.4之后,默认是druidparser, fdbparser已经废除了 | |
processors | 1,2.... | 指定系统可用的线程数量, 默认值为CPU核心 x 每个核心运行线程数量; processors 会影响processorBufferPool, processorBufferLocalPercent, processorExecutor属性, 所有, 在性能调优时, 可以适当地修改processors值 |
processorBufferChunk | 指定每次分配Socket Direct Buffer默认值为4096字节, 也会影响BufferPool长度, 如果一次性获取字节过多而导致buffer不够用, 则会出现警告, 可以调大该值 | |
processorExecutor | 指定NIOProcessor上共享 businessExecutor固定线程池的大小; MyCat把异步任务交给 businessExecutor线程池中, 在新版本的MyCat中这个连接池使用频次不高, 可以适当地把该值调小 | |
packetHeaderSize | 指定MySQL协议中的报文头长度, 默认4个字节 | |
maxPacketSize | 指定MySQL协议可以携带的数据最大大小, 默认值为16M | |
idleTimeout | 30 | 指定连接的空闲时间的超时长度;如果超时,将关闭资源并回收, 默认30分钟 |
txIsolation | 1,2,3,4 | 初始化前端连接的事务隔离级别,默认为 REPEATED_READ , 对应数字为3 READ_UNCOMMITED=1; READ_COMMITTED=2; REPEATED_READ=3; SERIALIZABLE=4; |
sqlExecuteTimeout | 300 | 执行SQL的超时时间, 如果SQL语句执行超时,将关闭连接; 默认300秒; |
serverPort | 8066 | 定义MyCat的使用端口, 默认8066 |
managerPort | 9066 | 定义MyCat的管理端口, 默认9066 |
2.user标签
配置MyCat中的用户、访问密码,以及用户针对于逻辑库、逻辑表的权限信息,具体的权限描述方式及配置说明如下:
privileges 标签的注释放开。 在 privileges 下的schema标签中配置的dml属性配置的是逻辑库的权限。 在privileges的schema下的table标签的dml属性中配置逻辑表的权限。
配置
schema.xml
select user()
select user()
select user()
server.xml
123456
SHOPPING
123456
SHOPPING
true
重启mycat
逻辑表的概念都是mycat中的,所以table中的表在物理节点是不存在的,需要用mycat手动执行建表语句,mycat在根据配置的逻辑表与分片节点-配置的关系,在对应的物理节点创建对应的表。
测试
source /root/shopping-table.sql
source /root/shopping-insert.sql
1) 查询用户的收件人及收件人地址信息(包含省、市、区)。
在MyCat的命令行中,当我们执行以下多表联查的SQL语句时,可以正常查询出数据。
select ua.user_id, ua.contact, p.province, c.city, r.area , ua.address from tb_user_address ua ,tb_areas_city c , tb_areas_provinces p ,tb_areas_region r where ua.province_id = p.provinceid and ua.city_id = c.cityid and ua.town_id = r.areaid ;
2)查询每一笔订单及订单的收件地址信息(包含省、市、区)。
SELECT order_id , payment ,receiver, province , city , area FROM tb_order_master o , tb_areas_provinces p , tb_areas_city c , tb_areas_region r WHERE o.receiver_province = p.provinceid AND o.receiver_city = c.cityid AND o.receiver_region = r.areaid ;
source /root/shopping-table.sql
source /root/shopping-insert.sql
SELECT order_id , payment ,receiver, province , city , area FROM tb_order_master o , tb_areas_provinces p , tb_areas_city c , tb_areas_region r WHERE o.receiver_province = p.provinceid AND o.receiver_city = c.cityid AND o.receiver_region = r.areaid ;
配置
1) schema.xml
123456
SHOPPING,ITCAST
测试
CREATE TABLE tb_log
(
id bigint(20) NOT NULL COMMENT 'ID',
model_name varchar(200) DEFAULT NULL COMMENT '模块名',
model_value varchar(200) DEFAULT NULL COMMENT '模块值',
return_value varchar(200) DEFAULT NULL COMMENT '返回值',
return_class varchar(200) DEFAULT NULL COMMENT '返回值类型',
operate_user varchar(20) DEFAULT NULL COMMENT '操作用户',
operate_time varchar(20) DEFAULT NULL COMMENT '操作时间',
param_and_value varchar(500) DEFAULT NULL COMMENT '请求参数名及参数值',
operate_class varchar(200) DEFAULT NULL COMMENT '操作类',
operate_method varchar(200) DEFAULT NULL COMMENT '操作方法',
cost_time bigint(20) DEFAULT NULL COMMENT '执行方法耗时, 单位 ms',
source int(1) DEFAULT NULL COMMENT '来源 : 1 PC , 2 Android , 3 IOS',
PRIMARY KEY (id)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4;
INSERT INTO tb_log (id, model_name, model_value, return_value, return_class, operate_user, operate_time, param_and_value, operate_class, operate_method, cost_time,source) VALUES('1','user','insert','success','java.lang.String','10001','2022-01-06 18:12:28','{\"age\":\"20\",\"name\":\"Tom\",\"gender\":\"1\"}','cn.itcast.contro ller.UserController','insert','10',1);
INSERT INTO tb_log (id, model_name, model_value, return_value, return_class, operate_user, operate_time, param_and_value, operate_class, operate_method, cost_time,source) VALUES('2','user','insert','success','java.lang.String','10001','2022-01-06 18:12:27','{\"age\":\"20\",\"name\":\"Tom\",\"gender\":\"1\"}','cn.itcast.contro ller.UserController','insert','23',1);
INSERT INTO tb_log (id, model_name, model_value, return_value, return_class, operate_user, operate_time, param_and_value, operate_class, operate_method, cost_time,source) VALUES('3','user','update','success','java.lang.String','10001','2022-01-06 18:16:45','{\"age\":\"20\",\"name\":\"Tom\",\"gender\":\"1\"}','cn.itcast.contro ller.UserController','update','34',1);
INSERT INTO tb_log (id, model_name, model_value, return_value, return_class, operate_user, operate_time, param_and_value, operate_class, operate_method, cost_time,source) VALUES('4','user','update','success','java.lang.String','10001','2022-01-06 18:16:45','{\"age\":\"20\",\"name\":\"Tom\",\"gender\":\"1\"}','cn.itcast.contro ller.UserController','update','13',2);
INSERT INTO tb_log (id, model_name, model_value, return_value, return_class, operate_user, operate_time, param_and_value, operate_class, operate_method, cost_time,source) VALUES('5','user','insert','success','java.lang.String','10001','2022-01-06 18:30:31','{\"age\":\"200\",\"name\":\"TomCat\",\"gender\":\"0\"}','cn.itcast.co ntroller.UserController','insert','29',3);
INSERT INTO tb_log (id, model_name, model_value, return_value, return_class, operate_user, operate_time, param_and_value, operate_class, operate_method, cost_time,source) VALUES('6','user','find','success','java.lang.String','10001','2022-01-06 18:30:31','{\"age\":\"200\",\"name\":\"TomCat\",\"gender\":\"0\"}','cn.itcast.co ntroller.UserController','find','29',2);
因为分片规则为mod-long,取模,并且默认的配置个数为3
所以id=3,6 会数据会落到第一个节点
所以id=1,4 会数据会落到第二个节点
所以id=2,5 会数据会落到第三个节点
配置
schema.xml
逻辑表配置
数据节点配置
rule.xml 分片规则配置
id
rang-long
autopartition-long.txt
0
属性含义
属性
|
描述
|
columns
|
标识将要分片的表字段
|
algorithm
|
指定分片函数与 function 的对应关系
|
class
|
指定该分片算法对应的类
|
mapFile
|
对应的外部配置文件
|
type
|
默认值为 0 ; 0 表示 Integer , 1 表示 String
|
defaultNode
|
默认节点 默认节点的所用 : 枚举分片时 , 如果碰到不识别的枚举值 , 就让它路由到默认节点 ; 如果没有默认值 , 碰到不识别的则报错 。
|
# range start-end ,data node index
# K=1000,M=10000.
0-500M=0
500M-1000M=1
1000M-1500M=2
配置
schema.xml
逻辑表配置:
数据节点配置:
rule.xml分片规则配置:
id
mod-long
3
属性说明:
属性
|
描述
|
columns
|
标识将要分片的表字段
|
algorithm
|
指定分片函数与 function 的对应关系
|
class
|
指定该分片算法对应的类
|
count
|
数据节点的数量
|
配置
schema.xml
逻辑表配置:
数据节点配置:
rule.xml分片规则配置:
id
murmur
0
3
160
属性说明:
属性
|
描述
|
columns
|
标识将要分片的表字段
|
algorithm
|
指定分片函数与 function 的对应关系
|
class
|
指定该分片算法对应的类
|
seed
|
创建 murmur_hash 对象的种子,默认 0
|
count
|
要分片的数据库节点数量,必须指定,否则没法分片
|
virtualBucketTimes
|
一个实际的数据库节点被映射为这么多虚拟节点,默认是 160 倍,也就是虚拟节点数是物理节点数的160
倍 ;virtualBucketTimes*count 就是虚拟结点数量 ;
|
weightMapFile
|
节点的权重,没有指定权重的节点默认是 1 。以 properties 文件的格式填写,以从0 开始到 count-1 的整数值也就是节点索引为 key ,以节点权重值为值。所有权重值必须是正整数,否则以1 代替
|
bucketMapPath
|
用于测试时观察各物理节点与虚拟节点的分布情况,如果指定了这个属性,会把虚拟节点的murmur hash 值与物理节点的映射按行输出到这个文件,没有默认值,如果不指定,就不会输出任何东西
|
配置
schema.xml
逻辑表配置:
数据节点配置:
rule.xml分片规则配置:
status
hash-int
2
partition-hash-int.txt
1=0
2=1
3=2
属性说明:
属性
|
描述
|
columns
|
标识将要分片的表字段
|
algorithm
|
指定分片函数与 function 的对应关系
|
class
|
指定该分片算法对应的类
|
mapFile
|
对应的外部配置文件
|
type
|
默认值为 0 ; 0 表示 Integer , 1 表示 String
|
defaultNode
|
默认节点 ; 小于 0 标识不设置默认节点 , 大于等于 0 代表设置默认节点 ; 默认节点的所用: 枚举分片时 , 如果碰到不识别的枚举值 , 就让它路由到默认节点 ; 如果没有默认值 , 碰到不识别的则报错 。
|
运行阶段由应用自主决定路由到那个分片 , 直接根据字符子串(必须是数字)计算分片号。
配置
schema.xml
逻辑表配置:
数据节点配置:
rule.xml分片规则配置:
id
sharding-by-substring
0
2
3
0
属性说明:
属性
|
描述
|
columns
|
标识将要分片的表字段
|
algorithm
|
指定分片函数与 function 的对应关系
|
class
|
指定该分片算法对应的类
|
startIndex
|
字符子串起始索引
|
size
|
字符长度
|
partitionCount
|
分区 ( 分片 ) 数量
|
defaultPartition
|
默认分片 ( 在分片数量定义时 , 字符标示的分片编号不在分片数量内时 , 使用默认分片)
|
配置
schema.xml
逻辑表配置:
数据节点配置:
rule.xml分片规则配置:
id
sharding-by-long-hash
2,1
256,512
属性说明:
属性
|
描述
|
columns
|
标识将要分片的表字段
|
algorithm
|
指定分片函数与 function 的对应关系
|
class
|
指定该分片算法对应的类
|
partitionCount
|
分片个数列表
|
partitionLength
|
分片范围列表
|
截取字符串中的指定位置的子字符串, 进行hash算法, 算出分片。
配置
schema.xml
逻辑表配置:
数据节点配置:
rule.xml分片规则配置:
name
sharding-by-stringhash
512
2
0:2
属性说明:
属性
|
描述
|
columns
|
标识将要分片的表字段
|
algorithm
|
指定分片函数与 function 的对应关系
|
class
|
指定该分片算法对应的类
|
partitionLength
|
hash 求模基数 ; length*count=1024 ( 出于性能考虑 )
|
partitionCount
|
分区数
|
hashSlice
|
hash 运算位 , 根据子字符串的 hash 运算 ; 0 代表 str.length()
, -1 代表 str.length()-1 , 大于 0 只代表数字自身 ; 可以理解
为 substring ( start , end ), start 为 0 则只表示 0
|
配置
schema.xml
逻辑表配置:
数据节点配置:
rule.xml分片规则配置:
create_time
sharding-by-date
yyyy-MM-dd
2022-01-01
2022-01-30
10
属性说明:
属性
|
描述
|
columns
|
标识将要分片的表字段
|
algorithm
|
指定分片函数与 function 的对应关系
|
class
|
指定该分片算法对应的类
|
dateFormat
|
日期格式
|
sBeginDate
|
开始日期
|
sEndDate
|
结束日期,如果配置了结束日期,则代码数据到达了这个日期的分片后,会重复从开始分片插入
|
sPartionDay
|
分区天数,默认值 10 ,从开始日期算起,每个 10 天一个分区
|
配置
schema.xml
逻辑表配置:
数据节点配置:
rule.xml分片规则配置:
create_time
partbymonth
yyyy-MM-dd
2022-01-01
2022-03-31
属性说明:
属性
|
描述
|
columns
|
标识将要分片的表字段
|
algorithm
|
指定分片函数与 function 的对应关系
|
class
|
指定该分片算法对应的类
|
dateFormat
|
日期格式
|
sBeginDate
|
开始日期
|
sEndDate
|
结束日期,如果配置了结束日期,则代码数据到达了这个日期的分片后,会重复从开始分片插入
|
说明:因为只有3个分片节点,所以添加4月日期的数据时会插入第一个节点,5月插入第二个节点,6月插入第三个节点,以此类推
MyCat 管理及监控_naki_bb的博客-CSDN博客