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 垂直分库与水平分表使用详解的主要内容,如果未能解决你的问题,请参考以下文章

Mycat+分库分表

mycat-分库分表

Mycat 读写分离+分库分表

MyCat分库分表-练习

MySQL:如何使用MyCAT实现分库分表?

基于mycat高可用方案——数据库负载