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

二MyCat1.x和MyCat2的区别

MyCat1.x Vs MyCat2

功能                                                              1.6                              2
多语句                                                        不支持                        支持
blob值(二进制大对象)                         支持一部分                   支持
全局二级索引                                             不支持                        支持
任意跨库join(包含复杂查询)                catlet支持                     支持
关联子查询                                                 不支持                   支持一部分
分库同时分表(亮点)                               不支持                   支持一部分
存储过程                                               支持固定形式                 支持更多

逻辑视图                                                      不支持                       支持

物理视图                                                        支持                         支持

批量插入                                                      不支持                        支持

执行计划管理                                                不支持                       支持

路由注释                                                         支持                         支持

集群功能                                                         支持                        支持更多集群

自动hash分片算法                                         不支持                       支持

支持第三方监控                                      支持mycat-web       支持普罗米斯,kafka,日志监控 

流式合并结果集                                               支持                          支持

范围查询                                                          支持                          支持

单表映射屋里表                                              不支持                        支持

XA事务                                                            弱XA                          支持

支持mysql8                           需要修改mysql8的服务器配置支持       支持

虚拟表                                                             不支持                        支持

union all 语法                                                   不支持                        支持

三、MyCat2安装

安装参考:“Mycat2安装配置(窗外流星) · 语雀

注意:将Mycat安装包上传linux服务器之后,需要更改一下四个文件的权限为最高权限777,否则后续安装会报权限相关的错误.

四、MyCat相关概念介绍

1、分库分表

按照一定的规则把数据库中的表拆分为多个带有数据库实例,物理库,物理表访问路径的分表。

分库:一个项目多个数据库,如电商项目,可分为产品库,订单库等等

分表:一张订单表数据数百万,达到mysql数据库单表瓶颈,可以将数据分到多个数据库中的多张表。

注意:在实际项目中,分库分表往往是一块使用的

2、逻辑库

数据库代理中的数据库,他可以包含多个逻辑表

mycat里定义的库,在逻辑上存在,物理上在数据库中(如mysql)中并不存在,有可能是多个mysql数据库共同组成的一个逻辑库。

3、逻辑表

数据库代理中的表,它可以映射代理连接的数据库中的表(物理表)

mycat里定义的表,在逻辑上存在,可以映射真实的mysql数据库的表,可以一对一,也可以一对多。

4、物理库

数据库代理连接中的数据库中的库

如:mysql真实的数据库

5、物理表

数据库代理连接中的数据库中的表

如:mysql真实数据库中的真实数据表

6、拆分键

即分片键,描述拆分逻辑表的数据规则的字段

比如:订单表可以按照归属用户id拆分,用户id就是拆分键

7、物理分表

值已经进行数据拆分的,在数据库上的物理表,是分片表的一个分区。

多个物理分表里的数据汇总就是逻辑表的全部数据

8、物理分库

一般值包含多个物理分表的库,即参与数据分片的实际数据库

9、分库

一般指通过多个数据库拆分分片表,每个数据库一个物理分表,物理分库名字相同

分库是动作,需要多个数据库参与,就像多个数据库是多个盘子,分库就是把一串数据葡萄分到各个盘子里,而查询数据时,所有盘子的葡萄又通过mycat2组成了完整的一串葡萄。

10、分片表,水平分片表

按照一定规则将数据拆分成多个分区的表,在分库分表语境下,它属于逻辑表的一种,即按照逻辑拆分数据
11、单表
没有分片,没有数据冗余的表,即没有拆分数据,也没有复制数据到别的库的表
12、全局表,广播表
每个数据库实例都冗余全量数据的逻辑表
它通过表数据的冗余,使分片表的分区与该表的数据在同一个数据库实例里,达到join运算能够直接在该数据库实例里执行,
它的数据一致一般是通过数据库代理分发sql实现,也有基于集群日志的实现。
13、ER表
狭义指父子表中的字表,它的分片键指向父表的分片键,而且两表的分片算法相同。
广义指具有相同数据分布的一组表,如关联别的表的子表,订单详情表就是订单表的ER表
14、集群
多个数据节点组成的逻辑节点,在mycat2里,它是把多个数据源地址视为一个数据源地址(名称),并
提供自动故障恢复,转移,即实现高可用,负载均衡的组件,集群即高可用,负载均衡的代名词
15、数据源
连接后端数据库的组件,它是数据库代理中连接后端数据库的客户端,如mycat通过数据源连接mysql数据库
16、原型库
原型库即mycat背后的库,如mysql,oracle等真实的数据库

