千家信息网

MySQL中安装配置和使用MyCat的教程

发表于:2025-01-26 作者:千家信息网编辑
千家信息网最后更新 2025年01月26日,一、MyCat基础概念1、什么是MyCat一个彻底开源的,面向企业应用开发的大数据库集群支持事务、ACID、可以替代MySQL的加强版数据库一个可以视为MySQL集群的企业级数据库,用来替代昂贵的Or
千家信息网最后更新 2025年01月26日MySQL中安装配置和使用MyCat的教程

一、MyCat基础概念

1、什么是MyCat

一个彻底开源的,面向企业应用开发的大数据库集群
支持事务、ACID、可以替代MySQL的加强版数据库
一个可以视为MySQL集群的企业级数据库,用来替代昂贵的Oracle集群
一个融合内存缓存技术、NoSQL技术、HDFS大数据的新型SQL Server
结合传统数据库和新型分布式数据仓库的新一代企业级数据库产品
一个新颖的数据库中间件产品

2、为什么使用MyCat

如今随着互联网的发展,数据的量级也是撑指数的增长,从GB到TB到PB。对数据的各种操作也是愈加的困难,传统的关系性数据库已经无法满足快速查询与插入数据的需求。这个时候NoSQL的出现暂时解决了这一危机。它通过降低数据的安全性,减少对事务的支持,减少对复杂查询的支持,来获取性能上的提升。但是,在有些场合NoSQL一些折衷是无法满足使用场景的(比如有些使用场景是绝对要有事务与安全指标的。这个时候NoSQL肯定是无法满足的)。所以还是需要使用关系性数据库。如何使用关系型数据库解决海量存储的问题呢?此时就需要做数据库集群,为了提高查询性能将一个数据库的数据分散到不同的数据库中存储,为应对此问题就出现了--MyCat

MyCat作用:

能满足数据库数据大量存储;提高了查询性能
读写分离
数据分片 垂直拆分(分库)、水平拆分(分表)、垂直+水平拆分(分库分表)
多数据源整合

3、 数据库中间件对比

① Cobar(前身为amoaba)属于阿里B2B事业群,始于2008年,在阿里服役3年多,接管3000+个MySQL数据库的schema, 集群日处理在线SQL请求50亿次以上。由于Cobar发起人的离职, Cobar停止维护。
② Mycat是开源社区在阿里cobar基础上进行二次开发,解决了cobar存在的问题,并且加入了许多新 的功能在其中。青出于蓝而胜于蓝。
③ OneProxy基于MySQL官方的proxy思想利用c进行开发的, OneProxy是一款商业收费的中间件。舍弃了一些功能,专注在性能和稳定性上。
④ kingshard由小团队用go语言开发,还需要发展,需要不断完善。
⑤ Vitess是Youtube生产在使用,架构很复杂。不支持MySQL原生协议,使用需要大量改造成本。
⑥ Atlas是360团队基于mysql proxy改写,功能还需完善,高并发下不稳定。
⑦ MaxScale是mariadb(MySQL原作者维护的一个版本) 研发的中间件
⑧ MySQLRoute是MySQL官方Oracle公司发布的中间件

4、支持的数据库

支持MySQL ORACLE SQLServer等一些主流的数据库

5、核心技术

分库分表:数据库分片指通过某种特定的条件,将我们存放在一个数据库中的数据分散存放在不同的多个数据库(主机)中,这样来达到分散单台设备的负载,根据切片规则,可分为以下两种切片模式,MyCAT通过定义表的分片规则来实现分片,每个表格可以捆绑一个分片规则,每个分片规则指定一个分片字段并绑定一个函数,来实现动态分片算法

1)Schema:逻辑库,与MySQL中的Database(数据库)对应,一个逻辑库中定义了所包括的Table。
2)Table:逻辑表,即物理数据库中存储的某一张表,与传统数据库不同,这里的表格需要声明其所存储的逻辑数据节点DataNode。在此可以指定表的分片规则。
3)DataNode:MyCAT的逻辑数据节点,是存放table的具体物理节点,也称之为分片节点,通过DataSource来关联到后端某个具体数据库上
4)DataSource:定义某个物理库的访问地址,用于捆绑到Datanode上
5)分片规则:前面讲了数据切分,一个大表被分成若干个分片表,就需要一定的规则,这样按照某种业务规则把数据分到某个分片的规则就是分片规则,数据切分选择合适的分片规则非常重要,将极大的避免后续数据处理的难

