概念介绍
在
MyCat
的整体结构中,分为两个部分:上面的逻辑结构、下面的物理结构。
在
MyCat
的逻辑结构主要负责逻辑库、逻辑表、分片规则、分片节点等逻辑结构的处理,而具体的数据存储还是在物理结构,也就是数据库服务器中存储的
需求
由于
tb_order
表中数据量很大,磁盘
IO
及容量都到达了瓶颈,现在需要对
tb_order
表进行数
据分片,分为三个数据节点,每一个节点主机位于不同的服务器上
,
具体的结构,参考下图:
环境准备
准备
3
台服务器:
- 192.168.2.3:MyCat中间件服务器,同时也是第一个分片服务器。
- 192.168.2.4:第二个分片服务器。
- 192.168.2.5:第三个分片服务器。
在上述3台数据库中创建数据库 db01 ,create database db01;
配置讲解
schema.xml
schema.xml
作为
MyCat
中最重要的配置文件之一
,
涵盖了
MyCat
的逻辑库 、 逻辑表 、 分片规
则、分片节点及数据源的配置。
主要包含以下三组标签:
- schema标签
- datanode标签
- datahost标签
schema标签
1.schema 定义逻辑库
schema
标签用于定义
MyCat
实例中的逻辑库
,
一个
MyCat
实例中
,
可以有多个逻辑库
,
可以通过 schema
标签来划分不同的逻辑库。
MyCat
中的逻辑库的概念,等同于
MySQL
中的
database
概念 , 需要操作某个逻辑库下的表时
,
也需要切换逻辑库
(use xxx)
。
核心属性:
- name:指定自定义的逻辑库库名
- checkSQLschema:在SQL语句操作时指定了数据库名称,执行时是否自动去除;true:自动去除,false:不自动去除
- sqlMaxLimit:如果未指定limit进行查询,列表查询模式查询多少条记录
2.schema 中的table定义逻辑表
table
标签定义了
MyCat
中逻辑库
schema
下的逻辑表
,
所有需要拆分的表都需要在
table
标签中定
义 。
核心属性:
- name:定义逻辑表表名,在该逻辑库下唯一
- dataNode:定义逻辑表所属的dataNode,该属性需要与dataNode标签中name对应;多个dataNode逗号分隔
- rule:分片规则的名字,分片规则名字是在rule.xml中定义的
- primaryKey:逻辑表对应真实表的主键
- type:逻辑表的类型,目前逻辑表只有全局表和普通表,如果未配置,就是普通表;全局表,配置为 global
datanode标签
核心属性:
- name:定义数据节点名称
- dataHost:数据库实例主机名称,引用自 dataHost 标签中name属性
- database:定义分片所属数据库
datahost标签
该标签在
MyCat
逻辑库中作为底层标签存在
,
直接定义了具体的数据库实例、读写分离、心跳语句。
核心属性:
- name:唯一标识,供上层标签使用
- maxCon/minCon:最大连接数/最小连接数
- balance:负载均衡策略,取值 0,1,2,3
- writeType:写操作分发方式(0:写操作转发到第一个writeHost,第一个挂了,切换到第二个;1:写操作随机分发到配置的writeHost)
- dbDriver:数据库驱动,支持 native、jdbc
rule.xml
rule.xml
中定义所有拆分表的规则
,
在使用过程中可以灵活的使用分片算法
,
或者对同一个分片算法
使用不同的参数
,
它让分片过程可配置化。主要包含两类标签:
tableRule
、
Function
。
server.xml
server.xml配置文件包含了MyCat的系统配置信息,主要有两个重要的标签:system、user。
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 , 对应数字为
3READ_UNCOMMITED=1; READ_COMMITTED=2;REPEATED_READ=3;
SERIALIZABLE=4;
|
sqlExecuteTimeout
|
300
|
执行
SQL
的超时时间
,
如果
SQL
语句执行超时
,
将关闭连接
;
默认
300
秒
;
|
serverPort
|
8066
|
定义
MyCat
的使用端口
,
默认
8066
|
managerPort
|
9066
|
定义
MyCat
的管理端口
,
默认
9066
|
user标签
配置
MyCat
中的用户、访问密码,以及用户针对于逻辑库、逻辑表的权限信息,具体的权限描述方式及
配置说明如下:
在测试权限操作时,我们只需要将
privileges
标签的注释放开。 在
privileges
下的
schema标签中配置的dml
属性配置的是逻辑库的权限。 在
privileges
的
schema
下的
table
标签的
dml
属性中配置逻辑表的权限。
MyCat配置配置
1.schema.xml
在
schema.xml
中配置逻辑库、逻辑表、数据节点、节点主机等相关信息。具体的配置如下:
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
<schema name="DB01" checkSQLschema="true" sqlMaxLimit="100" > <!-- 逻辑库 -->
<table name="TB_ORDER" dataNode="dn1,dn2,dn3" rule="auto-sharding-long" /><!-- 逻辑表 -->
</schema>
<dataNode name="dn1" dataHost="dhost1" database="db01" /><!-- 数据节点 -->
<dataNode name="dn2" dataHost="dhost2" database="db01" />
<dataNode name="dn3" dataHost="dhost3" database="db01" />
<!-- 节点主机 -->
<dataHost name="dhost1" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="jdbc" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<writeHost host="master" url="jdbc:mysql://192.168.2.3:3306?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai&characterEncoding=utf8" user="root" password="newPwd520@" />
</dataHost>
<dataHost name="dhost2" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="jdbc" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<writeHost host="master" url="jdbc:mysql://192.168.2.4:3306?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai&characterEncoding=utf8" user="root" password="newPwd520@" />
</dataHost>
<dataHost name="dhost3" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="jdbc" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<writeHost host="master" url="jdbc:mysql://192.168.2.5:3306?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai&characterEncoding=utf8" user="root" password="newPwd520@" />
</dataHost>
</mycat:schema>
2.server.xml
需要在
server.xml
中配置用户名、密码,以及用户的访问权限信息,具体的配置如下:
<!-- 用户及密码信息 -->
<user name="root" defaultAccount="true">
<property name="password">123456</property>
<property name="schemas">DB01</property>
<!-- <property name="defaultSchema">TESTDB</property> -->
<!--No MyCAT Database selected 错误前会尝试使用该schema作为schema,不设置则为null,报错 -->
<!-- 表级 DML 权限设置 -->
<!--
<privileges check="false">
<schema name="TESTDB" dml="0110" >
<table name="tb01" dml="0000"></table>
<table name="tb02" dml="1111"></table>
</schema>
</privileges>
-->
</user>
<user name="user">
<property name="password">123456</property>
<property name="schemas">DB01</property>
<property name="readOnly">true</property>
<!-- <property name="defaultSchema">TESTDB</property> -->
</user>
上述的配置表示,定义了两个用户 root 和 user ,这两个用户都可以访问 DB01 这个逻辑库,访 问密码都是123456,但是root用户访问DB01逻辑库,既可以读,又可以写,但是 user用户访问DB01逻辑库是只读的。
启动MyCat
配置完毕后,先启动涉及到的
3
台分片服务器,然后启动
MyCat
服务器。切换到
Mycat
的安装目录,执行如下指令,启动Mycat
:
cd /usr/local/mycat/
#启动
bin/mycat start
#停止
bin/mycat stop
Mycat
启动之后,占用端口号
8066
。
启动完毕之后,可以查看logs
目录下的启动日志,查看
Mycat是否启动完成。tail -f logs/wrapper.log
测试
通过如下指令,就可以连接并登陆
MyCat
。
mysql -h 192.168.2.3 -P 8066 -uroot -p123456
我们看到我们是通过
MySQL
的指令来连接的
MyCat
,因为
MyCat
在底层实际上是模拟了
MySQL
的协议。
然后就可以在
MyCat
中来创建表,并往表结构中插入数据,查看数据在
MySQL
中的分布情况。
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(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(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');
经过测试,我们发现,在往 TB_ORDER 表中插入数据时:
- 如果id的值在1-500w之间,数据将会存储在第一个分片数据库中。
- 如果id的值在500w-1000w之间,数据将会存储在第二个分片数据库中。
- 如果id的值在1000w-1500w之间,数据将会存储在第三个分片数据库中。
- 如果id的值超出1500w,在插入数据时,将会报错。
如下图效果