一、MyCat是什么
MyCat是什么呢?简而言之,MyCat就是一个数据库中间件,对数据库的请求直接连接到MyCat,MyCat再根据规则连接到后端的数据库集群。如果你不关心架构方面的事,只是纯粹的应用的话,那么你完全可以把它当做一个数据库看待。
下面摘自官方文档
从定义和分类来看,它是一个开源的分布式数据库系统,是一个实现了 MySQL 协议的的
Server,前端用户可以把它看作是一个数据库代理,用 MySQL 客户端工具和命令行访问,而其后端可以用
MySQL 原生(Native)协议与多个 MySQL 服务器通信,也可以用 JDBC 协议与大多数主流数据库服务器(包括Oracle,DB2,SqlServe,MongoDB等)通信,其核心功能是分表分库,即将一个大表水平分割为 N 个小表,存储在后端 MySQL 服务器里或者其他数据库里。
对于 DBA 来说,可以这么理解 Mycat:
Mycat 就是 MySQL Server,而 Mycat 后面连接的 MySQL Server,就好象是 MySQL 的存储引擎,如
InnoDB,MyISAM 等,因此,Mycat 本身并不存储数据,数据是在后端的 MySQL 上存储的,因此数据可靠性
以及事务等都是 MySQL 保证的,简单的说,Mycat 就是 MySQL 最佳伴侣,它在一定程度上让 MySQL 拥有了
能跟 Oracle PK 的能力。
对于软件工程师来说,可以这么理解 Mycat:
Mycat 就是一个近似等于 MySQL 的数据库服务器,你可以用连接 MySQL 的方式去连接 Mycat(除了端
口不同,默认的 Mycat 端口是 8066 而非 MySQL 的 3306,因此需要在连接字符串上增加端口信息),大多数
情况下,可以用你熟悉的对象映射框架使用 Mycat,但建议对于分片表,尽量使用基础的 SQL 语句,因为这样能
达到最佳性能,特别是几千万甚至几百亿条记录的情况下。
对于架构师来说,可以这么理解 Mycat:
Mycat 是一个强大的数据库中间件,不仅仅可以用作读写分离、以及分表分库、容灾备份,而且可以用于多
租户应用开发、云平台基础设施、让你的架构具备很强的适应性和灵活性,借助于即将发布的 Mycat 智能优化模
块,系统的数据访问瓶颈和热点一目了然,根据这些统计分析数据,你可以自动或手工调整后端存储,将不同的
表映射到不同存储引擎上,而整个应用的代码一行也不用改变。
对于MyCat想要深入全面了解的可以阅读官网的资料文档:http://www.mycat.io/document/Mycat_V1.6.0.pdf
二、什么情况下需要使用MyCat
当你开始有意的关注MyCat的时候,我想你肯定已经大概知道MyCat的作用或者你有了数据量非常大,对于存储性能扩展的担忧了。也就是说你想对数据库进行切分,分库分表。
数据的切分(Sharding)根据其切分规则的类型,可以分为两种切分模式。一种是按照不同的表(或者
Schema)来切分到不同的数据库(主机)之上,这种切可以称之为数据的垂直(纵向)切分;另外一种则是根据
表中的数据的逻辑关系,将同一个表中的数据按照某种条件拆分到多台数据库(主机)上面,这种切分称之为数
据的水平(横向)切分。
垂直切分的最大特点就是规则简单,实施也更为方便,尤其适合各业务之间的耦合度非常低,相互影响很
小,业务逻辑非常清晰的系统。在这种系统中,可以很容易做到将不同业务模块所使用的表分拆到不同的数据库
中。根据不同的表来进行拆分,对应用程序的影响也更小,拆分规则也会比较简单清晰。
水平切分于垂直切分相比,相对来说稍微复杂一些。因为要将同一个表中的不同数据拆分到不同的数据库
中,对于应用程序来说,拆分规则本身就较根据表名来拆分更为复杂,后期的数据维护也会更为复杂一些。
MyCat就是为了数据库切分而提供帮助的中间件,尤其是横向切分。
介绍就大概到这里了,下面展示下MyCat的安装,配置和简单实用。
三、安装以及配置
首先环境的准备需要jdk1.7以上,MySQL 5.5以上,环境的准备就不在这里赘述了,请自己备好。
我的安装环境选择的是Linux,Windows请下载Windows的安装包,都是直接解压的,配置文件的配置也都一样。
1.安装
去官方地址下载:
http://dl.mycat.io/1.6-RELEASE/
Linux选择 Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz
上传到Linux服务器上,tar -xvf Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz 解压。
[mysql@localhost ~]$ ls
mycat Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz
[mysql@localhost ~]$ cd mycat/
[mysql@localhost mycat]$ ls
bin catlet conf lib logs version.txt
可以看到mycat下的目录
Name | Academy | score |
---|---|---|
bin | 程序目录 | ./mycat console 注:mycat 支持的命令{console start/stop/restart/status/dump} |
conf | 配置文件目录 | server.xml 是 Mycat 服务器参数调整和用户授权的配置文件,schema.xml 是逻辑库定义和表以及分片定义的配置文件,rule.xml 是分片规则的配置文件,分片规则的具体一些参数信息单独存放为文件,也在这个目录下,配置文件修改,需要重启 Mycat 或者通过 9066 端口 reload. |
lib | 依赖的一些 jar 文件 | |
logs | 存放日志文件 | 日志存放在 logs/mycat.log 中,每天一个文件,日志的配置是在 conf/log4j.xml 中,根据自己的需要,可以调整输出级别为 debug,debug 级别下,会输出更多的信息,方便排查问题. |
注意:Linux 下部署安装 MySQL,默认不忽略表名大小写,需要手动到/etc/my.cnf 下配置
lower_case_table_names=1 使 Linux 环境下 MySQL 忽略表名大小写,否则使用 MyCAT 的时候会提示找不到
表的错误!
2.环境配置
MyCAT 在 Linux 中部署启动时,首先需要在 Linux 系统的环境变量中配置 MYCAT_HOME,操作方式如下:
1) vi /etc/profile,在系统环境变量文件中增加 MYCAT_HOME=mycat安装目录
2) 执行 source /etc/profile 命令,使环境变量生效
经过以上的配置,就可以到mycat/bin 目录下执行:
./mycat start
即可启动 mycat 服务!
[root@localhost mycat]# cd bin
[root@localhost bin]# ./mycat start
Starting Mycat-server...
[root@localhost bin]#
三、简单使用
1.测试数据准备
比如我们要把User这张表横向拆分为三个,根据id取模来定位。
我们在MySQL同一个实例下建3个库,每个库都建同样的表,建库建表语句如下:
create database db01;
create database db02;
create database db03;
//分别在以上三个库下建用户表
CREATE TABLE users (
id INT NOT NULL,
name varchar(50) NOT NULL default '',
indate DATETIME NOT NULL default '0000-00-00 00:00:00',
PRIMARY KEY (id)
)AUTO_INCREMENT= 1 ENGINE=InnoDB DEFAULT CHARSET=utf8;
建好后应该如图:
2.MyCat配置
server.xml
server.xml中配置了mycat系统所需要的信息,这里我们只需要改一下访问的用户名、密码、schema
<user name="root">
<property name="password">123456</property>
<property name="schemas">TESTDB</property>
</user>
<user name="user">
<property name="password">user</property>
<property name="schemas">TESTDB</property>
<property name="readOnly">true</property>
</user>
这就是你的数据库客户端需要连接的配置
schema.xml
schema.xml 作为 MyCat 中重要的配置文件之一,管理着 MyCat 的逻辑库、表、分片规则、DataNode 以
及 DataSource。这里我们只展示简单应用层
<schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100">
<table name="users" primaryKey="id" dataNode="node_db01,node_db02,node_db03" rule="idMod"/>
</schema>
<!-- 设置dataNode 对应的数据库,及 mycat 连接的地址dataHost -->
<dataNode name="node_db01" dataHost="dataHost01" database="db01" />
<dataNode name="node_db02" dataHost="dataHost01" database="db02" />
<dataNode name="node_db03" dataHost="dataHost01" database="db03" />
<!-- mycat 逻辑主机dataHost对应的物理主机.其中也设置对应的mysql登陆信息 -->
<dataHost name="dataHost01" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native">
<heartbeat>select user()</heartbeat>
<writeHost host="server1" url="127.0.0.1:3306" user="root" password="rootroot"/>
</dataHost>
schema name和schema.xml中保持一致,这里为TESTDB。table配置你需要分片的表,dataNode与下面配置一致,有几个配几个,rule是路由的规则,和rules.xml中规则保持一致。最下面host配置真实数据库的地址端口用户密码。
rules.xml
rule.xml 里面就定义了我们对表进行拆分所涉及到的规则定义。我们可以灵活的对表使用不同的分片算法,
或者对表使用相同的算法但具体的参数不同。这个文件里面主要有 tableRule 和 function 这两个标签。在具体使
用过程中可以按照需求添加 tableRule 和 function。
<tableRule name="idMod">
<rule>
<columns>id</columns>
<algorithm>mod-long</algorithm>
</rule>
</tableRule>
name 属性指定唯一的名字,用于标识不同的表规则。
内嵌的 rule 标签则指定对物理表中的哪一列进行拆分和使用什么路由算法。
columns 内指定要拆分的列名字。
algorithm 使用 function 标签中的 name 属性。连接表规则和具体路由算法。当然,多个表规则可以连接到
同一个路由算法上。table 标签内使用。让逻辑表使用这个规则进行分片。
<function name="mod-long" class="io.mycat.route.function.PartitionByMod">
<!-- how many data nodes -->
<property name="count">3</property>
</function>
name 指定算法的名字(mod-long中的count属性代表有几个库)
class 制定路由算法具体的类名字(这里可以自己写路由算法用来扩展)
property 为具体算法需要用到的一些属性。
3.验证
我们都配置完了,然后重启MyCat。
我们直接使用MySQL的命令来连接MyCat,端口默认是8066
[root@localhost bin]# ./mycat start
Starting Mycat-server...
[root@localhost bin]# mysql -uroot -p123456 -h127.0.0.1 -P8066 -DTESTDB
mysql> show databases;
+----------+
| DATABASE |
+----------+
| TESTDB |
+----------+
1 row in set (0.01 sec)
mysql> show tables;
+------------------+
| Tables in TESTDB |
+------------------+
| users |
+------------------+
1 row in set (0.00 sec)
接下来我们可以往里面插数据了,查出来看一下
mysql> insert into users(id,name,indate) values(1,'lvbu',now());
mysql> insert into users(id,name,indate) values(2,'zhaoyun',now());
mysql> insert into users(id,name,indate) values(3,'dianwei',now());
mysql> select * from users order by id;
+----+---------+---------------------+
| id | name | indate |
+----+---------+---------------------+
| 1 | lvbu | 2018-04-20 03:30:56 |
| 2 | zhaoyun | 2018-04-20 03:31:05 |
| 3 | dianwei | 2018-04-20 03:31:15 |
+----+---------+---------------------+
然后再连上后端真实MySQL数据库查看一下数据分布。
[root@localhost bin]# mysql -uroot -proot
mysql> select * from db01.users;
+----+---------+---------------------+
| id | name | indate |
+----+---------+---------------------+
| 3 | dianwei | 2018-04-20 03:31:15 |
+----+---------+---------------------+
mysql> select * from db02.users;
+----+------+---------------------+
| id | name | indate |
+----+------+---------------------+
| 1 | lvbu | 2018-04-20 03:30:56 |
+----+------+---------------------+
mysql> select * from db03.users;
+----+---------+---------------------+
| id | name | indate |
+----+---------+---------------------+
| 2 | zhaoyun | 2018-04-20 03:31:05 |
+----+---------+---------------------+
可以看出数据均匀的分布到三张表中了,这说明我们的分片策略奏效了。
四、总结
在大型分布式系统中,随着数据量的增多,分布式数据库是大势所趋,MyCat只是提供了一个便捷的工具,但是更重要的在于分库分表的策略,路由的规则,以及有前瞻性的规划。谢谢大家观看