二、MyCat安装部署

环境:

JDK:要求jdk必须是1.7及以上版本MySQL:推荐mysql是5.5以上版本MyCat的官方网站:http://www.mycat.org.cn/
主机操作系统IP地址
mysql01(master01)CentOS 7.3192.168.1.1
mysql02(slave)CentOS 7.3192.168.1.8
mycatCentOS 7.3192.168.1.3
PS:mysql使用现成的主机(搭建了双主+keepalived,主从也可以)。如果没有mysql,看上一个博客部署。

1、下载及安装,使用上面的官网地址下载。


复制链接,wget下载

[root@localhost ~]# wget http://dl.mycat.io/1.6-RELEASE/Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz

将压缩包解压缩。建议将mycat放到/usr/local/mycat目录下。

[root@localhost ~]# tar zxf Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz[root@localhost ~]# cd mycat/

修改配置文件:

server.xml: 定义用户以及系统相关变量,如端口等
schema.xml: 定义逻辑库,表、分片节点等内容
rule.xml: 定义分片规则

[root@mycat mycat]# vim conf/server.xml  80               //定义连接中间件的用户81                 123456  //密码82                 TESTDB      //逻辑库[root@mycat mycat]# cp conf/schema.xml conf/schema.xml.bak  //备份配置文件[root@mycat mycat]# vim conf/schema.xml              //指明逻辑库,以及节点                     //指定后端服务器中的真实库                        select user()                                                                                    //定义读的服务器(从)以及IP地址,用户密码                        

##这个配置文件已经把不必要配置项以及注释的都删了

重启mycat服务
让mycat拥有mysql命令

[root@mysql02 ~]# scp /usr/local/mysql/bin/mysql 192.168.1.3:/usr/local/sbin/

两台mysql授权,允许mycat远程登陆

mysql> grant all on *.* to root@'192.168.1.%' identified by '123.com';

MyCat远程登录测试:

[root@mycat mycat]# mysql -uroot -h 192.168.1.1 -P 3306 -p123.com[root@mycat mycat]# mysql -uroot -h 192.168.1.8 -P 3306 -p123.com

启动mycat服务:

[root@mycat mycat]# ./bin/mycat helpUsage: ./bin/mycat { console | start | stop | restart | status | dump }[root@mycat mycat]# ./bin/mycat console 

使用console启动,会占用一个终端,实时查看日志内容(登录、查询、退出),使用start启动不会又实时日志,不占用终端

[root@mycat ~]# ss -anplt |grep java


###mycat端口8806

测试,查看数据是否同步:

[root@mycat ~]# mysql -umycat -p123456 -h 192.168.1.3 -P8066mysql> show databases;

mysql> use TESTDBmysql> show tables;

mysql> select * from tab1;

三、MyCat读写分离

Mycat的读写分离是建立在Mysql的主从复制的基础上的

修改配置文件 schema.xml

[root@mycat ~]# cd mycat/[root@mycat mycat]# vim conf/schema.xml

1、设置balance="1"与writeType="0"

Balance参数设置:    修改的balance属性,通过此属性配置读写分离的类型负载均衡类型,目前的取值有4 种:    balance="0",不开启读写分离机制, 所有读操作都发送到当前可用的 writeHost 上。    balance="1",全部的 readHost与 stand by writeHost 参与 select 语句的负载均衡,简单的说,当双主双从模式(M1->S1, M2->S2,并且M1与M2 互为主备),正常情况下, M2,S1,S2 都参与 select 语句的负载均衡。   balance="2",所有读操作都随机的在 writeHost、 readhost 上分发。   balance="3",所有读请求随机的分发到 readhost 执行,writerHost 不负担读压力WriteType参数设置:   writeType="0", 所有写操作都发送到可用的writeHost上。   writeType="1",所有写操作都随机的发送到readHost。   writeType="2",所有写操作都随机的在writeHost、readhost分上发。

