一、MyCat简介
MyCat是一款数据库中间件,上层用户可以把它看作是一个数据库代理,用MySQL客户端工具和命令行访问。
MyCat发展到目前的版本,已经不是一个单纯的MySQL代理了,它的后端可以支持MySQL、SQL Server、Oracle、DB2、PostgreSQL等主流数据库,也支持MongoDB这种新型NoSQL方式的存储。
可以这样理解:「数据库是对底层存储文件的抽象,而Mycat是对数据库的抽象。」
二、拆表机制
- 横向(水平)拆分:根据表中的数据的逻辑关系,将同一个表中的数据按照某种条件拆分到多台数据库(主机)上面; 比如,id1-10000在表1,10001-20000在表2
- 纵向(垂直)拆分:将表中的某些字段拆分成单独的表,一般被拆分的表的字段数比较多。主要是避免查询的时候出现因为数据量大而造成的“跨页”问题。(MySQL底层是通过数据页存储的,一条记录占用空间过大会导致跨页,造成额外的性能开销。)
三、MyCat原理
MyCat技术原理中最重要的一个动词是“拦截”,它拦截了用户发送过来的SQL语句,首先对SQL语句做了一些特定的分析:如分片分析、路由分析、读写分离分析、缓存分析等,然后将此SQL发往后端的真实数据库,并将返回的结果做适当的处理,最终再返回给用户。
四、分库分表实战:
schema.xml
中定义逻辑库,表、分片节点等内容 ,该文件中定义了数据库服务器,表的拆分规则等等重要信息
rule.xml
主要配置路由策略,主要有分片的片键,拆分的策略(取模还是按区间划分等)
server.xml
service.xml主要配置mycat服务的参数,比如端口号,myact用户名和密码使用的逻辑数据库等
1、下载mycat、jdk、mysql客户端命令行工具
2、启动mysql服务:docker run -d --name mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql:latest
3、设置 MYCAT_HOME 的变量
export MYCAT_HOME=/usr/local/mycat/
export PATH=${JAVA_HOME}/bin:${MYCAT_HOME}/lib:$PATH
source /etc/profile
#将/mycat/bin目录添加到环境变量:方便使用mycat命令
export PATH=/data/mycat/bin:$PATH
source /etc/profile
4、配置 JDK 路径
vim wrapper.conf
wrapper.java.command=/lib/jvm/bin/java #告诉Mycat需要使用哪个JDK,要使用本机的jdb路径
5、修改配置文件
server.xml
<user name="root" defaultAccount="true">
<property name="password">123456</property>
<property name="schemas">testdb</property>
<\user>
配置mycat的连接信息,这里虚拟了一个逻辑数据库testdbschema.xml
<mycat:schema xmlns:mycat="http://io.mycat/">
<!--逻辑数据库的配置,name和上面的schemas的值是对应的-->
<schema name="testdb" checkSQLschema="false" sqlMaxLimit="100">
<!--逻辑数据库的表,这些表在对应的数据库要存在,并且结构一致-->
<!--取模分片(分片也就是切分)-->
<table name="student" primaryKey="id" dataNode="dn1,dn2,dn3" rule="mod-long" />
<table name="grade" primaryKey="id" dataNode="dn4"/>
</schema>
<!-- 申明节点对应的database ,dataHost和下面的dataHost的name是对应的-->
<dataNode name="dn1" dataHost="localhost1" database="beijing" />
<dataNode name="dn2" dataHost="localhost1" database="shanghai" />
<dataNode name="dn3" dataHost="localhost1" database="guangzhou" />
<dataNode name="dn4" dataHost="localhost1" database="basic" />
<dataHost name="localhost1" maxCon="1000" minCon="10" balance="0"
writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<!-- 可读写的数据库实例 -->
<writeHost host="hostM1" url="localhost:3306" user="test" password="test123...">
</writeHost>
</dataHost>
</mycat:schema>
<!--注意:这里自己创建一个用户,不要使用mysql的root用户,否则一直连接不上;-->
报错:ERROR 1184 (HY000): Invalid DataSource:0,具体原因不详;
(配置中的test用户的host是%,而root用户的host有%也有loaclhost,难道是这个原因?)
(默认的账号的host属性都是localhost,意思是这个账号只能本地使用,如果要使用某个账号来远程登录,必须将账号的host属性值更改成%)
还是连接不上时,试试把localhost改成127.0.0.1
6、启动mycat
mycat start #启动后要等会再进行操作,不然会Lost connection to MySQL server during query
7、在命令行访问mycat逻辑数据库
mysql -h 127.0.0.1 -P 3306 -u test -ptest123... #连接mysql
mysql -uroot -p123456 -h127.0.0.1 -P8066 TESTDB #连接mycat服务端,平时对数据库进行操作是连这个
mysql -uroot -p123456 -h127.0.0.1 -P9066 TESTDB #连接mycat管理端
8、操作逻辑数据库,就跟操作单库似的了
#创建数据库和表
create database beijing;
use beijing;
create table student(
id int primary key,
name varchar(8) not null,
grade int not null
);
create database shanghai;
use shanghai;
create table student(
id int primary key,
name varchar(8) not null,
grade int not null
);
create database guangzhou;
use guangzhou;
create table student(
id int primary key,
name varchar(8) not null,
grade int not null
);
create database basic;
use basic;
create table grade(
id int primary key,
name varchar(8) not null
);
#插入数据
insert into grade (id,name) values (1,'一年级');
insert into grade (id,name) values (2,'二年级');
insert into grade (id,name) values (3,'三年级');
insert into student (id,name,grade) values (1,'张三',2);
insert into student (id,name,grade) values (2,'李四',1);
insert into student (id,name,grade) values (3,'王五',3);
insert into student (id,name,grade) values (4,'甲',3);
insert into student (id,name,grade) values (5,'乙',2);
insert into student (id,name,grade) values (6,'丙',1);
#此时,去每个物理库查看数据,student表的6条数据是分布的存储的
select * from student;插叙结果是6条数据
至此,分库分表简单操作已经完成;
本文使用 mdnice 排版