五、配置文件

1、服务(server) 服务相关配置在mycat/conf目录下(默认即可)

2、用户(users) 配置用户相关信息

(1)、所在目录:mycat/conf/users

(2)、命名方式:{用户名}.user.json

内容如下:
        {
        "dialect":"mysql",
        "ip":null,
        "password":"123456",
        "transactionType":"proxy",
        "username":"root"
        }
字段含义:
ip:客户端访问ip,建议为空,填写后会对客户端的ip进行限制
username:用户名
password:密码
transactionType:事务类型
可选值:
proxy:本地事务,在涉及大于1个数据库的事务,commit阶段失败会导致数据不一致,但是兼容性最好
xa事务,需要确认存储节点的集群类型是否支持xa
可以通过下列语句切换:
set.transaction_policy='xa'
set.transaction_policy='proxy'
可以通过下列语句查询
select.@@transaction_policy
3、数据源
配置mycat连接的数据源信息
(1)所在目录mycat/conf/datasource
(2)命名方式:{数据源名字}.datasource.json
(3)配置内容
  {
        "dbType":"mysql",
        "idleTimeout":60000,
        "initSqls":[],
        "initSqlsGetConnection":true,
        "instanceType":"READ_WRITE",
        "maxCon":1000,
        "maxConnectTimeout":3000,
        "maxRetryCount":5,
        "minCon":1,
        "name":"prototypeDs",
        "password":"123456",
        "type":"JDBC",
        "url":"jdbc:mysql//localhost:3306/mycatdb1?useUnicode=true&serverTimezone=Asia/Shanghai&characterEncoding=UTF-8",
        "user":"root",
        "weight":0
  }
字段介绍:
dbType:数据库类型
name:用户名
password:密码
type:数据源类型,默认jdbc
url:访问数据库地址
idleTimeout:空闲连接超时时间
initSqls:初始化sql
initSqlsGetConnection:对于jdbc每次获取连接是否执行初始化initSql
instanceType:配置实例只读还是读写,默认READ_WRITE,备选READ,WRITE
weigh:负载均衡权重
连接相关配置:
maxCon:最大连接数
maxRetryCount:最大重新连接数
maxRetryCountTime:最大重新连接时间
minCon:最小连接数
4、集群
配置集群所在目录 mycat/conf/clusters
命名方式 {集群名字}.clusters.json
配置内容:
{
    "clusterType":"MASTER_SLAVE",   //
    "heartbeat":{
    "heartbeatTimeout":1000,
    "maxRetry":3,
    "minSwitchTimeInterval":300,
    "slaveThreshold":0
    },
    "masters":[   //配置多个主节点,在主挂的时候会选一个检测存活的数据数据源作为主节点
    "prototypeDs"
    ],
    "maxCon":200,
    "name":"prototype",
    "readBalanceType":"BALANCE_ALL",
    "switchType":"SWITCH"
}
重点:
readBalanceType可选值如下:
                BALANCE_ALL(默认值):获取集群中所有数据源
                BALANCE_ALL_READ:获取集群中允许读的数据源
                BALANCE_READ_WRITE:获取集群中允许读写的数据源,但允许读的数据源优先
                BALANCE_NONE:获取集群中允许写的数据源,即主节点中选择
5、逻辑库表
配置逻辑库表,实现分库分表,配置所在目录:mycat/conf/schemas
命名方式:{库名}.schemas.json
配置内容:内容见配置
六、搭建读写分离
目标:通过mycat和mysql的主从复制配合搭建数据的读写分离,实现mysql的高可用。
1、搭建一主一从,即一个主机用于处理所有写请求,一台主机负责所有读请求,架构图如下