"readHost是从属于writeHost的,即意味着它从那个writeHost获取同步数据,因此,当它所属的writeHost宕机了,则它也不会再参与到读写分离中来,即"不工作了",这是因为此时,它的数据已经"不可靠"了。基于这个考虑,目前mycat 1.3和1.4版本中,若想支持MySQL一主一从的标准配置,并且在主节点宕机的情况下,从节点还能读取数据,则需要在Mycat里配置为两个writeHost并设置banlance=1。"

2、设置switchType="2" 与slaveThreshold="100"

switchType 目前有三种选择:   -1:表示不自动切换   1 :默认值,自动切换   2 :基于MySQL主从同步的状态决定是否切换

"Mycat心跳检查语句配置为 show slave status ,dataHost 上定义两个新属性: switchType="2" 与slaveThreshold="100",此时意味着开启MySQL主从复制状态绑定的读写分离与切换机制。Mycat心跳机制通过检测 show slave status 中的 "Seconds_Behind_Master", "Slave_IO_Running", "Slave_SQL_Running" 三个字段来
确定当前主从同步的状态以及Seconds_Behind_Master主从复制时延。

3、修改配置文件,启动程序

[root@mycat mycat]# vim conf/schema.xml

①控制台启动:mycat/bin 目录下执行 ./mycat console
②后台启动:mycat/bin 目录下./mycat start
为了能第一时间看到启动日志,方便定位问题,选择①控制台启动。

[root@mycat mycat]# ./bin/mycat console

登录后台管理窗口 此登录方式用于管理维护 Mycat

[root@mycat ~]# mysql -umycat -p123456 -h 192.168.1.3 -P8066

4、验证读写分离 my.cnf binlog_format=STATEMENT

(1) 在写主机插入数据:
[root@mysql02 ~]# mysql -uroot -p123.commysql> use test1;mysql> select * from tab1;+------+| id   |+------+|    1 ||    2 ||    3 |+------+3 rows in set (0.01 sec)mysql> insert into tab1 values(4);Query OK, 1 row affected (0.02 sec)mysql> select * from tab1;+------+| id   |+------+|    1 ||    2 ||    3 ||    4 |+------+4 rows in set (0.00 sec)

主从主机数据不一致了

[root@mysql01 ~]# mysql -uroot -p123.commysql> use test1mysql> select * from tab1;+------+| id   |+------+|    1 ||    2 ||    3 |+------+3 rows in set (0.00 sec)
(2) 在Mycat里查询:
mysql> use TESTDBmysql> select * from tab1;+------+| id   |+------+|    1 ||    2 ||    3 ||    4 |+------+4 rows in set (0.00 sec)

四、垂直拆分--分库

一个数据库由很多表的构成,每个表对应着不同的业务,垂直切分是指按照业务将表进行分类, 分布到不同 的数据库上面,这样也就将数据或者说压力分担到不同的库
如何划分表分库的原则:有紧密关联关系的表应该在一个库里,相互没有关联关系的表可以分到不同的库里。

这个案例中需要一台新的mysql来进行分库操作。

主机操作系统IP地址
mysql01(master01)CentOS 7.3192.168.1.1
mysql02(slave)CentOS 7.3192.168.1.8
mycatCentOS 7.3192.168.1.3
mysql03(master02)CentOS 7.3192.168.1.9

先将上一个案例插入的数据删除

[root@mysql02 ~]# mysql -uroot -p123.commysql> delete from tab1 where id=4;Query OK, 1 row affected (0.01 sec)mysql> select * from tab1;+------+| id   |+------+|    1 ||    2 ||    3 |+------+3 rows in set (0.00 sec)[root@mycat ~]# mysql -umycat -p123456 -h 192.168.1.3 -P8066mysql> use TESTDBmysql> select * from tab1;+------+| id   |+------+|    1 ||    2 ||    3 |+------+3 rows in set (0.00 sec)

如下四个表:
客户表分在一个数据库,另外三张都需要关联查询,分在另外一个数据库。

