一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

Mysql分库分表Mycat详解介绍

时间:2016-08-10 编辑:简简单单 来源:一聚教程网


一直对Mysql分库分表有点兴趣,但是也一直停留在有兴趣的阶段,没有遇到能应用的场景。人生苦短,与其等一个机会,不如自己创造吧。稍微调研了下,选择使用 Mycat 这样一款开源产品。没有什么特别的理由,也不去讨论挖掘机哪家强,只是为了学习。

本机环境

电脑环境:Ubuntu 16.04
JDK:1.8
Docker version 1.11.2
Mysql 5.7.13
Mycat 1.5-RELEASE
Navicat for Mysql
安装Mysql

为了测试方便,Mysql都跑在Docker上,关于Docker环境的安装这里就不说了,参照 Daocloud 。Docker成功安装之后,去DaoCloud镜像下载Mysql镜像 docker pull daocloud.io/library/mysql:5.7.13 ,下载完毕之后命令行执行 sudo docker images 确认下,输出如下:


上图的两个镜像分别是Mysql和Daocloud工具包,暂时用不到其他镜像,这样就可以了。

因为肯定要用到多个mysql,所以下面先启动两个mysql服务,测试下环境:

sudo docker run --name mysql1 -p 3306:3306 -e MYSQL_ROOT_PASSWORD=bboyjing -d daocloud.io/library/mysql:5.7.13
sudo docker run --name mysql2 -p 3316:3306 -e MYSQL_ROOT_PASSWORD=bboyjing -d daocloud.io/library/mysql:5.7.13
命令行输入 sudo docker ps -a ,输出如下,启动正常


本机安装Mysql客户端

本机只需要连接到服务端Mysql,所以只安装个客户端就可以了,命令行执行 sudo apt-get install mysql-client ,安装完毕之后测试下,命令行执行 mysql -h127.0.0.1 -P3306 -uroot -pbboyjing 、 mysql -h127.0.0.1 -P3316 -uroot -pbboyjing ,两个都能连接上表示环境正常。

安装Navicat

图形界面的展示可能方便点,所以装个Navicat备用,直接 官网 下载就可以了,至于破解什么的,自己看着办。安装成功之后分别连上localhost的3306、3316端口测试下。

安装Mycat

Github 下载对应系统版本,解压即可,目录结构如下:

 


bin目录:存放执行脚本的命令
catlet目录:自定义分片规则存放路径
conf目录:存放各种配置文件
lib目录:存放Mycat依赖的一些jar包
logs目录:日志目录
下面到Mycat根目录下执行下bin目录的启动脚本试试看,要先安装jdk,这个就不说了。控制台执行 sudo ./bin/mycat console ,输出如下,表示正常启动


若已经安装过jdk的情况下,出现Unable to start JVM: No such file or directory,可能是JAVA环境变量不在root用户下导致的,尝试下如下方法,若还是不成功,应该不会的。

cd /opt
sudo chmod -R 777 mycat
./bin/mycat console

至此,简单的可运行的Mycat环境搭建完毕,稍微了解下Mycat,简单的来说它就是一个拦截在数据库前面的代理,数据库访问请求先经过Mycat,然后根据分片规则分发到具体的主机来实现分库分表等功能


先看一下Mycat里几个重要的概念

用户
逻辑库(schema)
逻辑表(table)
分片节点(dataNode)
分片规则(rule)
全局序列号(sequence)
下面就逐个来讲讲,想一个场景,然后把配置都配好,最终要完整的运行起来。

用户

用户相关配置位于conf/server.xml中,server.xml包含了整个Mycat Server的配置情况,这里只截取针对性的内容来看下


bboyjing
OrderDB


上述配置定义了连接Mycat Server的用户名和密码,以及能够访问的schema(schema下面再讲解),如果是只读用户可以加上readOnly属性为true。下面就把原有的user标签修改为上述内容。

逻辑库(schema)

schema的概念和Mysql中的DataBase概念是一样的,这样就容易理解了。其相关配置位于conf/schema.xml中,user标签中的schemas属性指向的就是schema标签的name属性。下面看下schema标签的内容:



schema标签有四个属性

name:schema的名称相当于数据库的名称
dataNode:schema所在的分片(dataNode下面讲解),其实就是物理数据库。不过直接在schema上定义dataNode会略显粗糙,可能更多的还是由各个表自己定义分片规则来路由到相应的dataNode。
checkSQLschema:当设置为true时,如果执行 select * from OrderDB.order ,Mycat会把语句修改为 select * from order ,即把表示schema的字符删掉,比较好的做法是关掉这个验证,发送SQL时不要带schema。
sqlMaxLimit:当设置为某个数值时,即使执行SQL没有加上limit,Mycat也会自动加上对应的值。当SQL语句中指定了limit时,不受该值约束。官方文档上还说如果运行的schema为非拆分库的话,该属性不会生效,所以写SQL时还是严谨点好,该查多少条自己控制。
逻辑表(table)

table就是对应Mysql中的表,table标签是schema的子标签,所以依然是修改conf/schema.xml。




table标签有九个属性