(1)、搭建mysql主从复制
mysql主从复制原理:

流程:主从写Binarylog,从库读取主从的Binarylog,将Binarylog写入Relaylog,再将Relaylog读取到从库的数据库。因为多次io,所以会存在延迟。
搭建方式找“度娘”,在设置mysql的主机设置binlog格式的时候,要按照实际业务需要进行合适的设置,如:binlog_format=STATEMENT,binlog_format有三个值可以设置,分别是默认值STATEMENT,ROW,MIXED。
STATEMENT: 记录所有写操作的sql到binlog日志中,从机通过复制这些sql,达到数据的一致,缺点可能会出现数据不一样的情况,如update user_info set update_time = now() where name = 'lisi';now()这个函数获取从机时间肯定要比主机时间晚。
ROW:记录每一行数据的变化,能够保证数据的强一致,缺点是如果很多行数据同时发生变化,会有性能问题MIXED:综合第一种和第二种,会对写操作进行判断,判断写操作中有没有类似now()这样的函数,如果有则用记录每行数据的变化,如果没有则记录sql语句,但是在某些特殊的场景,如果获取当前主机名词@@host name 这样的情况,也会出现无法判断导致数据的不一致问题。
(1)停止mysql的主从复制功能
stop slave;
(2)、如何重新配置主从
stop slave;
reset master;
2、配置mycat读写分离
登录mycat,创建逻辑库,配置数据源
1)在mycat里创建数据库mydb1
2)创建逻辑db2逻辑库
create database mydb1;
修改/usr/local/mycat/conf/schemas目录下的mydb1.schema.json文件,指定数据源,“targetName”:"prototype",配置主机数据源。
3)mycat2中支持注解的方式配置数据源,将下面脚本复制到连接mycat的客户端工具中进行执行即可,此配置也可以在配置文件中进行配置mycat/conf/datasources下添加配置。
/*+ mycat:createDataSource{"name":"rwSepw","url":"jdbc:mysql://localhost:3306/mydb1?useSSL=false&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true","user":"root","password":"123456"}*/
/*+ mycat:createDataSource{"name":"rwSepr","url":"jdbc:mysql://localhost:3307/mydb1?useSSL=false&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true","user":"root","password":"123456"}*/
4)通过下面脚本查看配置的数据源信息
/*+ mycat:showDataSources{} */
配置好之后会在datasource下生产读和写的数据源配置信息

5)更新集群信息,添加dr0从节点,实现读写分离
/*! mycat:createCluster{"name":"prototype","masters":["rwSepw"],"replicas":["rwSepr"]} */
6)查看配置集群信息
/*! mycat:showClusters{} */
配置好之后会在集群目录下生产集群配置信息
7)重启mycat验证读写分离
七、分库分表
    一个数据库由很多表构成,每个表对应不同的业务,垂直切分是指按照业务将表分类,分布到不同的数据库中,这样也就将数据分布到不同的库中,同时也将压力分布到不同的库中。在微服务中,如果每个服务对应了一个不同主机的数据库,这也体现了分库,比如用户服务连接A服务器的数据库,订单服务连接B服务器的数据库,仓储服务连接C服务器的数据库,这样就可以将数据库的压力分散,相比将所有数据都放在同一个数据库中,减轻了数据库压力,不会轻易达到数据库的性能瓶颈。
1、如何分库
一个问题:在两台主机上的两个数据库中的表能否关联查询?  答案:肯定是不能的
分库的原则:有紧密关联关系的表应该在一个库里,相互没有关联关系的表可以分到不同的库里。
比如在一个电商系统中,用户名中有50万数据,订单表中有800万数据,订单详情表中有1600万数据,因为订单表和订单详情表有很强的关联性,所以订单表和订单详情表必须在一个库里,而用户表和订单表没有强关联性,所以可以将用户表放到另外一个库里
2、如何分表
以订单(order)表为例,可以根据不同字段进行分表

编号