#客户表 rows:20万CREATE TABLE customer(id INT AUTO_INCREMENT,NAME VARCHAR(200),PRIMARY KEY(id));#订单表 rows:600万CREATE TABLE orders(id INT AUTO_INCREMENT,order_type INT,customer_id INT,amount DECIMAL(10,2),PRIMARY KEY(id));#订单详细表 rows:600万CREATE TABLE orders_detail(id INT AUTO_INCREMENT,detail VARCHAR(2000),order_id INT,PRIMARY KEY(id));#订单状态字典表 rows:20CREATE TABLE dict_order_type(id INT AUTO_INCREMENT,order_type VARCHAR(200),PRIMARY KEY(id));

实现分库:

1、 修改 schema 配置文件

[root@mycat mycat]# vim conf/schema.xml

                        
select user() select user()

授权MyCat远程登陆mysql03

[root@mysql03 ~]# mysql -uroot -p123.commysql> grant all on *.* to root@'192.168.1.%' identified by '123.com';

因为在配置文件中逻辑库所对应的真实库mysql03中并没有,需要在mysql03中创建

mysql> create database test1;

2、 重启mycat,访问MyCat,创建表

[root@mycat mycat]# mysql -umycat -p123456 -h 192.168.1.3 -P8066mysql> use TESTDBmysql> CREATE TABLE customer(    -> id INT AUTO_INCREMENT,    -> NAME VARCHAR(200),    -> PRIMARY KEY(id)    -> );Query OK, 0 rows affected (0.01 sec)mysql> CREATE TABLE orders(    -> id INT AUTO_INCREMENT,    -> order_type INT,    -> customer_id INT,    -> amount DECIMAL(10,2),    -> PRIMARY KEY(id)    -> );Query OK, 0 rows affected (0.01 sec)mysql> CREATE TABLE orders_detail(    -> id INT AUTO_INCREMENT,    -> detail VARCHAR(2000),    -> order_id INT,    -> PRIMARY KEY(id)    -> );Query OK, 0 rows affected (0.01 sec)mysql> CREATE TABLE dict_order_type(    -> id INT AUTO_INCREMENT,    -> order_type VARCHAR(200),    -> PRIMARY KEY(id)    -> );Query OK, 0 rows affected (0.01 sec)mysql> show tables;+-----------------     +| Tables_in_test1 |+-----------------     +| customer           || dict_order_type || orders               || orders_detail    || tab1                  |+-----------------    +5 rows in set (0.05 sec)

使用mysql01查看表:

mysql> show tables;+-----------------    +| Tables_in_test1 |+-----------------    +| dict_order_type || orders               || orders_detail    || tab1                  |+-----------------    +4 rows in set (0.00 sec)

使用mysql03查看表:

mysql> use test1;mysql> show tables;+-----------------     +| Tables_in_test1 |+-----------------     +| customer           |+-----------------     +1 row in set (0.00 sec)

查看结构

mysql> desc customer;+-------+--------------+------+-----+---------+----------------+| Field | Type         | Null | Key | Default | Extra          |+-------+--------------+------+-----+---------+----------------+| id          | int(11)           | NO    | PRI | NULL    | auto_increment || NAME  | varchar(200) | YES  |     | NULL       |                |+-------+--------------+------+-----+---------+----------------+2 rows in set (0.00 sec)

五、水平拆分--分表

相对于垂直拆分,水平拆分不是将表做分类,而是按照某个字段的某种规则来分散到多个库之中, 每个表中 包含一部分数据。简单来说,我们可以将数据的水平切分理解为是按照数据行的切分,就是将表中的某些行切分到一个数据库,而另外的某些行又切分到其他的数据库中。
实现分表 选择要拆分的表 MySQL 单表存储数据条数是有瓶颈的,单表达到 1000 万条数据就达到了瓶颈,会影响查询效率,需要进行水平拆分(分表)进行优化。 例如:上一案例的 orders、orders_detail 都已经达到600 万行数据,需要进行分表优化。 分表字段以 orders 表为例,可以根据不同自字段进行分表

编号分表字段效果
1id(主键、或创建时间)查询订单注重时效,历史订单被查询的次数少,如此分片会造成一个节点访问多,一个访问少,不平均。
2customer_id(客户ID)根据客户 id 去分,两个节点访问平均,一个客户的所有订单都在同一个节点

1、修改配置文件 schema.xml

[root@mycat mycat]# vim conf/schema.xml

                        
select user() select user()

2、修改配置文件rule.xml