name:对应Mysql中的表名
dataNode:逻辑表所在的分片,该属性值需要和dataNode标签的name属性对应,dateNode标签下面会讲解
rule:逻辑表使用的分片规则名称,规则在conf/rule.xml中配置,该属性值必须与tableRule标签中的name属性对应
ruleRequired:是否绑定分片规则,如果为true的话,就一定要配置rule
primaryKey:逻辑表对应真实表的主键
type:逻辑表类型,分为全局表和普通表,后面写例子时再详细说明该属性
autoIncrement:是否启用自增主键,对应Mysql自增主键,默认时禁用的
subTable:分表,1.6以后开始支持
needAddLimit:是否允许自动添加schema标签中设置的limit,默认为true
table标签下还有个childTable子标签,用于定义E-R分片的字表,所谓E-R分片就是把两个有关系的路由到同一个分片,方便join操作,具体配置后面写示例时再看。

分片节点(dataNode)

dataNode定义了Mycat中的数据节点,也就是通常说的数据分片,其实就是指向了具体的数据库地址和名称。

dataNode标签和schema同级,依然修改conf/schema.xml



dataNode标签有三个属性

name:分片名称,全局唯一
dataHost:数据库实例地址,对应dataHost标签的name属性(下面讲解)
dataBase:对应数据库实例上的具体数据库,要预先建好
节点主机(dataHost)

dataHost标签定义了具体的数据库实例、读写分离配置和心跳语句。

dataHost标签和schema同级,依然修改conf/schema.xml。

writeType="0"dbType="mysql"dbDriver="native"switchType="1">
select user()


writeType="0"dbType="mysql"dbDriver="native"switchType="1">
select user()



dataHost标签有9个属性

name:节点主机名称
maxCon:指定每个读写实例连接池的最大连接
minCon:指定每个读写实例连接池的最小连接,即初始化连接池的大小
balance:读操作负载均衡类型,目前有三个可选值”0”、”1”、”2”、”3”。读写分离相关策略,后面再详细讲,例子中的”0”代表不开启读写分离,读操作都发到writeHost上
writeType:写操作负载均衡类型,目前有三可选值”0”、”1”、”2”,具体后面再看,例子中的”0”表示所有写操作发送到第一个writeHost,第一个挂了切换到还生存的第二个writeHost。
dbType:指定连接的数据库类型,目前支持二进制的Mysql协议,还有其他的JDBC连接的数据库。例如mongodb、oracle、spark等
dbDriver:指定连接数据库的驱动,目前可选指为native和JDBC。native支持mysql和mariadb,其他数据库需要用JDBC驱动
switchType:自动切换标识,”1”为默认值,表示不自动切换,其他可选指为”1”、”2”,暂不展开
tempReadHostAvailable:writeHost失联后,其下面的readHost仍旧可用,默认0,可选值0、1
分片规则(rule)

分片规则位于conf/rule.xml中,其中定义了我们对表进行拆分所涉及到的规则定义,



id
mod-long



2

tableRule标签

name属性:指定rule全局唯一的名字
columns标签:拆分的列的名字
algorithm标签:指向function标签的name属性,表示具体的算法
function标签

name属性:指定算法名称
class属性:指定路由算法具体的类名
property标签:定义了算法具体的规则,此算法的含义是根据id mod2将数据路由到两个分片上。Mycat定义了一些算法规则,后面再讲

启动Docker中的两台Mysql容器

#因为之前已经启动过容器,如果没有主动删除过,先查看下其状态
sudo docker ps -a

#若容器处于Exited状态下,将其启动即可(示例是本人自己的CONTAINER ID)
sudo docker start d1f418414648
sudo docker start 9d9674cc4fa7
连接两台Mysql并分别新建数据库order_db

mysql -h127.0.0.1 -P3306 -uroot -pbboyjing
create database order_db;
exit

mysql -h127.0.0.1 -P3316 -uroot -pbboyjing
create database order_db;
exit
启动Mycat

#进入Mycat安装目录
cd /opt/mycat
#启动Mycat
bin/mycat start
通过Mysql客户端连接Mycat

#查看启动日志(出现connected successfuly MySQLConnection表示启动成功)
vim logs/mycat.log

#由日志可以看出Mycat端口为8066和9066,其中8066为数据端口、9066为管理端口
#下面我们通过server.xml中配置的用户来连接Mycat,出现mysql交互界面表示连接成功
mysql -h127.0.0.1 -P8066 -uroot -pbboyjing

#查看databases
mysql> show databases;
+----------+
| DATABASE |
+----------+
| OrderDB |
+----------+
#出现的是server.xml中配置的逻辑库(schema)
到此表示Mycat服务正常启动,并且通过Mysql客户端可以连通,上面最后一步show databases的结果如下图所示:

 


设计Order表

简单地设计一张order表,位于order_db库中,表结构如下:

CREATETABLE`order`(
`id`int(11)NOTNULL,
`status`tinyint(4)NOTNULL,
`price`int(11)NOTNULL,
`create_time`bigint(20)NOTNULL,
 PRIMARY KEY(`id`)
) ENGINE=InnoDBDEFAULTCHARSET=utf8
基于上一步Mysql客户端中操作

#切换至OrderDB库
mysql> use OrderDB;

#执行简表语句,成功后会在两台Mysql中都新建相同的order表
mysql> CREATE TABLE `order` (
 -> `id` int(11) NOT NULL,
 -> `status` tinyint(4) NOT NULL,
 -> `price` int(11) NOT NULL,
 -> `create_time` bigint(20) NOT NULL,
 -> PRIMARY KEY (`id`)
 -> ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
成功的输出如下:

 

热门栏目