mycat 垂直分库与水平分表使用详解
Posted 小码农叔叔
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mycat 垂直分库与水平分表使用详解相关的知识,希望对你有一定的参考价值。
前言
在上一篇 mycat环境搭建 的最后,分享了一个简单的使用mycat进行数据分片的案例配置,大致了解了如何使用mycat,本篇将在此基础上继续探讨mycat提供的常用的分片规则;
mycat 配置文件说明
在了解mycat的常用分片规则之前,有必要再对涉及到分片规则相关的几个配置文件做深入的了解,包括:schema.xml,server.xml,rule.xml等;
其中,最核心的schema.xml文件是配置分片规则的入口文件,有必要对该配置文件中的关键参数做了解,且看下面这幅图,回顾下里面的配置;
一、schema.xml
MyCat中最重要的配置文件之一 , 涵盖了MyCat的逻辑库 、 逻辑表 、 分片规则、分片节点及数据源的配置;从上面的截图来看,主要包含以下三组标签:
- schema标签;
- datanode标签;
- datahost标签;
schema 标签用于定义 MyCat实例中的逻辑库
一个MyCat实例, 可以有多个逻辑库 , 可以通过 schema 标签来划分不同的逻辑库。MyCat中的逻辑库的概念,类似于mysql中的database概念, 需要操作某个逻辑库下的表时, 也需要切换到目标逻辑库下;
schema 标签的核心属性包括:
- name:指定自定义的逻辑库库名(访问时需要在server.xml中配置);
- checkSQLschema:在SQL语句操作时指定了数据库名称,执行时是否自动去除;true:自动去除,false:不自动去除;
- sqlMaxLimit:如果指定了limit进行查询,列表查询默认查询指定的数量的记录;
1、table标签,用于定义逻辑表
table 标签定义了MyCat中某个逻辑库schema下的逻辑表 , 所有需要拆分的表都在table标签中定义;
table标签中的核心属性主要包括下面几个:
- name:定义逻辑表表名,在该逻辑库下唯一;
- dataNode:定义逻辑表所属的dataNode,该属性需要与dataNode标签中name对应,多个dataNode逗号分隔;
- rule:分片规则的名字,分片规则名字是在rule.xml中定义的;
- primaryKey:逻辑表对应真实表的主键;
- type:逻辑表的类型,目前逻辑表只有全局表和普通表,如果未配置,就是普通表;全局表,配置为 global;
2、datanode标签
核心属性包括:
- name:定义数据节点的名称;
- dataHost:数据库实例主机名称(配置物理节点的位置),引用自 dataHost 标签中name属性;
- database:定义分片所属数据库;
3、datahost标签
datahost 在MyCat逻辑库中作为底层标签存在, 直接定义了具体的物理数据库实例、读写分离、心跳检测语句;
核心属性如下:
- name:唯一标识,供上层标签使用;
- maxCon/minCon:最大连接数/最小连接数;
- balance:负载均衡策略,取值 0,1,2,3;
- writeType:写操作分发方式(0:写操作转发到第一个writeHost,第一个挂了,切换到第二个;1:写操作随机分发到配置的writeHost);
- dbDriver:数据库驱动,支持 native、jdbc;
二、 rule.xml
rule.xml 文件中,定义了所有拆分表的规则, 在使用过程中可以根据业务需要灵活选择不同的分片算法, 或者对同一个分片算法使用不同的参数, 支持让分片过程可配置化,主要包含两类标签:tableRule、Function。
还记得在上一篇最后的演示demo中,schema 标签中配置的默认的那个分表规则吗?其对应的规则就在 rule.xml文件中;
三、 server.xml
server.xml配置文件主要是定义了MyCat的系统相关的配置信息,其中主要有两个重要标签:system、user
system:主要配置MyCat中的系统配置的参数信息,这个可以从官网或者相关的资料中查到各个配置的含义,就不再一一列举了;
user:配置MyCat中客户端访问的用户名、密码,以及用户针对于逻辑库、逻辑表的权限信息,具体的权限描述方式及配置说明如下
如果需要配置操作权限时,只要将 privileges 标签的注释放开。 在 privileges 下的schema标签中配置的dml属性配置的是逻辑库的权限,用数字表示。 在privileges的schema下的table标签的dml属性中配置逻辑表的权限。
mycat 常用分片规则
四、数据库垂直拆分
系统在运行过程中,随着业务越来越复杂,表也越来越多,从数据库这一层来说,当单库的表增加到一定数量后,由单台服务器的数据存储及处理能力是有限的,所以当业务高峰期时,必然有一部分业务操作表的时处于等待状态,如何解决这个问题呢?
容易想到,将单库下N多张表拆分到多个数据库下,降低单库的表的总量不失为不错的方案,这就是数据库的垂直拆分;
下图为单库下的多个表,通过垂直拆分之后,多个表将会被分散到多个数据库存储;
那么通过mycat的schema.xml文件的配置,最终可得到如下结构图:
接下来按照上面图中的规划,实际操作下数据库的垂直拆分过程吧
1、数据准备
分别创建3张表,建表sql如下
CREATE TABLE `TB_USER` (
`id` bigint(20) NOT NULL,
`username` varchar(100) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `TB_PRODUCT` (
`id` bigint(20) NOT NULL,
`productname` varchar(100) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `TB_ORDER` (
`id` bigint(20) NOT NULL,
`ordername` varchar(100) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
2、schema.xml 配置
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
<schema name="DB02" checkSQLschema="true" sqlMaxLimit="100">
<table name="tb_user" dataNode="dn1" primaryKey="id" />
<table name="tb_product" dataNode="dn2" primaryKey="id" />
<table name="tb_order" dataNode="dn3" primaryKey="id" />
</schema>
<dataNode name="dn1" dataHost="dhost1" database="db01" />
<dataNode name="dn2" dataHost="dhost2" database="db01" />
<dataNode name="dn3" dataHost="dhost3" database="db01" />
<dataHost name="dhost1" maxCon="1000" minCon="10" balance="0"
writeType="0" dbType="mysql" dbDriver="jdbc" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<writeHost host="hostM1" url="jdbc:mysql://IP1:3306" user="root"
password="123456">
</writeHost>
</dataHost>
<dataHost name="dhost2" maxCon="1000" minCon="10" balance="0"
writeType="0" dbType="mysql" dbDriver="jdbc" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<writeHost host="hostM1" url="IP2" user="root"
password="123456">
</writeHost>
</dataHost>
<dataHost name="dhost3" maxCon="1000" minCon="10" balance="0"
writeType="0" dbType="mysql" dbDriver="jdbc" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<writeHost host="hostM1" url="IP3" user="root"
password="123456">
</writeHost>
</dataHost>
</mycat:schema>
3、server.xml 配置
<user name="root" defaultAccount="true">
<property name="password">123456</property>
<property name="schemas">DB02</property>
<property name="defaultSchema">DB02</property>
</user>
配置完毕后,重启mycat服务,然后使用客户端连接mycat,并执行上面的sql建表语句
执行成功后,去各自的数据库实例下检查相关的表,可以看到三张表分别落到不同的数据实例下面了
五、表的水平拆分
在上一篇概述中,我们谈到,当单表数据量达到一定的量级之后,一定会产生性能问题,解决这个问题比较好的方式就是将表的数据分散到多张表进行存储,这样就把单表的数据量给降下去了;
最终映射到schema.xml中的分片规则配置如下图所示
1、前置准备
提前在三个数据库实例下创建三个数据库,这里名叫:dblog
2、准备一张数据表
CREATE TABLE `TB_LOG` (
`id` bigint(20) NOT NULL,
`details` varchar(100) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
3、schema.xml 配置
下面贴出核心配置
<schema name="DB02" checkSQLschema="true" sqlMaxLimit="100">
<table name="tb_log" dataNode="dn1,dn2,dn3" primaryKey="id" rule="mod-long" />
</schema>
<dataNode name="dn1" dataHost="dhost1" database="dblog" />
<dataNode name="dn2" dataHost="dhost2" database="dblog" />
<dataNode name="dn3" dataHost="dhost3" database="dblog" />
4、重启mycat服务
注意:如果配置文件中语法格式有错误,或者任意一个数据库连接出现异常,启动的时候都会报 “stop” ,所以配置的时候一定要小心。
5、连接mycat客户端,并使用上面的sql创建表
创建完毕后,在三个数据库实例下检查是否创建成功
创建成功后,让我们来随机插入几条数据测试下效果吧
INSERT into TB_LOG(id,details) values(1,"测试1");
INSERT into TB_LOG(id,details) values(2,"测试2");
INSERT into TB_LOG(id,details) values(3,"测试3");
INSERT into TB_LOG(id,details) values(5,"测试5");
执行成功后,分别检查3个数据库实例表的数据
从这个效果来看也是符合预期的,因为本次我们配置的分片规则是求模,即按照求模的结果分别定位到3个不同的分片节点上,这种分配规则下,可以基本上实现数据分布相对均匀的效果。
以上是关于mycat 垂直分库与水平分表使用详解的主要内容,如果未能解决你的问题,请参考以下文章