[root@mycat mycat]# vim conf/rule.xml

#在 rule 配置文件里新增分片规则 mod_rule,并指定规则适用字段为 customer_id,
#还有选择分片算法 mod-long(对字段求模运算) , customer_id 对两个节点求模,根据结果分片

 38          39                  40                         customer_id 41                         mod-long 42                  43          …… 105          106                  107                 2#配置算法 mod-long 参数 count 为 2,两个节点 108         

3、因为在dn2(mysql03:192.168.1.9)上并没有orders表,在数据节点dn2上创建orders表,并重启mycat服务

[root@mysql03 ~]# mysql -uroot -p123.commysql> use test1;mysql> CREATE TABLE orders(    -> id INT AUTO_INCREMENT,    -> order_type INT,    -> customer_id INT,    -> amount DECIMAL(10,2),    -> PRIMARY KEY(id)    -> );Query OK, 0 rows affected (0.00 sec)

4、在MyCat中向orders表插入数据,insert字段不能省略

[root@mycat mycat]# mysql -umycat -p123456 -P8066 -h292.168.1.3mysql> use TESTDBmysql> INSERT INTO orders(id,order_type,customer_id,amount) VALUES (1,101,100,100100);Query OK, 1 row affected (0.00 sec)mysql> INSERT INTO orders(id,order_type,customer_id,amount) VALUES(2,101,100,100300);Query OK, 1 row affected (0.00 sec)mysql> INSERT INTO orders(id,order_type,customer_id,amount) VALUES(3,101,101,120000);Query OK, 1 row affected (0.00 sec)mysql> INSERT INTO orders(id,order_type,customer_id,amount) VALUES(4,101,101,103000);Query OK, 1 row affected (0.00 sec)mysql> INSERT INTO orders(id,order_type,customer_id,amount) VALUES(5,102,101,100400);Query OK, 1 row affected (0.00 sec)mysql> INSERT INTO orders(id,order_type,customer_id,amount) VALUES(6,102,100,100020);Query OK, 1 row affected (0.01 sec)

#在mycat、dn1、dn2中查看orders表数据,分表成功

dn1(mysql01:192.168.1.1):

[root@mysql01 ~]# mysql -uroot -p123.commysql> use test1;mysql> select * from orders;+----+------------+-------------+-----------+| id | order_type | customer_id | amount    |+----+------------+-------------+-----------+|  2 |        101 |         100 | 100300.00 ||  4 |        101 |         101 | 103000.00 ||  6 |        102 |         100 | 100020.00 |+----+------------+-------------+-----------+3 rows in set (0.00 sec)

dn2(mysql03:192.168.1.9):

[root@mysql03 ~]# mysql -uroot -p123.commysql> use test1;mysql> select * from orders;+----+------------+-------------+-----------+| id | order_type | customer_id | amount    |+----+------------+-------------+-----------+|  1 |        101 |         100 | 100100.00 ||  3 |        101 |         101 | 120000.00 ||  5 |        102 |         101 | 100400.00 |+----+------------+-------------+-----------+3 rows in set (0.00 sec)

在dn2(mysql03:192.168.1.9) 创建 orders_detail 表

mysql> CREATE TABLE orders_detail(    -> id INT AUTO_INCREMENT,    -> detail VARCHAR(2000),    -> order_id INT,    -> PRIMARY KEY(id)    -> );Query OK, 0 rows affected (0.02 sec)

重启 Mycat 访问 Mycat 向 orders_detail 表插入数据

