数据库分库分表分片中间件——MyCat配置及使用

一、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;  

建好后应该如图:
数据库分库分表分片中间件——MyCat配置及使用_第1张图片

2.MyCat配置

server.xml

server.xml中配置了mycat系统所需要的信息,这里我们只需要改一下访问的用户名、密码、schema

    name="root">
        <property name="password">123456property>
        <property name="schemas">TESTDBproperty>      
    

    name="user">
        <property name="password">userproperty>
        <property name="schemas">TESTDBproperty>
        <property name="readOnly">trueproperty>
    

这就是你的数据库客户端需要连接的配置

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 name="node_db01" dataHost="dataHost01" database="db01" />  
    <dataNode name="node_db02" dataHost="dataHost01" database="db02" />  
    <dataNode name="node_db03" dataHost="dataHost01" database="db03" />  

      
    <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>idcolumns>
            <algorithm>mod-longalgorithm>
        rule>
    tableRule>

name 属性指定唯一的名字,用于标识不同的表规则。
内嵌的 rule 标签则指定对物理表中的哪一列进行拆分和使用什么路由算法。
columns 内指定要拆分的列名字。
algorithm 使用 function 标签中的 name 属性。连接表规则和具体路由算法。当然,多个表规则可以连接到
同一个路由算法上。table 标签内使用。让逻辑表使用这个规则进行分片。

    <function name="mod-long" class="io.mycat.route.function.PartitionByMod">
        
        <property name="count">3property>
    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只是提供了一个便捷的工具,但是更重要的在于分库分表的策略,路由的规则,以及有前瞻性的规划。谢谢大家观看

你可能感兴趣的:(数据库)