MyCat分库分表高级教程

Posted AAA教育张晨光

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MyCat分库分表高级教程相关的知识,希望对你有一定的参考价值。

1.课程回顾

2,本章重点

数据库拆分方式种类和优缺点

mycat横向切分如何实现

分表分库后,表中主键如何生成

3.具体内容

3.1 数据切分概念

简单来说,就是指通过某种特定的条件,将我们存放在同一个数据库中的数据分散存放到多个数据库(主机) 上面,以达到分散单台设备负载的效果。

3.2 切分种类及优缺点

3.2.1 的垂直(纵向)切分

概念:

一种是按照不同的表(或者Schema)来切分到不同的数据库(主机)之上,这种切可以称之为数据的垂直(纵向)切分

使用场景:

垂直切分的最大特点就是规则简单,实施也更为方便,尤其适合各业务之间的耦合度非常低,相互影响很小, 业务逻辑非常清晰的系统。在这种系统中,可以很容易做到将不同业务模块所使用的表分拆到不同的数据库中。(尤其是微服务项目,更适合按照不同微服务的功能,然后把数据库表也分开)

具体实现:

优点:

 

• 拆分后业务清晰,拆分规则明确;

• 系统之间整合或扩展容易;(微服务更适合敏捷开发,每个服务都使用自己的一套表)

• 数据维护简单。

缺点:

• 部分业务表无法 join,只能通过接口方式解决,提高了系统复杂度;

• 受每种业务不同的限制存在单库(单表数据库很大)性能瓶颈,不易数据扩展跟性能提高;

• 事务处理复杂(分布式事务,单应用事务无法解决问题)

3.2.2 水平(横向)切分

概念:

根据 表中的数据的逻辑关系,将同一个表中的数据按照某种条件拆分到多台数据库(主机)上面,这种切分称之为数 据的水平(横向)切分

使用场景:

水平切分于垂直切分相比,相对来说稍微复杂一些。因为要将同一个表中的不同数据拆分到不同的数据库中, 对于应用程序来说,拆分规则本身就较根据表名来拆分更为复杂,后期的数据维护也会更为复杂一些。(mycat 主要实现的就是这个功能)

关系型数据库本身比较容易成为系统瓶颈,单机存储容量、连接数、处理能力都有限。当单表的数据量达到1000W或100G以后,由于查询维度较多,即使添加优化从库(读负载均衡)、优化索引,做很多操作时性能仍下降严重。此时就要考虑对其进行切分了,切分的目的就在于减少数据库的负担,缩短查询时间。

具体实现:

 

user1,user2,user3并不是指三个库中表的名称,表名称是一样的 user1用户表的第一部分数据 user2用户表的第二部分数据。。。

相对于垂直拆分,水平拆分不是将表做分类,而是按照某个字段的某种规则来分散到多个库之中,每个表中 包含一部分数据。简单来说,我们可以将数据的水平切分理解为是按照数据行的切分,就是将表中的某些行切分 到一个数据库,而另外的某些行又切分到其他的数据库中,

水平切分常见分片规则:

• 按照用户 ID 求模,将数据分散到不同的数据库,具有相同数据用户的数据都被分散到一个库中;

• 按照日期,将不同月甚至日的数据分散到不同的库中; 

 

优点:

• 拆分规则抽象好,join 操作基本可以数据库做(mycat 可以使用join);

• 不存在单库大数据(数据量大的表都被拆分),提升高并发的性能瓶颈;

• 应用端改造较少(数据拆分后,业务项目中mybatis语句不用做任何更改);

• 提高了系统的稳定性跟负载能力。

缺点:

• 拆分规则难以抽象(实际开发应用过程,可能表存的数据列复杂);

• 分片事务一致性难以解决(一次插入10条数据,有5条向db1中添加,有另外5条向db2中添加);

• 数据多次扩展难度跟维护量极大;

• 跨库 join 性能较差(跨网络。。。)。 

3.3 mycat实现分表分库

3.3.1 准备工作

需求:假如用户数据量非常大,想切分用户表数据

正常方式,需要再克隆5台独立mysql服务器,都安装mysql数据,再克隆一台mycat服务器,进行分表分库配置。

本节课,为了节省时间,使用mycat做读写分离的所有服务器。

首先要把mysql数据库服务器都启动起来,然后去除主从关系(一旦服务器重启,主从关系依然存在)。

查看mysqld服务是否启动:

service mysqld status

登录(allsession中操作):

mysql -uroot -ptiger

查看从服务状态:

show slave status \\G;

关闭主从关系:

stop slave; 注意,再次启动启动服务器,主从关系依然启动,可能再次去除

创建5个数据库:

db_sharding_test1,db_sharding_test2,db_sharding_test3,db_sharding_test4,db_sharding_test5(同时在mysql4上) 因为关闭主从关系,所以创建库时其他服务器上没有

在5个库中分别创建表:

create table tb_user(

   user_id  int  primary key comment '主键不自增',

   user_name  varchar(20) comment '用户名',

   real_name  varchar(30) comment '真实姓名',

   salary   double  comment '薪酬' ,

   hiredate  date  comment '雇佣时间'

);

在5个库中都要执行

3.3.2 server.xml配置

如果修改前面mycat读写分离的配置,非常麻烦,所以再解压一份mycat,不再配置环境变量,直接在新解压的mycat中配置分表分库。

启动mycat服务器,并使用xshell进行连接。

在/usr下创建mycat-shard目录:

mkdir  /usr/mycat-shard

解压mycat压缩包到该目录:

tar -xzvf /root/software/Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz -C /usr/mycat-shard/

修改server.xml配置:

 

vim /usr/mycat-shard/mycat/conf/server.xml

 

3.3.3 schema.xml配置

vim /usr/mycat-shard/mycat/conf/schema.xml

<table>分片表:

分片表,是指那些原有的很大数据的表,需要切分到多个数据库的表,这样,每个分片都有一部分数据,所 有分片构成了完整的数据。

<table rule=""> rule 属性 配置分片规则:

前面讲了数据切分,一个大表被分成若干个分片表,就需要一定的规则,这样按照某种业务规则把数据分到 某个分片的规则就是分片规则,数据切分选择合适的分片规则非常重要,将极大的避免后续数据处理的难度

 

 

3.3.4 分片规则配置 rule.xml id取模方式分片

rule.xml 里面就定义了我们对表进行拆分所涉及到的规则定义。我们可以灵活的对表使用不同的分片算法, 或者对表使用相同的算法但具体的参数不同。这个文件里面主要有 tableRule 和 function 这两个标签。在具体使 用过程中可以按照需求添加 tableRule 和 function。

tableRule:

<tableRule name="r1"><rule><columns>分片列</columns><algorithm>算法规则</algorithm></tableRule> 这个标签定义表分片规则。

name 属性指定唯一的名字,用于标识不同的表规则。 内嵌的 rule 标签则指定对物理表中的哪一列进行拆分和使用什么路由算法。

columns 内指定要拆分的列名字。

algorithm 使用 function 标签中的 name 属性。连接表规则和具体路由算法

function:

 <function name="xxx"

                class="XXX">

                <property name="paramName">paramValue</property>

        </function>

name 指定算法的名字。

class 制定路由算法具体的类名字。

property 为具体算法需要用到的一些属性。

vim /usr/mycat-shard/mycat/conf/rule.xml 

配置自己分片:

 

 

 

3.3.5 id取模方式测试

启动mycat : 注意是 /usr/mycat-shard/mycat

 /usr/mycat-shard/mycat/bin/mycat start

测试添加:11%5 =1   12 %5 =2   13%5=3  14%5 =4   15%5=0 1005%5=0 1006%5=1 .......

insert tb_user(user_id,user_name,real_name,salary,hiredate) values(11,'zhangsan1','张三1',20000,'2022-04-04');



insert tb_user(user_id,user_name,real_name,salary,hiredate) values(12,'zhangsan1','张三2',21000,'2022-04-04');



insert tb_user(user_id,user_name,real_name,salary,hiredate) values(13,'zhangsan1','张三3',20000,'2022-04-04');



insert tb_user(user_id,user_name,real_name,salary,hiredate) values(14,'zhangsan1','张三4',20000,'2022-04-04');



insert tb_user(user_id,user_name,real_name,salary,hiredate) values(15,'zhangsan1','张三5',20000,'2022-04-04');



insert tb_user(user_id,user_name,real_name,salary,hiredate) values(16,'zhangsan1','张三7',30000,'2022-04-04');



insert tb_user(user_id,user_name,real_name,salary,hiredate) values(17,'zhangsan1','张三7',20000,'2022-04-04');





insert tb_user(user_id,user_name,real_name,salary,hiredate) values(1005,'zhangsan1','张三5',20000,'2022-04-04');



insert tb_user(user_id,user_name,real_name,salary,hiredate) values(1006,'zhangsan1','张三7',30000,'2022-04-04');



insert tb_user(user_id,user_name,real_name,salary,hiredate) values(1007,'zhangsan1','张三7',20000,'2022-04-04');



insert tb_user(user_id,user_name,real_name,salary,hiredate) values(1008,'zhangsan1','张三5',20000,'2022-04-04');