[root@mycat mycat]# mysql -umycat -p123456 -h 192.168.1.3 -P8066mysql> use TESTDBmysql> insert into orders_detail(id,detail,order_id) values (1,'detail',1);Query OK, 1 row affected (0.03 sec)mysql> insert into orders_detail(id,detail,order_id) values (2,'detail',2);Query OK, 1 row affected (0.00 sec)mysql> insert into orders_detail(id,detail,order_id) values (3,'detail',3);Query OK, 1 row affected (0.01 sec)mysql> insert into orders_detail(id,detail,order_id) values (4,'detail',4);Query OK, 1 row affected (0.01 sec)mysql> insert into orders_detail(id,detail,order_id) values (5,'detail',5);Query OK, 1 row affected (0.00 sec)mysql> insert into orders_detail(id,detail,order_id) values (6,'detail',6);Query OK, 1 row affected (0.01 sec)mysql> select o.*,od.detail from orders as o inner join orders_detail as od on o.id=od.order_id;+----+------------+-------------+-----------+--------+| id | order_type | customer_id | amount    | detail |+----+------------+-------------+-----------+--------+|  1 |        101 |         100 | 100100.00 | detail ||  3 |        101 |         101 | 120000.00 | detail ||  5 |        102 |         101 | 100400.00 | detail ||  2 |        101 |         100 | 100300.00 | detail ||  4 |        101 |         101 | 103000.00 | detail ||  6 |        102 |         100 | 100020.00 | detail |+----+------------+-------------+-----------+--------+6 rows in set (0.03 sec)

使用dn1、dn2查看:

mysql> select * from orders_detail;

mysql> select * from orders_detail;

六、全局表

在分片的情况下,当业务表因为规模而进行分片以后,业务表与这些附属的字典表之间的关联,就成了比较棘手的问题,考虑到字典表具有以下几个特性:

变动不频繁 数据量总体变化不大 数据规模不大,很少有超过数十万条记录 

鉴于此, Mycat 定义了一种特殊的表,称之为"全局表",全局表具有以下特性:

全局表的插入、更新操作会实时在所有节点上执行,保持各个分片的数据一致性全局表的查询操作,只从一个节点获取 全局表可以跟任何一个表进行 JOIN 操作 将字典表或者符合字典表特性的一些表定义为全局表,则从另外一个方面,很好的解决了数据 JOIN 的难题。 

通过全局表+基于 E-R 关系的分片策略, Mycat 可以满足 80%以上的企业应用开发

[root@mycat mycat]# vim conf/schema.xml

                

在dn2(mysql03:192.168.1.9)创建dict_order_type表

mysql> CREATE TABLE dict_order_type(    -> id INT AUTO_INCREMENT,    -> order_type VARCHAR(200),    -> PRIMARY KEY(id)    -> );Query OK, 0 rows affected (0.01 sec)

重启MyCat,访问MyCat向dict_order_type表插入数据

[root@mycat mycat]# mysql -umycat -p123456 -h 192.168.1.3 -P8066mysql> use TESTDBmysql>  insert into dict_order_type (id,order_type) values (101,'type1');Query OK, 1 row affected (0.03 sec)mysql>  insert into dict_order_type (id,order_type) values (102,'type2');Query OK, 1 row affected (0.01 sec)mysql> select * from dict_order_type;+-----+------------+| id  | order_type |+-----+------------+| 101 | type1      || 102 | type2      |+-----+------------+2 rows in set (0.03 sec)

常用分片规则

取模:此规则为对分片字段求摸运算。 也是水平分表最常用规则。 5.1 配置分表中, orders 表采用了此规则。
分片枚举:通过在配置文件中配置可能的枚举 id,自己配置分片,本规则适用于特定的场景,比如有些业务 需要按照省份或区县来做保存,而全国省份区县固定的,这类业务使用本条规则。

数据 数据库 规则 配置 节点 分表 文件 查询 字段 逻辑 不同 全局 业务 主从 分库 水平 支持 中间件 主机 存储 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 网络安全最好的行业 护苗网络安全课第二季 网络安全等级保护 公有云 塔科夫为什么老服务器连接中断 问道会员哪个服务器最便宜 查询数据库中有多少表格 网络安全随笔500字 软件开发 确定验收标准 服务器刀片化百度百科 辽宁建筑软件开发 工信局备案游戏软件开发所需材料 打印机域服务器不可用 sql服务器叫什么名字 基本的数据库管理系统 此网络安全证书已过期英雄联盟 达梦数据库有限公司 招聘 静海区信息网络技术售后保障 天河区国内网络技术开发动态 数据库给我们提供了哪些服务 2018年网络安全事例 成果数据库与管理平台建 sql数据库关闭拷出来 传统游戏和微端服务器有什么区别 excel表格中查询数据库 分管网络安全的负责是直接责任人 db2数据库的存储过程 网页获取数据库数据 网络安全工作措施实 健身数据库系统选择 迷你世界服务器获取的
0