分布字段效果
1id(主键或创建时间)查询订单注重实效,历史订单被查询次数少,如此分片会造成一个节点访问多,一个节点访问少,不平衡
2customer_id(客户id)根据客户id去分,两个节点访问平均,一个客户所有订单都在同一个节点
3、实现分库分表
   mycat2有一大优势就是可以在终端创建数据源,集群,库表,并在创建时指定分库,分表。与1.6版本相比大大简化了分库分表的操作。
1)、添加数据源,存储数据源
/*+ mycat:createDataSource{
"name":"dw0",
"url":"jdbc:mysql://124.203.60.100:3306",
"user":"root",
"password":"123456"
}*/;

/*+ mycat:createDataSource{
"name":"dr0",
"url":"jdbc:mysql://124.203.60.100:3306",
"user":"root",
"password":"123456"
}*/;

/*+ mycat:createDataSource{
"name":"dw1",
"url":"jdbc:mysql://124.203.60.101:3307",
"user":"root",
"password":"123456"
}*/;

/*+ mycat:createDataSource{
"name":"dr1",
"url":"jdbc:mysql://124.203.60.101:3307",
"user":"root",
"password":"123456"
}*/;
添加完数据源信息之后,在对应的配置路径下也能看到对应的信息

2)、添加集群配置
把新添加的数据源配置成集群
/*! 
   mycat:createCluster{
     "name":"c0",
     "masters":["dw0"],
     "replicas":["dr0"]
   }
*/;

/*! 
   mycat:createCluster{
     "name":"c1",
     "masters":["dw1"],
     "replicas":["dr1"]
   }
*/;
添加之后,在mycat集群目录下也能查看到添加的信息

3)、创建全局表(全局表是指各个数据节点都需要,而且必须是全量的,比如,数据字典表)
A、创建逻辑数据库(在终端执行下列建库语句)
CREATE DATABASE db3;
B、创建表,在建表语句中加上关键字BROADCAST(广播,即为全局表)
create table db3.travelrecord(
 id bigint NOT NULL AUTO_INCREMENT,
 user_id VARCHAR(100) DEFAULT NULL,
 traveldate date DEFAULT NULL,
 fee DECIMAL(10,0) DEFAULT NULL,
 days int DEFAULT null,
 `blob` LONGBLOB,
 PRIMARY KEY (id),
 KEY id (id)
)ENGINE=INNODB DEFAULT CHARSET=utf8 BROADCAST;
在mycat/conf/schemas路径下查看db3.schema.json文件,

4)、创建分片表(分库分表)
执行下面语句创建订单表
create table db3.orders(
 id bigint NOT NULL AUTO_INCREMENT,
 order_type int,
 customer_id int,
 amount DECIMAL(10,0),
 days int DEFAULT null,
 PRIMARY KEY (id),
 KEY id (id)
)ENGINE=INNODB DEFAULT CHARSET=utf8
 dbpartition by mod_hash(customer_id) tbpartition by mod_hash(customer_id) tbpartitions 1 dbpartitions 2;
# dbpartition:数据库分片规则
# tbpartition:表分片规则
# tbpartitions:表分几片
# dbpartitions:库分几片

#添加下列几条数据

insert into orders(id,order_type,customer_id,amount) VALUES (1,101,100,100100);
insert into orders(id,order_type,customer_id,amount) VALUES (2,101,100,100300);
insert into orders(id,order_type,customer_id,amount) VALUES (3,100,101,100100);
insert into orders(id,order_type,customer_id,amount) VALUES (4,100,101,100500);
insert into orders(id,order_type,customer_id,amount) VALUES (5,102,101,100100);
insert into orders(id,order_type,customer_id,amount) VALUES (6,102,100,110100);
#查询数据
select * from orders;
​​​​​​​返回数据如下显示:

从上面的截图中可以看出数据数据返回时并不是按照我们插入的顺序返回的,而是按照customer_id分类返回的。
再次查看db3.schema.json文件内容,可以看到mycat会自动将语句中的特殊关键字转化成对应的数据写入schema文件,很是方便。

​​​​​​​物理库中数据展示


逻辑库中的数据展示

ll

 

 

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