insert tb_user(user_id,user_name,real_name,salary,hiredate) values(1009,'zhangsan1','张三7',30000,'2022-04-04');



insert tb_user(user_id,user_name,real_name,salary,hiredate) values(1010,'zhangsan1','张三7',20000,'2022-04-04');



-- mycat 会自动合并数据集

select * from tb_user;

-- 支持排序

select * from tb_user order by user_id;

3.3.6 分片规则配置role.xml 自然月方式分片

vim /usr/mycat-shard/mycat/conf/rule.xml

 

 schema.xml配置:

重启mycat:

 

  /usr/mycat-shard/mycat/bin/mycat stop

  /usr/mycat-shard/mycat/bin/mycat start

3.3.7 自然月方式测试

insert tb_user(user_id,user_name,real_name,salary,hiredate) values(113,'zhangsan1','张三3',20000,'2022-01-04');



insert tb_user(user_id,user_name,real_name,salary,hiredate) values(114,'zhangsan1','张三4',20000,'2022-01-14');



insert tb_user(user_id,user_name,real_name,salary,hiredate) values(115,'zhangsan1','张三5',20000,'2022-01-24');



insert tb_user(user_id,user_name,real_name,salary,hiredate) values(116,'zhangsan1','张三7',30000,'2022-02-04');



insert tb_user(user_id,user_name,real_name,salary,hiredate) values(117,'zhangsan1','张三7',20000,'2022-02-14');





insert tb_user(user_id,user_name,real_name,salary,hiredate) values(105,'zhangsan1','张三5',20000,'2022-03-04');



insert tb_user(user_id,user_name,real_name,salary,hiredate) values(106,'zhangsan1','张三7',30000,'2022-03-24');



insert tb_user(user_id,user_name,real_name,salary,hiredate) values(107,'zhangsan1','张三7',20000,'2022-03-14');



insert tb_user(user_id,user_name,real_name,salary,hiredate) values(108,'zhangsan1','张三5',20000,'2022-04-04');



insert tb_user(user_id,user_name,real_name,salary,hiredate) values(109,'zhangsan1','张三7',30000,'2022-04-04');



insert tb_user(user_id,user_name,real_name,salary,hiredate) values(110,'zhangsan1','张三7',20000,'2022-05-04');

一定是按照自然月分片(从2022-01-01开始,最多到5月,因为就5个库):

//错误Can't find a valid data node for specified node index :TB_USER -> HIREDATE -> 2022-07-04 -> Index : 5

insert tb_user(user_id,user_name,real_name,salary,hiredate) values(110,'zhangsan1','张三7',20000,'2022-06-04');

//错误Can't find a valid data node for specified node index :TB_USER -> HIREDATE -> 2022-07-04 -> Index : 6

insert tb_user(user_id,user_name,real_name,salary,hiredate) values(110,'zhangsan1','张三7',20000,'2022-07-04');

更多分片规则参考:

 

3.4 mycat 全局序列号

概念:

在实现分库分表的情况下,数据库自增主键已无法保证自增主键的全局唯一。为此,MyCat 提供了全局 sequence,并且提供了包含本地配置和数据库配置等多种实现方式。

本地配置原理:

此方式 MyCAT 将 sequence 配置到文件中,当使用到 sequence 中的配置后,MyCAT 会更下 classpath 中的 sequence_conf.properties 文件中 sequence 当前的值。

具体实现:

vim /usr/mycat-shard/mycat/conf/sequence_conf.properties 

 

vim /usr/mycat-shard/mycat/conf/server.xml

具体使用:

 

重启mycat服务

/usr/mycat-shard/mycat/bin/mycat restart

多次执行下面语句:

insert tb_user(user_id,user_name,real_name,salary,hiredate) values(next value for MYCATSEQ_GLOBAL,'zhangsan1','张三7',20000,'2022-01-04');

切换分片规则:

 vim /usr/mycat-shard/mycat/conf/schema.xml 

 

重启mycat服务

/usr/mycat-shard/mycat/bin/mycat restart

多次执行下面语句:

insert tb_user(user_id,user_name,real_name,salary,hiredate) values(next value for MYCATSEQ_GLOBAL,'zhangsan1','张三7',20000,'2022-01-04');

以上是关于MyCat分库分表高级教程的主要内容,如果未能解决你的问题,请参考以下文章

Mycat快速入门: Mycat分库分表案例

这个教程不错!用数据库中间件Mycat+SpringBoot实现分库分表~

通过Mycat的分库分表案例来培养架构思维

MySQL+MyCat分库分表 读写分离配置MySQL+MyCat分库分表 读写分离配置

mycat怎么操作oracle做分库分表的操作

Mycat+分库分表