比较好的高端网站制作公司,定陶菏泽网站建设,秀米编辑器,陕西网站制作电话3.分库分表
3.1 介绍
3.1.1 问题分析
使用单个数据库存储所有的数据#xff0c;如果磁盘和内存和内存不足了可以增大磁盘和内存#xff0c;但是对于一台服务器的磁盘和内存不可能无限制的扩张下去#xff0c;它是受我们服务器的硬件影响的#xff0c;如果说数据库所存储…3.分库分表
3.1 介绍
3.1.1 问题分析
使用单个数据库存储所有的数据如果磁盘和内存和内存不足了可以增大磁盘和内存但是对于一台服务器的磁盘和内存不可能无限制的扩张下去它是受我们服务器的硬件影响的如果说数据库所存储的数据还在不断增加那么会带来数据库的性能问题。而此时前端的程序还在持续频繁的去请求数据库那么数据库的访问压力会变得非常大。 随着互联网及移动互联网的发展应用系统的数据量也是成指数式增长若采用单数据库进行数据存储存在以下性能瓶颈 IO瓶颈热点数据太多数据库缓存不足产生大量磁盘IO效率较低。 请求数据太多带宽不够网络IO瓶颈。 在InnoDB存储引擎中有很大一部分的内存都分配给了缓存区如果服务器的内存不足那么缓冲区分配的空间也会不足缓冲区不足会造成缓冲区缓冲的数据变少了这个时候就会产生大量的磁盘Io。大量的请求过来会占用大量的网络带宽网络io瓶颈。 CPU瓶颈大量用户请求过来用户在查询时所涉及到的排序、分组、连接查询、聚合统计等这些SQL会耗费大量的CPU资源请求数太多CPU出现瓶颈。
为了解决上述问题我们需要对数据库进行分库分表处理。
分库分表的中心思想都是将数据分散存储使得单一数据库/表的数据量变小来缓解单一数据库的性能 问题从而达到提升数据库性能的目的。
3.1.2 拆分策略
分库分表的形式主要是两种垂直拆分和水平拆分。而拆分的粒度一般又分为分库和分表所以组成的拆分策略最终如下
分库指的是对一个数据库进行拆分将一个数据库中的数据分散存储在多个数据库当中。分表指的是对表结构进行拆分原来存储在一张表结构当中的数据现在我要分散地存储在多张表结构当中 3.1.3 垂直拆分
1.垂直分库 垂直分库以表为依据根据业务将不同表拆分到不同库中。
场景一台数据库中存储了6张表以表为单位进行拆分根据业务将用户表相关的表结构拆分到一个服务器订单相关的表结构拆分到第二台服务器中商品相关的表结构拆分到第三台服务器中。
特点
每个库的表结构都不一样。每个库的数据也不一样。所有库的并集是全量数据。
2.垂直分表 垂直分表以字段为依据根据字段属性将不同字段拆分到不同表中。
场景数据库当中有一张表这张表的数据量特别大而且用户访问频次特别高这样就会造成这台数据库的压力特别大。解决可以对这张表进行拆分以这张表的字段为依据拆分为2张表这2张表可以位于不同的服务器当中这样就缓解了单台数据库服务器的访问压力。
特点
每个表的结构都不一样。每个表的数据也不一样一般通过一列主键/外键关联。所有表的并集是全量数据。
3.1.4 水平拆分
1.水平分库
水平分库以字段为依据按照一定策略将一个库的数据拆分到多个库中。
场景单台数据库此时有2张表拆分后此时这三个数据库当中将都会存储这两张表虽然里面的表结构一样但是所涉及到的数据不同也就是说对于tb_order这张表来说有一部分数据是存放在第一个数据库当中的有一部分存储在第二个数据库中有一部分存储在第三个数据库服务器中。总结原来一张表中的数据现在分散地存储在这三个数据库当中的三张表中。
特点
每个库的表结构都一样。每个库的数据都不一样。所有库的并集是全量数据。
2.水平分表
水平分表以字段为依据按照一定策略将一个表的数据拆分到多个表中。
他不会再将这张表结构拆分而是对tb_order这张表的数据进行拆分也就意味着将tb_order这张表的数据分散存储在这三台服务器中这三台数据库服务器所存放的表结构相同表中的数据不同。总结原来这一张表存放的数据现在分散的存储在这3台数据库服务器中的3张表结构中每个表结构相同数据不同。
特点
每个表的表结构都一样。每个表的数据都不一样。所有表的并集是全量数据。 在业务系统中为了缓解磁盘IO及CPU的性能瓶颈到底是垂直拆分还是水平拆分具体是分库还是分表都需要根据具体的业务需求具体分析。 3.1.5 实现技术
问题
以前我们的应用程序直接去访问一个数据库就可以了现在对数据库进行拆分之后现在应用程序需要访问多个数据库服务器那假如说我们的设置的拆分策略为根据id进程拆分如果id取模等于0则访问第一个数据库等于1访问第二个数据库等于2访问第三个数据库也就意味着原来只需要操作一个数据库现在要操作三个数据库而且在应用程序中我们还需要自行根据当前业务的执行来决定当前要操作哪一个数据库这就造成用程序的编写代码难度将会增大而且处理起来相当繁琐。甚至对拆分后的数据库又搭建了主从结构那么此时应用程序的操作将会更加繁琐。
解决 shardingJDBC基于AOP原理在应用程序中对本地执行的SQL进行拦截解析、改写、路由处理。需要自行编码配置实现只支持java语言性能较高。 MyCat数据库分库分表中间件不用调整代码即可实现分库分表支持多种语言性能不及前者。
什么叫数据库分库分表中间件
我们使用了MyCat之后应用程序你不需要做任何改动也不用考虑每次需要连接的是哪一个数据库而且也不需要在应用程序中去集成任何第三方的依赖也不用做编码和配置。有了这个中间件之后应用程序在访问的时候不用直接访问数据库直接访问的是MyCat中间件而我们访问MyCat就和访问mysql是一样的对应用程序来说它是无感知的。
本次课程我们选择了是MyCat数据库中间件通过MyCat中间件来完成分库分表操作。
3.2 MyCat概述
3.2.1 介绍
Mycat阿里的是开源的、活跃的、基于Java语言编写的MySQL数据库中间件。可以像使用mysql一样来使用mycat对于开发人员来说根本感觉不到mycat的存在。
原理MyCat伪装了mysql的协议所以就可以把mycat看作成一台mysql。对于我们的应用程序来说完全可以不关心你用的是mysql还是mycat只需要把数据库的连接换为mycat就可以了连驱动都不用换。
开发人员只需要连接MyCat即可而具体底层用到几台数据库每一台数据库服务器里面存储了什么数据都无需关心。 具体的分库分表的策略只需要在MyCat中配置即可。 优势
性能可靠稳定强大的技术团队体系完善社区活跃
3.2.2 下载
官网 http://www.mycat.org.cn/
2版本出来没多久所以这里选择比较稳定的版本1.6 3.2.3 安装
Mycat是采用java语言开发的开源的数据库中间件支持Windows和Linux运行环境下面介绍MyCat的Linux中的环境搭建。我们需要在准备好的服务器中安装如下软件。
MySQL 因为最终数据是存储在mysql当中的mycat仅仅是一个中间件他不存储数据。 JDK 因为它是基于java语言开发的所以需要安装java的运行环境 Mycat
服务器安装软件说明192.168.10.210JDK、MycatMyCat中间件服务器192.168.10.210MySQL分片服务器192.168.10.213MySQL分片服务器192.168.10.214MySQL分片服务器
占用磁盘太大了测试完成后删了。 具体的安装步骤 参考资料中提供的 《MyCat安装文档》即可里面有详细的安装及配置步骤。mycat安装的博客地址
3.2.4 目录介绍
进入解压后生成的mycat目录 bin : 存放可执行文件用于启动停止mycatconf存放mycat的配置文件lib存放mycat的项目依赖包jarlogs存放mycat的日志文件
进入存放jar包的目录可以看到这个自带的mysql驱动版本的包比较低我们现在使用的mysql版本是8.0.26所以需要替换掉这个驱动包
cd libll在lib目录下删除此驱动包
rm -rf mysql-connector-java-5.1.35.jar重新上传一份驱动包到lib目录 ll查看发现此jar包为红色因为它的权限不够所以还要进行授权。 chmod 777 mysql-connector-java-8.0.22.jar#再次查看就变为绿色了
ll3.2.5 概念介绍
在MyCat的整体结构中分为两个部分上面的逻辑结构、下面的物理结构。 在MyCat的逻辑结构主要负责逻辑库、逻辑表、分片规则、分片节点等逻辑结构的处理而具体的数据存储还是在物理结构也就是数据库服务器中存储的。
在后面讲解MyCat入门以及MyCat分片时还会讲到上面所提到的概念。
3.3 MyCat入门水平分表
3.3.1 需求
由于 tb_order 表中数据量很大磁盘IO及容量都到达了瓶颈现在需要对 tb_order 表进行数据分片分为三个数据节点每一个节点主机位于不同的服务器上, 具体的结构参考下图
水平分表
3.3.2 环境准备
准备3台服务器
192.168.10.210MyCat中间件服务器同时也是第一个分片服务器。192.168.10.213第二个分片服务器。192.168.10.214第三个分片服务器。 并且在上述3台数据库中创建数据库 db01 。 说明
底层的数据库的准本工作做完了现在这3台mysql我们就不要在动了不要在这3台数据库上创建表也不要去执行一些增删改的操作。现在所有的操作都是针对于mycat所以接下来呢我们就需要在mycat当中来配置当前tb_order表的分表的一些策略
3.3.3 配置
1).schema.xml
在schema.xml中配置逻辑库、逻辑表、数据节点、节点主机等相关信息。具体的配置如下
#存放在mycat解压后的conf目录
cd /usr/local/src/MyCat/mycat/conf/#也可以直接在远程工具中使用记事本打开左侧的文件这样更方便。
vim schema.xml精简完毕后的内容
?xml version1.0?
!DOCTYPE mycat:schema SYSTEM schema.dtd
mycat:schema xmlns:mycathttp://io.mycat/!--schema标签配置逻辑库name属性逻辑库的名字后2个属性后面讲。 --schema nameDB01 checkSQLschematrue sqlMaxLimit100!--table标签配置逻辑库中的逻辑表一个逻辑库下面可以包含多个逻辑表dataNode这个逻辑表关联的数据节点有几个rule分片规则暂时使用官方默认的分片规则--table nameTB_ORDER dataNodedn1,dn2,dn3 ruleauto-sharding-long //schema!--dataNode:具体的数据节点 dataHost配置该数据节点关联的节点主机 database关联该节点主机下的哪个数据库这3台数据库都是db01--dataNode namedn1 dataHostdhost1 databasedb01 /dataNode namedn2 dataHostdhost2 databasedb01 /dataNode namedn3 dataHostdhost3 databasedb01 /!--dataHost具体配置的是数据库的连接信息maxCon最大连接数minCon最小连接数balance负载均衡的策略这些参数暂时不用管只需要改一个参数dbDrivermysql8.0暂时只支持jdbc的连接方式不支持native--dataHost namedhost1 maxCon1000 minCon10 balance0writeType0 dbTypemysql dbDriverjdbc switchType1 slaveThreshold100!--heartbeat心跳不用管--heartbeatselect user()/heartbeat!--writeHost当前mycat中的这个节点主机所关联的数据库的连接信息host这个名字无所谓--writeHost hostmaster urljdbc:mysql://192.168.10.210:3306?useSSLfalseamp;serverTimezoneAsia/Shanghaiamp;characterEncodingutf8 userroot password1234 //dataHostdataHost namedhost2 maxCon1000 minCon10 balance0writeType0 dbTypemysql dbDriverjdbc switchType1 slaveThreshold100heartbeatselect user()/heartbeatwriteHost hostmaster urljdbc:mysql://192.168.10.213:3306?useSSLfalseamp;serverTimezoneAsia/Shanghaiamp;characterEncodingutf8 userroot password1234 //dataHostdataHost namedhost3 maxCon1000 minCon10 balance0writeType0 dbTypemysql dbDriverjdbc switchType1 slaveThreshold100heartbeatselect user()/heartbeatwriteHost hostmaster urljdbc:mysql://192.168.10.214:3306?useSSLfalseamp;serverTimezoneAsia/Shanghaiamp;characterEncodingutf8 userroot password1234 //dataHost/mycat:schema
去掉注释后的内容
?xml version1.0?
!DOCTYPE mycat:schema SYSTEM schema.dtd
mycat:schema xmlns:mycathttp://io.mycat/schema nameDB01 checkSQLschematrue sqlMaxLimit100table nameTB_ORDER dataNodedn1,dn2,dn3 ruleauto-sharding-long //schemadataNode namedn1 dataHostdhost1 databasedb01 /dataNode namedn2 dataHostdhost2 databasedb01 /dataNode namedn3 dataHostdhost3 databasedb01 /dataHost namedhost1 maxCon1000 minCon10 balance0writeType0 dbTypemysql dbDriverjdbc switchType1 slaveThreshold100heartbeatselect user()/heartbeatwriteHost hostmaster urljdbc:mysql://192.168.10.210:3306?useSSLfalseamp;serverTimezoneAsia/Shanghaiamp;characterEncodingutf8 userroot password1234 //dataHostdataHost namedhost2 maxCon1000 minCon10 balance0writeType0 dbTypemysql dbDriverjdbc switchType1 slaveThreshold100heartbeatselect user()/heartbeatwriteHost hostmaster urljdbc:mysql://192.168.10.213:3306?useSSLfalseamp;serverTimezoneAsia/Shanghaiamp;characterEncodingutf8 userroot password1234 //dataHostdataHost namedhost3 maxCon1000 minCon10 balance0writeType0 dbTypemysql dbDriverjdbc switchType1 slaveThreshold100heartbeatselect user()/heartbeatwriteHost hostmaster urljdbc:mysql://192.168.10.214:3306?useSSLfalseamp;serverTimezoneAsia/Shanghaiamp;characterEncodingutf8 userroot password1234 //dataHost/mycat:schema
2).server.xml
需要在server.xml中配置用户名、密码以及用户的访问权限信息具体的配置如下 同样在这个目录下
cd /usr/local/src/MyCat/mycat/conf/配置内容其它的配置信息到下面讲解这里只配置需要修改的部分内容 user nameroot defaultAccounttrue!--登录mycat的密码123456--property namepassword123456/property!--root用户访问的逻辑库是哪个--property nameschemasDB01/property!--没有配置说明既能读又能写--!-- 表级 DML 权限设置 --!-- privileges checkfalseschema nameTESTDB dml0110 table nametb01 dml0000/tabletable nametb02 dml1111/table/schema/privileges --/useruser nameuserproperty namepassword123456/property!--user用户访问的逻辑库是哪个--property nameschemasDB01/property!--配置只能够读--property namereadOnlytrue/property/user上述的配置表示定义了两个用户 root 和 user 这两个用户都可以访问 DB01 这个逻辑库访问密码都是123456但是root用户访问DB01逻辑库既可以读又可以写但是 user用户访问DB01逻辑库是只读的。
3.3.4 测试
3.3.4.1 启动
配置完毕后先启动涉及到的3台分片服务器然后启动MyCat服务器。切换到Mycat的安装目录执行如下指令启动Mycat
#注意不能到bin目录下
cd /usr/local/src/MyCat/mycat/#启动
bin/mycat start#停止
bin/mycat stopMycat启动之后占用端口号 8066。
启动完毕之后可以查看logs目录下的启动日志查看Mycat是否启动完成。
#在mycat目录下查看日志
tail -f logs/wrapper.log 3.3.4.2 测试
1).连接MyCat
通过如下指令就可以连接并登陆MyCat用法和mysql相同。
mysql -h 192.168.10.210 -P 8066 -uroot -p123456#显示的是DB01他是在schema.xml文件中配置的逻辑库
show databases;use DB01;#显示tb_order配置文件里是大写这里显示小写这张表目前只是在mycat中逻辑
# 存在的在具体的数据库当中是没有的。
show tables;我们看到我们是通过MySQL的指令来连接的MyCat因为MyCat在底层实际上是模拟了MySQL的协议。
2).数据测试
然后就可以在MyCat中来创建表并往表结构中插入数据查看数据在MySQL中的分布情况。
CREATE TABLE TB_ORDER (id BIGINT(20) NOT NULL,title VARCHAR(100) NOT NULL ,PRIMARY KEY (id)) ENGINEINNODB DEFAULT CHARSETutf8 ;一旦在mycat中把这个表结构创建了那么这个逻辑表对应的数据库表结构中的真实表就已经创建了此时底层所涉及到的三个数据节点都有这张表了。水平分表----表结构相同 插入数据测试
INSERT INTO TB_ORDER(id,title) VALUES(1,goods1);
INSERT INTO TB_ORDER(id,title) VALUES(2,goods2);
INSERT INTO TB_ORDER(id,title) VALUES(3,goods3);
INSERT INTO TB_ORDER(id,title) VALUES(5000000,goods5000000);
INSERT INTO TB_ORDER(id,title) VALUES(10000000,goods10000000);
INSERT INTO TB_ORDER(id,title) VALUES(10000001,goods10000001);
INSERT INTO TB_ORDER(id,title) VALUES(15000000,goods15000000);
INSERT INTO TB_ORDER(id,title) VALUES(15000001,goods15000001);经过测试我们发现在往 TB_ORDER 表中插入数据时 如果id的值在1-500w之间数据将会存储在第一个分片数据库中。 如果id的值在500w-1000w之间数据将会存储在第二个分片数据库中。 如果id的值在1000w-1500w之间数据将会存储在第三个分片数据库中。 如果id的值超出1500w在插入数据时将会报错需要在去增加对应的数据节点。
为什么会出现这种现象数据到底落在哪一个分片服务器到底是如何决定的呢 这是由逻辑表配置时的一个参数 rule 决定的而这个参数配置的就是分片规则关于分片规则的配置在后面的课程中会详细讲解。
解释 第一步在schema.xml配置的分片规则auto-sharding-long他引用了rule.xml 第二步上在rule.xml可以看到这种分片规则是根据id字段进行分片的具体是通过下面这个rang-long算法决定的 第二步下rang-long也是一个引用具体引用的是rule.xml中下面的分片函数 第三步这个函数又管理了一个物理文件autopartition-long.txt。 range start-end范围开始-结束0-500data node index数据节点的索引从0开始排012k一千M一万最终0-500万存放在第一个节点500万-1000万存放在第二个节点1000万-1500万存放在第三个节点 schema.xml、rule.xml、autopartition-long.txt都在/usr/local/src/MyCat/mycat/conf/目录下
3.4 MyCat配置
3.4.1 schema.xml
schema.xml 作为MyCat中最重要的配置文件之一 , 涵盖了MyCat的逻辑库 、 逻辑表 、 分片规则、分片节点及数据源的配置。 主要包含以下三组标签
schema标签datanode标签datahost标签
3.4.1.1 schema标签
1).schema 定义逻辑库 schema 标签用于定义 MyCat实例中的逻辑库 , 一个MyCat实例中, 可以有多个逻辑库 , 可以通过 schema 标签来划分不同的逻辑库。MyCat中的逻辑库的概念等同于MySQL中的database概念 需要操作某个逻辑库下的表时也需要切换逻辑库(use xxx)。
核心属性 name指定自定义的逻辑库库名注意大小写 checkSQLschema在SQL语句操作时指定了数据库名称执行时是否自动去除true自动去 除false不自动去除 正常情况想要执行sql语句必须要先切换到对应的数据库下现在可以不用切换直接在sql语句上数据库名.表名进行执行如果配置的为true在执行的时候会自动去掉数据库名称如果是false不会去掉数据库名执行这条sql会报错必须要先切换数据库在执行。 sqlMaxLimit如果未指定limit进行查询列表查询模式最多查询多少条记录 不使用分页也就是说查询的是全部数据既然使用mycat查询说明数据非常大查询全表数据太耗费性能了。
2).schema 中的table定义逻辑表 table 标签定义了MyCat中逻辑库schema下的逻辑表 一个逻辑库下面可以配置多个逻辑表所有需要拆分的表都需要在table标签中定义 。
核心属性
name定义逻辑表表名在该逻辑库下唯一dataNode定义逻辑表所属的dataNode数据节点该属性需要与dataNode标签中name对应多个dataNode逗号分隔rule分片规则的名字分片规则名字是在rule.xml中定义的primaryKey逻辑表对应真实表的主键type逻辑表的类型目前逻辑表只有全局表和普通表如果未配置就是普通表全局表配置为 global 普通表需要去分片的表全局表所有分片节点当中都会包含这张全局表
3.4.1.2 datanode标签
用来配置数据节点 核心属性
name定义数据节点名称dataHost数据库实例主机名称引用自 dataHost 标签中name属性database定义分片所属数据库
3.4.1.3 datahost标签 该标签在MyCat逻辑库中作为底层标签存在, 直接定义了具体的数据库实例、读写分离、心跳语句。
核心属性
name唯一标识供上层标签使用maxCon/minCon最大连接数/最小连接数balance负载均衡策略取值 0,1,2,3 具体到读写分离时讲解writeType写操作分发方式0写操作转发到第一个writeHost数据源第一个挂了切换到第二 个1写操作随机分发到配置的writeHost 也就是说writeHost可以配置多个 dbDriver数据库驱动支持 native、jdbcmysql8版本支持writeHost标签 host属性的值任意
3.4.2 rule.xml
rule.xml中定义所有拆分表的规则在使用过程中可以灵活的使用分片算法或者对同一个分片算法使用不同的参数它让分片过程可配置化。主要包含两类标签tableRule、Function。
tableRule定义所涉及到的分片规则在后面详解 columns标签根据那个字段进行分片algorithm便签当前这种分片规则所关联的分片算法是那个。它也是一个引用引用的是下面这个Function中定义的分片算法。 Function这个分片规则所涉及到的一些java类以及参数配置 name属性上下2个对应class属性mycat提供分片规则处理的java类是哪个property标签这种分片规则所关联的一些属性配置当然这些属性配置也可以封装在一个外部的文件中。
3.4.3 server.xml
server.xml配置文件包含了MyCat的系统配置信息主要有两个重要的标签system、user。
1). system标签
不作为重点关注 主要配置MyCat中的系统配置信息对应的系统配置项及其含义如下
属性取值含义charsetutf8设置Mycat的字符集, 字符集需要与MySQL的字符集保持一致nonePasswordLogin0,10为需要密码登陆、1为不需要密码登陆 ,默认为0设置为1则需要指定默认账户useHandshakeV100,1使用该选项主要的目的是为了能够兼容高版本的jdbc驱动, 是否采用 HandshakeV10Packet来与client进行通 信, 1:是, 0:否useSqlStat0,1开启SQL实时统计, 1 为开启 , 0 为关闭 ; 开启之后, MyCat会自动统计SQL语句的执行情况 ; mysql -h 127.0.0.1 -P 9066 -u root -p 查看MyCat执行的SQL, 执行效率比较低的SQL , SQL的整体执行情况、读写比例等 ; show sql ; show sql.slow ; show sql.sum ;useGlobleTableCheck0,1是否开启全局表的一致性检测。1为开启 0 为关闭sqlExecuteTimeout1000SQL语句执行的超时时间 , 单位为 s ;sequnceHandlerType0,1,2用来指定Mycat全局序列类型0 为本地文件1 为数据库方式2 为时间戳列方式默认使用本地文件方式文件方式主要用于测试sequnceHandlerPattern正则表达式必须带有MYCATSEQ或者 mycatseq进入序列匹配流程 注意MYCATSEQ_有空格的情况subqueryRelationshipChecktrue,false子查询中存在关联查询的情况下,检查关联字段中是否有分片字段 .默认 falseuseCompression0,1开启mysql压缩协议 , 0 : 关闭, 1 : 开启fakeMySQLVersion5.5,5.6设置模拟的MySQL版本号
属性取值含义defaultSqlParser由于MyCat的最初版本使用了FoundationDB 的SQL解析器, 在MyCat1.3后增加了Druid 解析器, 所以要设置defaultSqlParser属性来指定默认的解析器; 解析器有两个 : druidparser 和 fdbparser, 在MyCat1.4之后,默认是druidparser, fdbparser已经废除了processors1,2…指定系统可用的线程数量, 默认值为CPU核心x 每个核心运行线程数量; processors 会影响processorBufferPoolprocessorBufferLocalPercentprocessorExecutor属性, 所有, 在性能调优时, 可以适当地修改processors值processorBufferChunk指定每次分配Socket Direct Buffer默认值为4096字节, 也会影响BufferPool长度, 如果一次性获取字节过多而导致buffer不够 用, 则会出现警告, 可以调大该值processorExecutor指定NIOProcessor上共享businessExecutor固定线程池的大小; MyCat把异步任务交给 businessExecutor 线程池中, 在新版本的MyCat中这个连接池使用频次不高, 可以适当地把该值调小packetHeaderSize指定MySQL协议中的报文头长度, 默认4个字节maxPacketSize指定MySQL协议可以携带的数据最大大小, 默认值为16MidleTimeout30指定连接的空闲时间的超时长度;如果超时,将关闭资源并回收, 默认30分钟
属性取值含义txIsolation1,2,3,4初始化前端连接的事务隔离级别默认为REPEATED_READ , 对应数字为3 READ_UNCOMMITED1READ_COMMITTED2REPEATED_READ3SERIALIZABLE4sqlExecuteTimeout300执行SQL的超时时间, 如果SQL语句执行超时, 将关闭连接; 默认300秒;serverPort8066定义MyCat的使用端口, 默认8066managerPort9066定义MyCat的管理端口, 默认9066
2). user标签
配置MyCat中的用户、访问密码以及用户针对于逻辑库、逻辑表的权限信息具体的权限描述方式及配置说明如下 在测试权限操作时我们只需要将 privileges 标签的注释放开。 在 privileges 下的schema 标签中配置的dml属性配置的是逻辑库的权限。 在privileges的schema下的table标签的dml属性中配置逻辑表的权限。如果不配置就代表他可以对这个逻辑库当中的虽有的逻辑表进行任何操作。
测试完成后注释掉。 !-- 表级 DML 权限设置 --privileges checktrue !--true开启权限检查--schema nameDB01 dml1110 !--tb01指定逻辑库名0110没有增加权限有修改权限有查询权限没有删除权限 配置数据库的增改查删权限0代表没有1代表有--table nameTB_ORDER dml1110 /table !--TB_ORDER逻辑表的名字0000配置逻辑表的权限如果逻辑库和逻辑表都配置了权限那么使用的是逻辑表的权限遵循就近原则--/schema/privileges 3.5 MyCat分片
3.5.1 垂直拆分垂直分库
3.5.1.1 场景
在业务系统中涉及以下表结构但是由于用户与订单每天都会产生大量的数据单台服务器的数据存储及处理能力是有限的可以对数据库表进行拆分原有的数据库表如下。
现在考虑将其进行垂直分库操作将商品相关的表拆分到一个数据库服务器订单表拆分的一个数据库服务器用户及省市区表拆分到一个服务器。最终结构如下
省市区相关的表里面存储的数据本来就不多几千最多几万条数据也就没有必要存放在一个单独的分区中用户表里面有一个用户地址字段里面存放的有省市区相关的编号最终我在展示的时候还需要展示省市区的名字。所以考虑把用户和省市区相关的表放在一个分片当中。 3.5.1.2 准备
准备三台服务器IP地址如图所示 并且在192.168.10.210192.168.10.213192.168.10.214上面创建数据库shopping3台都要创建。 3.5.1.3 配置
1).schema.xml
?xml version1.0?
!DOCTYPE mycat:schema SYSTEM schema.dtd
mycat:schema xmlns:mycathttp://io.mycat/schema nameSHOPPING checkSQLschematrue sqlMaxLimit100!--只有涉及到分表的时候才需要指定分片规则现在是垂直分库所以不需要指定代表这张表的所有数据都存放在这一个分片上--table nametb_goods_base dataNodedn1 primaryKeyid /table nametb_goods_brand dataNodedn1 primaryKeyid /table nametb_goods_cat dataNodedn1 primaryKeyid /table nametb_goods_desc dataNodedn1 primaryKeygoods_id /table nametb_goods_item dataNodedn1 primaryKeyid /table nametb_order_item dataNodedn2 primaryKeyid /table nametb_order_master dataNodedn2 primaryKeyorder_id /table nametb_order_pay_log dataNodedn2 primaryKeyout_trade_no /table nametb_user dataNodedn3 primaryKeyid /table nametb_user_address dataNodedn3 primaryKeyid /table nametb_areas_provinces dataNodedn3 primaryKeyid/table nametb_areas_city dataNodedn3 primaryKeyid/table nametb_areas_region dataNodedn3 primaryKeyid//schemadataNode namedn1 dataHostdhost1 databaseshopping /dataNode namedn2 dataHostdhost2 databaseshopping /dataNode namedn3 dataHostdhost3 databaseshopping /dataHost namedhost1 maxCon1000 minCon10 balance0writeType0 dbTypemysql dbDriverjdbc switchType1 slaveThreshold100heartbeatselect user()/heartbeatwriteHost hostmaster urljdbc:mysql://192.168.10.210:3306?useSSLfalseamp;serverTimezoneAsia/Shanghaiamp;characterEncodingutf8 userroot password1234 //dataHostdataHost namedhost2 maxCon1000 minCon10 balance0writeType0 dbTypemysql dbDriverjdbc switchType1 slaveThreshold100heartbeatselect user()/heartbeatwriteHost hostmaster urljdbc:mysql://192.168.10.213:3306?useSSLfalseamp;serverTimezoneAsia/Shanghaiamp;characterEncodingutf8 userroot password1234 //dataHostdataHost namedhost3 maxCon1000 minCon10 balance0writeType0 dbTypemysql dbDriverjdbc switchType1 slaveThreshold100heartbeatselect user()/heartbeatwriteHost hostmaster urljdbc:mysql://192.168.10.214:3306?useSSLfalseamp;serverTimezoneAsia/Shanghaiamp;characterEncodingutf8 userroot password1234 //dataHost/mycat:schema
2).server.xml user nameroot defaultAccounttrueproperty namepassword123456/property!--root用户访问的逻辑库是哪个--property nameschemasSHOPPING/property!--没有配置说明既能读又能写--!-- 表级 DML 权限设置 --!--privileges checktrue schema nameDB01 dml1110 table nameTB_ORDER dml1110/table /schema/privileges --/useruser nameuserproperty namepassword123456/property!--user用户访问的逻辑库是哪个--property nameschemasSHOPPING/property!--配置只能够读--property namereadOnlytrue/property/user3.5.1.4 测试
1mycat修改完配置文件后需要重新启动
#注意不能到bin目录下
cd /usr/local/src/MyCat/mycat/#先把之前启动的mycat 关闭掉
bin/mycat stop#启动
bin/mycat start#在mycat目录下查看日志是否启动成功
tail -f logs/wrapper.log2连接连接MyCat
mysql -h 192.168.10.210 -P 8066 -uroot -p123456#显示的是SHOPPING他是在schema.xml文件中配置的逻辑库
show databases;use SHOPPING;#显示所有的逻辑表这些逻辑表只是在schema.xml中定义出来了在逻辑上是有这些表的
# 但是这些表在具体的物理节点中并不存在所以接下来要创建具体的表结构
show tables; 3上传测试SQL脚本到服务器的/root目录 4执行指令导入测试数据
重新启动MyCat后在mycat的命令行中通过source指令导入表结构以及对应的数据查看数据分布情况。
#登录mycat并且切换了数据库之后执行
source /root/shopping-table.sqlsource /root/shopping-insert.sql将表结构及对应的测试数据导入之后可以检查一下各个数据库服务器中的表结构分布情况。 检查是否和我们准备工作中规划的服务器一致以及表中是否有数据。 5查询用户的收件人及收件人地址信息(包含省、市、区)。
涉及到的表
第三个分片服务器中
在MyCat的命令行中当我们执行以下多表联查的SQL语句时可以正常查询出数据。
SELECT ua.user_id, ua.contact, p.province, c.city, r.area , ua.address
FROM tb_user_address ua ,tb_areas_city c , tb_areas_provinces p ,tb_areas_region r
WHERE ua.province_id p.provinceid AND ua.city_id c.cityid AND ua.town_id r.areaid ;6查询每一笔订单及订单的收件地址信息(包含省、市、区)。
涉及到的表
第二个分片服务器中
第三个分片服务器中
实现该需求对应的SQL语句如下
SELECT order_id , payment ,receiver, province , city , area
FROM tb_order_master o, tb_areas_provinces p , tb_areas_city c , tb_areas_region r
WHERE o.receiver_province p.provinceid AND o.receiver_city c.cityid AND o.receiver_region r.areaid ;但是现在存在一个问题订单相关的表结构是在 192.168.10.213 数据库服务器中而省市区的数据库表是在 192.168.10.214 数据库服务器中。那么在MyCat中执行是否可以成功呢 经过测试我们看到SQL语句执行报错。原因就是因为MyCat在执行该SQL语句时需要往具体的数据库服务器中路由而当前没有一个数据库服务器完全包含了订单以及省市区的表结构造成SQL语句失败报错。
对于上述的这种现象我们如何来解决呢 下面我们介绍的全局表就可以轻松解决这个问题。
3.5.1.5 全局表
对于省、市、区/县表tb_areas_provinces , tb_areas_city , tb_areas_region是属于数据字典表在多个业务模块中都可能会遇到可以将其设置为全局表利于业务操作。
字典表数据不多还不会变。
全局表在每一个节点中都存在。
修改schema.xml中的逻辑表的配置修改 tb_areas_provinces、tb_areas_city、tb_areas_region 三个逻辑表增加 type 属性配置为global就代表该表是全局表就会在所涉及到的dataNode中创建给表。对于当前配置来说也就意味着所有的节点中都有该表了。 table nametb_areas_provinces dataNodedn1,dn2,dn3 primaryKeyid typeglobal/table nametb_areas_city dataNodedn1,dn2,dn3 primaryKeyid typeglobal/table nametb_areas_region dataNodedn1,dn2,dn3 primaryKeyid typeglobal/1配置完毕后先停止MyCat。
#注意不能到bin目录下
cd /usr/local/src/MyCat/mycat/#停止
bin/mycat stop2删除原来每一个数据库服务器中的所有表结构即把三个分片数据库shopping中的表都删除
3删除表结构之后重新启动mycat
#启动
bin/mycat start#在mycat目录下查看日志
tail -f logs/wrapper.log4通过source指令导入表及数据
mysql -h 192.168.10.210 -P 8066 -uroot -p123456use SHOPPING;source /root/shopping-table.sql
source /root/shopping-insert.sql5检查每一个数据库服务器中的表及数据分布看到三个节点中都有这三张全局表
6然后再次执行上面的多表联查的SQL语句
SELECT order_id , payment ,receiver, province , city , area
FROM tb_order_master o, tb_areas_provinces p , tb_areas_city c , tb_areas_region r
WHERE o.receiver_province p.provinceid AND o.receiver_city c.cityid AND o.receiver_region r.areaid ;是可以正常执行成功的。
7当在MyCat中更新全局表的时候我们可以看到所有分片节点中的数据都发生了变化每个节点的全局表数据时刻保持一致。
update tb_areas_provinces set province 北京 where id 1;3.5.2 水平拆分水平分表
3.5.2.1 场景
在业务系统中有一张表(日志表)业务系统每天都会产生大量的日志数据单台服务器的数据存储及处理能力是有限的可以对数据库表进行拆分。
3.5.2.2 准备
准备三台服务器具体的结构如下
并且在三台数据库服务器中分表创建一个数据库itcast。
3个都要创建 3.5.2.3 配置
1).schema.xml
在schema.xml中增加水平分表的配置上面垂直分库的配置不用删除。 schema nameITCAST checkSQLschematrue sqlMaxLimit100!--分表需要指定分片规则mod-long这张表的数据需要均匀分散的存储在这三个节点中原理根据id进行分片对主键id进行求模id%3结果为0落在第一个节点为1落在第二个节点为2落在第三个节点--table nametb_log dataNodedn4,dn5,dn6 primaryKeyid rulemod-long //schemadataNode namedn4 dataHostdhost1 databaseitcast /dataNode namedn5 dataHostdhost2 databaseitcast /dataNode namedn6 dataHostdhost3 databaseitcast /tb_log表最终落在3个节点中分别是 dn4、dn5、dn6 而具体的数据分别存储在 dhost1、dhost2、dhost3的itcast数据库中。
rule.xml中的分片规则
2).server.xml
配置root用户既可以访问 SHOPPING 逻辑库又可以访问ITCAST逻辑库。 user nameroot defaultAccounttrueproperty namepassword123456/property!--root用户访问的逻辑库是哪个--property nameschemasSHOPPING,ITCAST/property!--没有配置说明既能读又能写--!-- 表级 DML 权限设置 --!--privileges checktrue schema nameDB01 dml1110 table nameTB_ORDER dml1110/table /schema/privileges --/useruser nameuserproperty namepassword123456/property!--user用户访问的逻辑库是哪个--property nameschemasSHOPPING/property!--配置只能够读--property namereadOnlytrue/property/user3.5.2.4 测试
配置完毕后重新启动MyCat
#注意不能到bin目录下
cd /usr/local/src/MyCat/mycat/#先停止
bin/mycat stop#在启动
bin/mycat start#在mycat目录下查看日志
tail -f logs/wrapper.log登录mycat并切换到ITCAST数据库
mysql -h 192.168.10.210 -P 8066 -uroot -p123456#显示的是ITCAST、SHOPPING他是在schema.xml文件中配置的逻辑库
show databases;use ITCAST;#这个逻辑表tb_log只是逻辑上存在的在真实的数据库中并不存在所以要进行创建
show tables;然后在mycat的命令行中执行如下SQL创建表、并插入数据查看数据分布情况。
CREATE TABLE tb_log (id bigint(20) NOT NULL COMMENT ID,model_name varchar(200) DEFAULT NULL COMMENT 模块名,model_value varchar(200) DEFAULT NULL COMMENT 模块值,return_value varchar(200) DEFAULT NULL COMMENT 返回值,return_class varchar(200) DEFAULT NULL COMMENT 返回值类型,operate_user varchar(20) DEFAULT NULL COMMENT 操作用户,operate_time varchar(20) DEFAULT NULL COMMENT 操作时间,param_and_value varchar(500) DEFAULT NULL COMMENT 请求参数名及参数值,operate_class varchar(200) DEFAULT NULL COMMENT 操作类,operate_method varchar(200) DEFAULT NULL COMMENT 操作方法,cost_time bigint(20) DEFAULT NULL COMMENT 执行方法耗时, 单位 ms,source int(1) DEFAULT NULL COMMENT 来源 : 1 PC , 2 Android , 3 IOS,PRIMARY KEY (id)) ENGINEInnoDB DEFAULT CHARSETutf8mb4;INSERT INTO tb_log (id, model_name, model_value, return_value, return_class, operate_user, operate_time, param_and_value, operate_class, operate_method, cost_timesource) VALUES(1,user,insert,success,java.lang.String,10001,2022-01-06 18:12:28,{\age\:\20\,\name\:\Tom\,\gender\:\1\},cn.itcast.controller.UserController,insert,10,1);
INSERT INTO tb_log (id, model_name, model_value, return_value, return_class, operate_user, operate_time, param_and_value, operate_class, operate_method, cost_timesource) VALUES(2,user,insert,success,java.lang.String,10001,2022-01-06 18:12:27,{\age\:\20\,\name\:\Tom\,\gender\:\1\},cn.itcast.controller.UserController,insert,23,1);
INSERT INTO tb_log (id, model_name, model_value, return_value, return_class, operate_user, operate_time, param_and_value, operate_class, operate_method, cost_timesource) VALUES(3,user,update,success,java.lang.String,10001,2022-01-06 18:16:45,{\age\:\20\,\name\:\Tom\,\gender\:\1\},cn.itcast.controller.UserController,update,34,1);
INSERT INTO tb_log (id, model_name, model_value, return_value, return_class, operate_user, operate_time, param_and_value, operate_class, operate_method, cost_timesource) VALUES(4,user,update,success,java.lang.String,10001,2022-01-06 18:16:45,{\age\:\20\,\name\:\Tom\,\gender\:\1\},cn.itcast.controller.UserController,update,13,2);
INSERT INTO tb_log (id, model_name, model_value, return_value, return_class, operate_user, operate_time, param_and_value, operate_class, operate_method, cost_timesource) VALUES(5,user,insert,success,java.lang.String,10001,2022-01-06 18:30:31,{\age\:\200\,\name\:\TomCat\,\gender\:\0\},cn.itcast.controller.UserController,insert,29,3);
INSERT INTO tb_log (id, model_name, model_value, return_value, return_class, operate_user, operate_time, param_and_value, operate_class, operate_method, cost_timesource) VALUES(6,user,find,success,java.lang.String,10001,2022-01-06 18:30:31,{\age\:\200\,\name\:\TomCat\,\gender\:\0\},cn.itcast.controller.UserController,find,29,2); 效果发现是均匀分片并且满足分片规则分片1id%0分片2id%1分片3id%2 3.5.3 分片规则
schema.xml文件中的rule字段指定分片规则它是个引用 具体是在rule.xml中配置的分片规则
3.5.3.1 范围分片
1).介绍
根据指定的字段及其配置的范围与数据节点的对应情况 来决定该数据属于哪一个分片。 2).配置 schema.xml逻辑表配置
table nameTB_ORDER dataNodedn1,dn2,dn3 ruleauto-sharding-long /schema.xml数据节点配置
dataNode namedn1 dataHostdhost1 databasedb01 /
dataNode namedn2 dataHostdhost2 databasedb01 /
dataNode namedn3 dataHostdhost3 databasedb01 /rule.xml分片规则配置
tableRule nameauto-sharding-longrulecolumnsid/columnsalgorithmrang-long/algorithm/rule
/tableRulefunction namerang-long classio.mycat.route.function.AutoPartitionByLongproperty namemapFileautopartition-long.txt/propertyproperty namedefaultNode0/property
/function分片规则配置属性含义
属性描述columns标识将要分片的表字段algorithm指定分片函数与function的对应关系class指定该分片算法对应的类mapFile对应的外部配置文件type默认值为0 ; 0 表示Integer , 1 表示StringdefaultNode默认节点 默认节点的所用:枚举分片时,如果碰到不识别的枚举值, 就让它路由到默认节点 ; 如果没有默认值,碰到不识别的则报错 。
在rule.xml中配置分片规则时关联了一个映射配置文件 autopartition-long.txt该配置文件的配置如下
# range start-end ,data node index
# K1000,M10000.
0-500M0
500M-1000M1
1000M-1500M2含义0-500万之间的值存储在0号数据节点(数据节点的索引从0开始) 500万-1000万之间的数据存储在1号数据节点 1000万-1500万的数据节点存储在2号节点
该分片规则主要是针对于数字类型的字段适用。 在MyCat的入门程序中我们使用的就是该分片规则。
3.5.3.2 取模分片
1).介绍 根据指定的字段值与节点数量进行求模运算根据运算结果 来决定该数据属于哪一个分片。 2).配置 schema.xml逻辑表配置
table nametb_log dataNodedn4,dn5,dn6 primaryKeyid rulemod-long /schema.xml数据节点配置
dataNode namedn4 dataHostdhost1 databaseitcast /
dataNode namedn5 dataHostdhost2 databaseitcast /
dataNode namedn6 dataHostdhost3 databaseitcast /rule.xml分片规则配置
tableRule namemod-longrulecolumnsid/columnsalgorithmmod-long/algorithm/rule
/tableRulefunction namemod-long classio.mycat.route.function.PartitionByModproperty namecount3/property
/function分片规则属性说明如下
属性描述columns标识将要分片的表字段algorithm指定分片函数与function的对应关系class指定该分片算法对应的类count数据节点的数量
该分片规则主要是针对于数字类型的字段适用。 在前面水平拆分的演示中我们选择的就是取模分片。
3.5.3.3 一致性hash分片
1).介绍 所谓一致性哈希指的是在进行分片操作的时候它会去计算我们所指定的字段的哈希值相同的哈希因子计算值总是被划分到相同的分区表中不会因为分区节点的增加而改变原来数据的分区位置有效的解决了分布式数据的拓容问题。 2).配置 schema.xml中逻辑表配置
!-- 一致性hash --
table nametb_order dataNodedn4,dn5,dn6 rulesharding-by-murmur /schema.xml中数据节点配置在3.5.2水平分表中已经写过了
dataNode namedn4 dataHostdhost1 databaseitcast /
dataNode namedn5 dataHostdhost2 databaseitcast /
dataNode namedn6 dataHostdhost3 databaseitcast /rule.xml中分片规则配置
tableRule namesharding-by-murmurrulecolumnsid/columnsalgorithmmurmur/algorithm/rule
/tableRulefunction namemurmur classio.mycat.route.function.PartitionByMurmurHashproperty nameseed0/property!-- 默认是0 --property namecount3/propertyproperty namevirtualBucketTimes160/property
/function分片规则属性含义
属性描述columns标识将要分片的表字段algorithm指定分片函数与function的对应关系class指定该分片算法对应的类seed创建murmur_hash对象的种子默认0count要分片的数据库节点数量必须指定否则没法分片virtualBucketTimes一个实际的数据库节点被映射为这么多虚拟节点默认是160倍也就是虚拟节点数是物理节点数的160倍virtualBucketTimes*count就是虚拟结点数量 ;weightMapFile节点的权重没有指定权重的节点默认是1。以properties文件的格式填写以从0开始到count-1的整数值也就是节点索引为key 以节点权重值为值。所有权重值必须是正整数否则以1代替bucketMapPath用于测试时观察各物理节点与虚拟节点的分布情况如果指定了这个属性会把虚拟节点的murmur hash值与物理节点的映射按行输出到这个文件没有默认值如果不指定就不会输出任何东西
3).测试
配置完毕后重新启动MyCat然后在mycat的命令行中执行如下SQL创建表、并插入数据查看数 据分布情况。
配置完毕后重新启动MyCat
#注意不能到bin目录下
cd /usr/local/src/MyCat/mycat/#先停止
bin/mycat stop#在启动
bin/mycat start#在mycat目录下查看日志
tail -f logs/wrapper.log登录mycat并切换到ITCAST数据库
mysql -h 192.168.10.210 -P 8066 -uroot -p123456#显示的是ITCAST、SHOPPING他是在schema.xml文件中配置的逻辑库
show databases;use ITCAST;#这个逻辑表tb_order只是逻辑上存在的在真实的数据库中并不存在所以要进行创建
show tables;然后在mycat的命令行中执行如下SQL创建表、并插入数据查看数据分布情况。 create table tb_order(id varchar(100) not null primary key,money int null,content varchar(200) null
);INSERT INTO tb_order (id, money, content) VALUES (b92fdaaf-6fc4-11ec-b831-482ae33c4a2d, 10, b92fdaf8-6fc4-11ec-b831-482ae33c4a2d);
INSERT INTO tb_order (id, money, content) VALUES (b93482b6-6fc4-11ec-b831-482ae33c4a2d, 20, b93482d5-6fc4-11ec-b831-482ae33c4a2d);
INSERT INTO tb_order (id, money, content) VALUES (b937e246-6fc4-11ec-b831-482ae33c4a2d, 50, b937e25d-6fc4-11ec-b831-482ae33c4a2d);
INSERT INTO tb_order (id, money, content) VALUES (b93be2dd-6fc4-11ec-b831-482ae33c4a2d, 100, b93be2f9-6fc4-11ec-b831-482ae33c4a2d);
INSERT INTO tb_order (id, money, content) VALUES (b93f2d68-6fc4-11ec-b831-482ae33c4a2d, 130, b93f2d7d-6fc4-11ec-b831-482ae33c4a2d);
INSERT INTO tb_order (id, money, content) VALUES (b9451b98-6fc4-11ec-b831-482ae33c4a2d, 30, b9451bcc-6fc4-11ec-b831-482ae33c4a2d);
INSERT INTO tb_order (id, money, content) VALUES (b9488ec1-6fc4-11ec-b831-482ae33c4a2d, 560, b9488edb-6fc4-11ec-b831-482ae33c4a2d);
INSERT INTO tb_order (id, money, content) VALUES (b94be6e6-6fc4-11ec-b831-482ae33c4a2d, 10, b94be6ff-6fc4-11ec-b831-482ae33c4a2d);
INSERT INTO tb_order (id, money, content) VALUES (b94ee10d-6fc4-11ec-b831-482ae33c4a2d, 123, b94ee12c-6fc4-11ec-b831-482ae33c4a2d);
INSERT INTO tb_order (id, money, content) VALUES (b952492a-6fc4-11ec-b831-482ae33c4a2d, 145, b9524945-6fc4-11ec-b831-482ae33c4a2d);
INSERT INTO tb_order (id, money, content) VALUES (b95553ac-6fc4-11ec-b831-482ae33c4a2d, 543, b95553c8-6fc4-11ec-b831-482ae33c4a2d);
INSERT INTO tb_order (id, money, content) VALUES (b9581cdd-6fc4-11ec-b831-482ae33c4a2d, 17, b9581cfa-6fc4-11ec-b831-482ae33c4a2d);
INSERT INTO tb_order (id, money, content) VALUES (b95afc0f-6fc4-11ec-b831-482ae33c4a2d, 18, b95afc2a-6fc4-11ec-b831-482ae33c4a2d);
INSERT INTO tb_order (id, money, content) VALUES (b95daa99-6fc4-11ec-b831-482ae33c4a2d, 134, b95daab2-6fc4-11ec-b831-482ae33c4a2d);
INSERT INTO tb_order (id, money, content) VALUES (b9667e3c-6fc4-11ec-b831-482ae33c4a2d, 156, b9667e60-6fc4-11ec-b831-482ae33c4a2d);
INSERT INTO tb_order (id, money, content) VALUES (b96ab489-6fc4-11ec-b831-482ae33c4a2d, 175, b96ab4a5-6fc4-11ec-b831-482ae33c4a2d);
INSERT INTO tb_order (id, money, content) VALUES (b96e2942-6fc4-11ec-b831-482ae33c4a2d, 180, b96e295b-6fc4-11ec-b831-482ae33c4a2d);
INSERT INTO tb_order (id, money, content) VALUES (b97092ec-6fc4-11ec-b831-482ae33c4a2d, 123, b9709306-6fc4-11ec-b831-482ae33c4a2d);
INSERT INTO tb_order (id, money, content) VALUES (b973727a-6fc4-11ec-b831-482ae33c4a2d, 230, b9737293-6fc4-11ec-b831-482ae33c4a2d);
INSERT INTO tb_order (id, money, content) VALUES (b978840f-6fc4-11ec-b831-482ae33c4a2d, 560, b978843c-6fc4-11ec-b831-482ae33c4a2d);效果根据字段的hash值来决定到底路由到那个分片 3.5.3.4 枚举分片
1).介绍 通过在配置文件中配置可能的枚举值, 指定数据分布到不同数据节点上, 本规则适用于按照省份、性别、状态拆分数据等业务 。
枚举值索引 枚举值字段的枚举值比如 某一张表的数据状态索引节点的索引 eg 1: 0如果这个字段的枚举值是1则数据存放在第1个节点上2: 1如果这个字段的枚举值是2则数据存放在第2个节点上3: 2如果这个字段的枚举值是3则数据存放在第3个节点上 defaultNode默认节点指的是如果我们往这个数据库表在插入数据的时候超出了我们所指定的枚举值那么此时默认往哪一个节点当中进行存储。默认值是2意味着往第3个节点进行储存。mapFile关联的外部文件partition-hash-int.txt配置的是枚举值与对应的分片节点
2).配置
schema.xml中逻辑表配置
!-- 枚举 --
table nametb_user dataNodedn4,dn5,dn6 rulesharding-by-intfile-enumstatus/schema.xml中数据节点配置在3.5.2水平分表中已经写过了
dataNode namedn4 dataHostdhost1 databaseitcast /
dataNode namedn5 dataHostdhost2 databaseitcast /
dataNode namedn6 dataHostdhost3 databaseitcast /rule.xml中分片规则配置 !--columns指定根据什么字段进行分片我们是想要根据status字段分片如果直接写可能会出现问题例如在逻辑表当中有可能有另外的一张逻辑表也想根据枚举进行分片此时就会存在一个矛盾。逻辑表1在进行枚举分片的时候他想根据status进行分片逻辑表2想根据sex性别进行分片此时如果只有一个逻辑分片规则那么columns属性该怎么写呢解决复制一份修改名字即可 --tableRule namesharding-by-intfilerulecolumnssharding_id/columnsalgorithmhash-int/algorithm/rule/tableRule!-- 自己增加 tableRule --tableRule namesharding-by-intfile-enumstatusrulecolumnsstatus/columnsalgorithmhash-int/algorithm/rule/tableRulefunction namehash-int classio.mycat.route.function.PartitionByFileMapproperty namedefaultNode2/propertyproperty namemapFilepartition-hash-int.txt/property/function partition-hash-int.txt 内容如下 :
10
21
32分片规则属性含义
属性描述columns标识将要分片的表字段algorithm指定分片函数与function的对应关系class指定该分片算法对应的类mapFile对应的外部配置文件type默认值为0 ; 0 表示Integer , 1 表示StringdefaultNode默认节点 ; 小于0 标识不设置默认节点 , 大于等于0代表设置默认节点 ; 默认节点的所用:枚举分片时,如果碰到不识别的枚举值, 就让它路由到默认节点 ; 如果没有默认值,碰到不识别的则报错 。
3).测试 配置完毕后重新启动MyCat然后在mycat的命令行中执行如下SQL创建表、并插入数据查看数据分布情况。
配置完毕后重新启动MyCat
#注意不能到bin目录下
cd /usr/local/src/MyCat/mycat/#先停止
bin/mycat stop#在启动
bin/mycat start#在mycat目录下查看日志
tail -f logs/wrapper.log登录mycat并切换到ITCAST数据库
mysql -h 192.168.10.210 -P 8066 -uroot -p123456#显示的是ITCAST、SHOPPING他是在schema.xml文件中配置的逻辑库
show databases;use ITCAST;#这个逻辑表tb_user只是逻辑上存在的在真实的数据库中并不存在所以要进行创建
show tables;然后在mycat的命令行中执行如下SQL创建表、并插入数据查看数据分布情况。
CREATE TABLE tb_user (id bigint(20) NOT NULL COMMENT ID,username varchar(200) DEFAULT NULL COMMENT 姓名,status int(2) DEFAULT 1 COMMENT 1: 未启用, 2: 已启用, 3: 已关闭,PRIMARY KEY (id)
) ENGINEInnoDB DEFAULT CHARSETutf8mb4;insert into tb_user (id,username ,status) values(1,Tom,1);
insert into tb_user (id,username ,status) values(2,Cat,2);
insert into tb_user (id,username ,status) values(3,Rose,3);
insert into tb_user (id,username ,status) values(4,Coco,2);
insert into tb_user (id,username ,status) values(5,Lily,1);
insert into tb_user (id,username ,status) values(6,Tom,1);
insert into tb_user (id,username ,status) values(7,Cat,2);
insert into tb_user (id,username ,status) values(8,Rose,3);
insert into tb_user (id,username ,status) values(9,Coco,2);
insert into tb_user (id,username ,status) values(10,Lily,1);效果第一个节点的status都为1第二个节点的status都为2第三个节点的status都为3 4).测试如果我们往这个数据库表在插入数据的时候超出了我们所指定的枚举值那么此时默认往哪一个节点当中进行存储。默认值是2意味着往第3个节点进行储存。 配置完毕后重新启动MyCat
#注意不能到bin目录下
cd /usr/local/src/MyCat/mycat/#先停止
bin/mycat stop#在启动
bin/mycat start#在mycat目录下查看日志
tail -f logs/wrapper.log登录mycat并切换到ITCAST数据库
mysql -h 192.168.10.210 -P 8066 -uroot -p123456#显示的是ITCAST、SHOPPING他是在schema.xml文件中配置的逻辑库
show databases;use ITCAST;#这个逻辑表tb_order只是逻辑上存在的在真实的数据库中并不存在所以要进行创建
show tables;#status为6自己在partition-hash-int.txt中设置的是1 2 3超出最大值3所以会放在第3个节点中。
insert into tb_user (id,username ,status) values(11,xiaoheihei,6);3.5.3.5 应用指定算法
1).介绍 运行阶段由应用自主决定当前这条数据会路由到那个分片 , 直接根据字符子串必须是数字计算分片号。
即根据这条数据当中某一个字段的子字符串来计算出对应的分片。这个求取出来的子字符串必须是数字比如求取出来的这个子字符串是0 就代表会落在第一个分片上求取出来的这个子字符串是1 就代表会落在第二个分片上求取出来的这个子字符串是2 就代表会落在第三个分片上。
截取前2个子字符串
00100010截取的是00则落在第一个分片中01100011截取的是01则落在第二个分片中02100012截取的是02则落在第三个分片中 开始索引从那个位置开始截取字符串截取长度截取几位分片数量当前是3片默认分片截取出来的子字符串不在这个分片数量的范围3中那么他会走默认分片值为2也就是第3个分片
2).配置 schema.xml中逻辑表配置
!-- 应用指定算法 --
table nametb_app dataNodedn4,dn5,dn6 rulesharding-by-substring /schema.xml中数据节点配置在3.5.2水平分表中已经写过了
dataNode namedn4 dataHostdhost1 databaseitcast /
dataNode namedn5 dataHostdhost2 databaseitcast /
dataNode namedn6 dataHostdhost3 databaseitcast /rule.xml中分片规则配置默认没有提供这个规则样例需要自己增加
tableRule namesharding-by-substringrulecolumnsid/columnsalgorithmsharding-by-substring/algorithm/rule
/tableRulefunction namesharding-by-substring classio.mycat.route.function.PartitionDirectBySubStringproperty namestartIndex0/property !-- zero-based --property namesize2/propertyproperty namepartitionCount3/propertyproperty namedefaultPartition0/property
/function分片规则属性含义
属性描述columns标识将要分片的表字段algorithm指定分片函数与function的对应关系class指定该分片算法对应的类startIndex字符子串起始索引size字符长度partitionCount分区(分片)数量defaultPartition默认分片(在分片数量定义时, 字符标示的分片编号不在分片数量内时, 使用默认分片)
示例说明 :
id05-100000002 , 在此配置中代表根据id中从 startIndex0开始截取siz2位数字即0505就是获取的分区如果没找到对应的分片则默认分配到defaultPartition 。
3).测试
配置完毕后重新启动MyCat然后在mycat的命令行中执行如下SQL创建表、并插入数据查看数 据分布情况。
配置完毕后重新启动MyCat
#注意不能到bin目录下
cd /usr/local/src/MyCat/mycat/#先停止
bin/mycat stop#在启动
bin/mycat start#在mycat目录下查看日志
tail -f logs/wrapper.log重新登录mycat并切换到ITCAST数据库
mysql -h 192.168.10.210 -P 8066 -uroot -p123456#显示的是ITCAST、SHOPPING他是在schema.xml文件中配置的逻辑库
show databases;use ITCAST;#这个逻辑表tb_app只是逻辑上存在的在真实的数据库中并不存在所以要进行创建
show tables;然后在mycat的命令行中执行如下SQL创建表、并插入数据查看数据分布情况。
CREATE TABLE tb_app (id varchar(10) NOT NULL COMMENT ID,name varchar(200) DEFAULT NULL COMMENT 名称,PRIMARY KEY (id)) ENGINEInnoDB DEFAULT CHARSETutf8mb4;insert into tb_app (id,name) values(0000001,Testx00001);
insert into tb_app (id,name) values(0100001,Test100001);
insert into tb_app (id,name) values(0100002,Test200001);
insert into tb_app (id,name) values(0200001,Test300001);
insert into tb_app (id,name) values(0200002,TesT400001);效果截取id的前2个字符串截取的数字就代表所属的分片。 如果插入数据的id截取出来的前2个字符串不在3这个分片范围内默认放在第一个分片中因为rule.xml中设置的是0
insert into tb_app (id,name) values(0400002,TesT500001);3.5.3.6 固定分片hash算法
1).介绍
该算法类似于十进制的求模运算但是为二进制的操作例如取 id 的二进制低 10 位 与1111111111 进行位 运算位与运算最小值为 0000000000最大值为1111111111转换为十进制也就是位于0-1023之间。
同为1则为1有一个是0则为0
例如如果计算出来的结果在0~255之间则落在第一个分片256~511之间则落在第二个分片512~1023之间则落在第三个分片。
举例
当插入的数据id值为1转化为二进制后和1111111111 进行位 运算结果在0到255之间所以在第一个分片中。当插入的数据id值为2转化为二进制后和1111111111 进行位 运算结果在0到255之间所以在第一个分片中。当插入的数据id值为300转化为二进制后和1111111111 进行位 运算结果在256到511之间所以在第二个分片中。 特点
如果是求模连续的值分别分配到各个不同的分片但是此算法会将连续的值可能分配到相同的分片降低事务处理的难度。 比如0、1、2都会分配在第一个分片中 可以均匀分配也可以非均匀分配。 目前这个图是非均匀分配第3个分片的范围是前2个分片的范围之和。 分片字段必须为数字类型。 因为要进行位运算 partitionCount分片的数量2,1-----有2个分片节点有一个分片节点partitionLength分片的长度256,512------前面2个分片节点的长度都是256后一个的分片节点长度是512。这2组之和是1024而且必须是1024。也就是说固定分片hash算法整个分片长度是固定的就是1024。
2).配置 schema.xml中逻辑表配置
!-- 固定分片hash算法 --
table nametb_longhash dataNodedn4,dn5,dn6 rulesharding-by-long-hash / schema.xml中数据节点配置在3.5.2水平分表中已经写过了
dataNode namedn4 dataHostdhost1 databaseitcast /
dataNode namedn5 dataHostdhost2 databaseitcast /
dataNode namedn6 dataHostdhost3 databaseitcast /rule.xml中分片规则配置这个也是rule.xml中默认没有案例
tableRule namesharding-by-long-hashrulecolumnsid/columnsalgorithmsharding-by-long-hash/algorithm/rule
/tableRule!-- 分片总长度为1024count与length数组长度必须一致 --
function namesharding-by-long-hash classio.mycat.route.function.PartitionByLongproperty namepartitionCount2,1/propertyproperty namepartitionLength256,512/property
/function分片规则属性含义
属性描述columns标识将要分片的表字段名algorithm指定分片函数与function的对应关系class指定该分片算法对应的类partitionCount分片个数列表partitionLength分片范围列表
约束 : 分片长度 : 默认最大2^10 , 为 1024 ; count, length的数组长度必须是一致的 ;
以上分为三个分区:0-255,256-511,512-1023
示例说明 :
当配置了这2个属性分片的数量partitionCount分片的长度partitionLength之后mycat在进行分片的时候就相当于在底层他要去初始化一个数组数组的整个长度是1024其中0到255索引上存放的元素全部是0256到511索引上存放的元素全部是1512到1023索引上存放的元素全部是2。当插入的id为515时他会与1023进行位与运算515转化为二进制就是10 0000 00111023转化为二进制就是11 1111 1111结果为10 0000 0011也就是515在数组中515索引对应的元素是2这个2是分片的索引所以此时会路由到第三个分片中。 3).测试
配置完毕后重新启动MyCat然后在mycat的命令行中执行如下SQL创建表、并插入数据查看数据分布情况。
配置完毕后重新启动MyCat此时会报错
#注意不能到bin目录下
cd /usr/local/src/MyCat/mycat/#先停止
bin/mycat stop#在启动
bin/mycat start#在mycat目录下查看日志此时会报错
#因为在rule.xml中还有2个引用使用到了func1,而我们在下面函数中把func1修改成了sharding-by-long-hash
#解决这个个规则测试时候我们没用到所以直接注释换删除掉即可
tail -f logs/wrapper.log注释掉后再次重新启动
#先停止
bin/mycat stop#在启动
bin/mycat start#查看日志启动成功
tail -f logs/wrapper.log重新登录mycat并切换到ITCAST数据库
mysql -h 192.168.10.210 -P 8066 -uroot -p123456#显示的是ITCAST、SHOPPING他是在schema.xml文件中配置的逻辑库
show databases;use ITCAST;#这个逻辑表tb_longhash只是逻辑上存在的在真实的数据库中并不存在所以要进行创建
show tables;然后在mycat的命令行中执行如下SQL创建表、并插入数据查看数据分布情况。 CREATE TABLE tb_longhash (id int(11) NOT NULL COMMENT ID,name varchar(200) DEFAULT NULL COMMENT 名称,firstChar char(1) COMMENT 首字母,PRIMARY KEY (id)
) ENGINEInnoDB DEFAULT CHARSETutf8mb4;insert into tb_longhash (id,name,firstChar) values(1,七匹狼,Q);
insert into tb_longhash (id,name,firstChar) values(2,八匹狼,B);
insert into tb_longhash (id,name,firstChar) values(3,九匹狼,J);
insert into tb_longhash (id,name,firstChar) values(4,十匹狼,S);
insert into tb_longhash (id,name,firstChar) values(5,六匹狼,L);
insert into tb_longhash (id,name,firstChar) values(6,五匹狼,W);
insert into tb_longhash (id,name,firstChar) values(7,四匹狼,S);
insert into tb_longhash (id,name,firstChar) values(8,三匹狼,S);
insert into tb_longhash (id,name,firstChar) values(9,两匹狼,L);效果这9条记录都是在第一个节点 当插入id为1089的数据时此时超过1024范围会落在第一个节点上。因为进行位与运算之后他出来的结果就落在第一个节点上了。
insert into tb_longhash (id,name,firstChar) values(1089,两匹狼,L);3.5.3.7 字符串hash解析算法
1).介绍 截取字符串中的指定位置的子字符串进行hash算法算出分片。
解释
固定分片hash算法针对的是数字类型的字段进行截取字符串hash解析算法针对的是字符串类型的字段进行截取
举例截取的子字符串为字段的前2位之后对截取出来的这2个子字符串进行hash运算算出的hash值在与1023进行位于运算最后根据运算的结果来决定到底落在哪一个分片节点上。 partitionCount分片的数量2-----有2个分片节点partitionLength分片的长度512------2个分片节点的长度都是512hashSlicehash运算位就是在进行hash运算的时候所截取的子字符串是哪个。 0如果在末尾代表的是整个字符串的长度如果是-1代表字符串长度减去1如果是大于0代表数字本身0:20出现在start就代表从第1个位置开始到索引为2的字符串截取出来。
2).配置 schema.xml中逻辑表配置
!-- 字符串hash解析算法 --
table nametb_strhash dataNodedn4,dn5 rulesharding-by-stringhash /schema.xml中数据节点配置在3.5.2水平分表中已经写过了
dataNode namedn4 dataHostdhost1 databaseitcast /
dataNode namedn5 dataHostdhost2 databaseitcast /rule.xml中分片规则配置默认没有需要自己定义
tableRule namesharding-by-stringhashrulecolumnsname/columnsalgorithmsharding-by-stringhash/algorithm/rule
/tableRulefunction namesharding-by-stringhash classio.mycat.route.function.PartitionByStringproperty namepartitionLength512/property !-- zero-based --property namepartitionCount2/propertyproperty namehashSlice0:2/property
/function分片规则属性含义
属性描述columns标识将要分片的表字段algorithm指定分片函数与function的对应关系class指定该分片算法对应的类partitionLengthhash求模基数 ; length*count1024 (出于性能考虑)partitionCount分区数hashSlicehash运算位 , 根据子字符串的hash运算 ; 0 代表 str.length(), -1 代表 str.length()-1 , 大于0只代表数字自身 ; 可以理解为substringstartendstart为0则只表示0
示例说明
在rule.xml配置了分片规则后他会初始化一个数组长度为1024配置了2个分片所以分为2个部分0~511之间的索引存的都是0512~1023之间的索引存的都是1。如果插入的数据需要截取的字符串为world他会截取0:23个字符为wor之后对wor进行hash运算运算出来的结果在和1023进行位于运算运算的结果为5结果是二进制转化为了十进制之后它就会拿着这个5到数组中找索引为5的元素是多少对应的是0这个0代表的就是当前这条记录会路由在第一个分片。0和1代表的是分片的索引值 3).测试
配置完毕后重新启动MyCat
#注意不能到bin目录下
cd /usr/local/src/MyCat/mycat/#先停止
bin/mycat stop#在启动
bin/mycat start#在mycat目录下查看日志
tail -f logs/wrapper.log重新登录mycat并切换到ITCAST数据库
mysql -h 192.168.10.210 -P 8066 -uroot -p123456#显示的是ITCAST、SHOPPING他是在schema.xml文件中配置的逻辑库
show databases;use ITCAST;#这个逻辑表tb_strhash只是逻辑上存在的在真实的数据库中并不存在所以要进行创建
show tables;然后在mycat的命令行中执行如下SQL创建表、并插入数据查看数据分布情况。
create table tb_strhash(name varchar(20) primary key,content varchar(100)
)engineInnoDB DEFAULT CHARSETutf8mb4;INSERT INTO tb_strhash (name,content) VALUES(T1001, UUID());
INSERT INTO tb_strhash (name,content) VALUES(ROSE, UUID());
INSERT INTO tb_strhash (name,content) VALUES(JERRY, UUID());
INSERT INTO tb_strhash (name,content) VALUES(CRISTINA, UUID());
INSERT INTO tb_strhash (name,content) VALUES(TOMCAT, UUID());效果因为只配置了2个分片所以此时只有在第一个分片和第二个分片中有这张表。分片1中有2条数据分片2中有3条数据。 3.5.3.8 按天分片算法
1).介绍 按照日期及对应的时间周期来分片。
begin开始时间end结束时间partionday周期
eg: 2022-01-1 ~ 2022-01-100放在第一个分片当中 2022-01-11 ~ 2022-01-201放在第二个分片当中 2022-01-21 ~ 2022-01-302放在第三个分片当中问题假如指定的这个分片字段的时间大于1月30号为1月31号那么这条记录该如何路由呢 答如果配置了结束时间当结束时间到达后它会重新在从头开始计算分片那也就意味着1月31号到2月9号这十天的数据会继续放到第一个分片 dateFormat日期格式sBeginDate开始时间sEndDate结束时间sPartionDay周期10代表10天为一个分片按照开始时间和结束时间相差30天也就意味着在这个范围内有3个分片。
注意事项
从开始时间开始每10天为一个分片到达结束时间之后会重复开始分片插入也就是说会再从第一个分片开始插入我们在配置逻辑表的时候所指定的分片节点的数量为3个那么在配置分片规则的时候它所计算出来的分片数量也必须是3个。这个地方设置的1月1号到1月30号每隔10天是一个分片刚好是3个这样就保证了上下是一致的如果不一致会报错。
2).配置 schema.xml中逻辑表配置
!-- 按天分片 --
table nametb_datepart dataNodedn4,dn5,dn6 rulesharding-by-date /schema.xml中数据节点配置在3.5.2水平分表中已经写过了
dataNode namedn4 dataHostdhost1 databaseitcast /
dataNode namedn5 dataHostdhost2 databaseitcast /
dataNode namedn6 dataHostdhost3 databaseitcast /rule.xml中分片规则配置没有案例自己定义
tableRule namesharding-by-daterulecolumnscreate_time/columnsalgorithmsharding-by-date/algorithm/rule
/tableRulefunction namesharding-by-date classio.mycat.route.function.PartitionByDateproperty namedateFormatyyyy-MM-dd/propertyproperty namesBeginDate2022-01-01/propertyproperty namesEndDate2022-01-30/propertyproperty namesPartionDay10/property
/function分片规则属性含义
属性描述columns标识将要分片的表字段algorithm指定分片函数与function的对应关系class指定该分片算法对应的类dateFormat日期格式sBeginDate开始日期sEndDate结束日期如果配置了结束日期则代码数据到达了这个日期的分片后会重复从开始分片插入sPartionDay分区天数默认值 10 从开始日期算起每个10天一个分区
3).测试
配置完毕后重新启动MyCat
#注意不能到bin目录下
cd /usr/local/src/MyCat/mycat/#先停止
bin/mycat stop#在启动
bin/mycat start#在mycat目录下查看日志
tail -f logs/wrapper.log登录mycat并切换到ITCAST数据库
mysql -h 192.168.10.210 -P 8066 -uroot -p123456#显示的是ITCAST、SHOPPING他是在schema.xml文件中配置的逻辑库
show databases;use ITCAST;#这个逻辑表tb_datepart只是逻辑上存在的在真实的数据库中并不存在所以要进行创建
show tables;然后在mycat的命令行中执行如下SQL创建表、并插入数据查看数据分布情况。
create table tb_datepart(id bigint not null comment ID primary key,name varchar(100) null comment 姓名,create_time date null
);insert into tb_datepart(id,name ,create_time) values(1,Tom,2022-01-01);
insert into tb_datepart(id,name ,create_time) values(2,Cat,2022-01-10);
insert into tb_datepart(id,name ,create_time) values(3,Rose,2022-01-11);
insert into tb_datepart(id,name ,create_time) values(4,Coco,2022-01-20);
insert into tb_datepart(id,name ,create_time) values(5,Rose2,2022-01-21);
insert into tb_datepart(id,name ,create_time) values(6,Coco2,2022-01-30);
insert into tb_datepart(id,name ,create_time) values(7,Coco3,2022-01-31);效果
3.5.3.9 自然月分片
1).介绍 使用场景为按照月份来分片, 每个自然月为一个分片。 注意事项
从开始时间开始一个月为一个分片到达结束时间之后会重复开始分片插入也就是说会再从第一个分片开始插入我们在配置逻辑表的时候所指定的分片节点的数量为3个那么在配置分片规则的时候它所计算出来的分片数量也必须是3个。这个地方设置的1月1号到3月31号每隔一个月是一个分片刚好是3个这样就保证了上下是一致的如果不一致会报错。
2).配置 schema.xml中逻辑表配置
!-- 按自然月分片 --
table nametb_monthpart dataNodedn4,dn5,dn6 rulesharding-by-month /schema.xml中数据节点配置在3.5.2水平分表中已经写过了
dataNode namedn4 dataHostdhost1 databaseitcast /
dataNode namedn5 dataHostdhost2 databaseitcast /
dataNode namedn6 dataHostdhost3 databaseitcast /rule.xml中分片规则配置
tableRule namesharding-by-monthrulecolumnscreate_time/columnsalgorithmpartbymonth/algorithm/rule
/tableRulefunction namepartbymonth classio.mycat.route.function.PartitionByMonthproperty namedateFormatyyyy-MM-dd/propertyproperty namesBeginDate2022-01-01/propertyproperty namesEndDate2022-03-31/property
/function分片规则属性含义
属性描述columns标识将要分片的表字段algorithm指定分片函数与function的对应关系class指定该分片算法对应的类dateFormat日期格式sBeginDate开始日期sEndDate结束日期如果配置了结束日期则代码数据到达了这个日期的分片后会重复从开始分片插入
3).测试 配置完毕后重新启动MyCat
#注意不能到bin目录下
cd /usr/local/src/MyCat/mycat/#先停止
bin/mycat stop#在启动
bin/mycat start#在mycat目录下查看日志
tail -f logs/wrapper.log重新登录mycat并切换到ITCAST数据库
mysql -h 192.168.10.210 -P 8066 -uroot -p123456#显示的是ITCAST、SHOPPING他是在schema.xml文件中配置的逻辑库
show databases;use ITCAST;#这个逻辑表tb_monthpart只是逻辑上存在的在真实的数据库中并不存在所以要进行创建
show tables;然后在mycat的命令行中执行如下SQL创建表、并插入数据查看数据分布情况。
create table tb_monthpart(id bigint not null comment ID primary key,name varchar(100) null comment 姓名,create_time date null
);insert into tb_monthpart(id,name ,create_time) values(1,Tom,2022-01-01);
insert into tb_monthpart(id,name ,create_time) values(2,Cat,2022-01-10);
insert into tb_monthpart(id,name ,create_time) values(3,Rose,2022-01-31);
insert into tb_monthpart(id,name ,create_time) values(4,Coco,2022-02-20);
insert into tb_monthpart(id,name ,create_time) values(5,Rose2,2022-02-25);
insert into tb_monthpart(id,name ,create_time) values(6,Coco2,2022-03-10);
insert into tb_monthpart(id,name ,create_time) values(7,Coco3,2022-03-31);
insert into tb_monthpart(id,name ,create_time) values(8,Coco4,2022-04-10);
insert into tb_monthpart(id,name ,create_time) values(9,Coco5,2022-04-30);效果
3.6 MyCat管理及监控
3.6.1 MyCat原理 在MyCat中当执行一条SQL语句时MyCat需要进行SQL解析、分片分析、路由分析、读写分离分析 等操作最终经过一系列的分析决定将当前的SQL语句到底路由到那几个(或哪一个)节点数据库数据 库将数据执行完毕后如果有返回的结果则将结果返回给MyCat最终还需要在MyCat中进行结果合 并、聚合处理、排序处理、分页处理等操作最终再将结果返回给客户端。
而在MyCat的使用过程中MyCat官方也提供了一个管理监控平台MyCat-WebMyCat-eye。Mycat-web 是 Mycat 可视化运维的管理和监控平台弥补了 Mycat 在监控上的空白。帮 Mycat 分担统计任务和配置管理任务。Mycat-web 引入了 ZooKeeper 作为配置中心可以管理多个节点。Mycat-web 主要管理和监控 Mycat 的流量、连接、活动线程和内存等具备 IP 白名单、邮件告警等模块还可以统计 SQL 并分析慢 SQL 和高频 SQL 等。为优化 SQL 提供依据。
3.6.2 MyCat管理方式一命令行
Mycat默认开通2个端口可以在server.xml中进行修改。
8066 数据访问端口即进行 DML 和 DDL 操作。9066 数据库管理端口即 mycat 服务管理控制功能用于管理mycat的整个集群状态
连接MyCat的管理控制台
#之前连接的是8066数据访问端口现在连接的是9066数据库管理端口
#这个密码是连接mycat的密码之前在server.xml中配置的
mysql -h 192.168.10.210 -P 9066 -uroot -p123456#注意要加分号
show help;#之前修改配置文件后需要重启mycat才能生效,现在可以使用此命令直接加载配置文件生效。
reload config;命令含义show help查看Mycat管理工具帮助文档show version查看Mycat的版本reload config重新加载Mycat的配置文件show datasource查看Mycat的数据源信息show datanode查看MyCat现有的分片节点信息show threadpool查看Mycat的线程池信息show sql查看执行的SQLshow sql.sum查看执行的SQL统计
说明
以上这些都是使用命令行的方式来进行管理的不方便查看。MyCat官方也提供了一个管理监控平台MyCat-WebMyCat-eye。 图形化界面的方式。
3.6.3 MyCat-eye方式二图形化界面
3.6.3.1 介绍
Mycat-web(Mycat-eye)是对mycat-server提供监控服务功能不局限于对mycat-server使用通过它也可以去监控mysql。他通过JDBC连接对Mycat、Mysql监控监控远程服务器(目前仅限于linux系统)的cpu、内 存、网络、磁盘。
Mycat-eye运行过程中需要依赖zookeeper因此需要先安装zookeeper。
3.6.3.2 安装
zookeeper安装Mycat-web安装 具体的安装步骤请参考资料中提供的《MyCat-Web安装文档》 MyCat-web安装文档安装Zookeeper、安装Mycat-web 3.6.3.3 访问
http://192.168.10.210:8082/mycat 3.6.3.4 配置
1).开启MyCat的实时统计功能(server.xml)
#进入到mycat的配置文件目录
cd /usr/local/src/MyCat/mycat/conf/#直接在左侧打开也可以
vim server.xml配置内容
property nameuseSqlStat1/property !-- 1为开启实时统计、0为关闭 --配置完毕后重新启动MyCat
#注意不能到bin目录下
cd /usr/local/src/MyCat/mycat/#先停止
bin/mycat stop#在启动
bin/mycat start#在mycat目录下查看日志
tail -f logs/wrapper.log
2).在Mycat监控界面配置服务地址 Mycat01192.168.10.21090668066ITCASTroot1234563.6.3.5 测试
配置好了之后我们可以通过MyCat执行一系列的增删改查的测试然后过一段时间之后打开mycat-eye的管理界面查看mycat-eye监控到的数据信息。
A.性能监控 B.物理节点 C.SQL统计
D.SQL表分析 E.SQL监控 F.高频SQL 3.7 总结 4. 读写分离
4.1 介绍
读写分离的前提是基于主从复制的简单地说是把对数据库的读和写操作分开以对应不同的数据库服务器。主数据库提供写操作从数据库提供读操作这样能有效地减轻单台数据库的压力。 方式一如果应用程序直接连接数据库那么也就意味着应用程序需要操作两个数据源执行写入操作连接的是主库执行读操作连接的是从库。这样的话应用程序在操作时就比较繁琐那么我们需要根据所执行的业务来决定到底要操作那个数据库实现起来比较麻烦不推荐这种方式。 方式二通过MyCat即可轻易实现上述功能不仅可以支持MySQL也可以支持Oracle和SQL Server关系型数据库。 应用程序执行crud操作的时候只需要连接mycat把sql语句发送给mycatmycat在根据所执行的SQL语句将sql语句路由到对应的数据库节点即可。 如果是增删改操作 它直接将sql语句路由到主节点在主节点执行增删改之后主节点的数据会同步到从节点这样主从节点的数据就一致了。如果是查询操作 它直接将sql语句路由到从节点从节点执行查询操作把数据查询后返回给应用程序即可 主要通过mycat给我们提供的2个组件来实现 writeHost写入的节点是哪个readHost读取的节点是那个
4.2 一主一从的搭建
之前已经学过了这里再次复习下。
4.2.1 原理
MySQL的主从复制是基于二进制日志binlog实现的。 4.2.2 准备
不在重新创建2台虚拟机了直接使用之前学习主从复制的2台虚拟机。
还用到了一个分片1的虚拟机因为要使用mycat。
主机角色用户名密码192.168.10.200masterroot1234192.168.10.201slaveroot1234 备注主从复制的搭建可以参考前面课程中 主从复制 章节讲解的步骤操作。 博客地址日志主从复制章节 4.2.3 测试主从复制环境是否搭建成功
在主库中执行以下sql操作
mysql -uroot -p1234create database itcast;use itcast;create table tb_user(id int(11) not null,name varchar(50) not null,sex varchar(1),primary key (id)
)engineinnodb default charsetutf8;insert into tb_user(id,name,sex) values(1,Tom,1);
insert into tb_user(id,name,sex) values(2,Trigger,0);
insert into tb_user(id,name,sex) values(3,Dawn,1);查看从库发现从库也有主库创建的库和表以及表中的数据说明主从环境搭建成功。
mysql -uroot -p1234show databases;use itcast;show tables;select * from tb_user; 4.3 一主一从读写分离
MyCat控制后台数据库的读写分离和负载均衡由schema.xml文件datahost标签的balance属性控制。
配置的是mycat当中的配置文件
4.3.1 schema.xml配置
cd /usr/local/src/MyCat/mycat/conf/配置内容 !-- 配置逻辑库 原先dataNode是加在定哟逻辑表的标签上现在没有定义逻辑表这个属性可以写在逻辑库的标签上--schema nameITCAST_RW checkSQLschematrue sqlMaxLimit100 dataNodedn7/schemadataNode namedn7 dataHostdhost7 databaseitcast /!--host属性值任意但是尽量上下2个不要一样-- dataHost namedhost7 maxCon1000 minCon10 balance3writeType0 dbTypemysql dbDriverjdbc switchType1 slaveThreshold100heartbeatselect user()/heartbeatwriteHost hostmaster urljdbc:mysql://192.168.10.200:3306?useSSLfalseamp;serverTimezoneAsia/Shanghaiamp;characterEncodingutf8 userroot password1234readHost hostsalve urljdbc:mysql://192.168.10.201:3306?useSSLfalseamp;serverTimezoneAsia/Shanghaiamp;characterEncodingutf8 userroot password1234/readHost/writeHost/dataHost上述配置的具体关联对应情况如下 writeHost代表的是写操作对应的数据库readHost代表的是读操作对应的数据库。 所以我们要想实现读写分离就得配置writeHost关联的是主库readHost关联的是从库。
注意
这个地方声明了逻辑库之后并没有指定对应的逻辑表在读写分离的结构中逻辑表可以不指定当然指定也没有问题。如果不指定它会自动的去加载所在的数据节点对应的数据库然后去读取这个数据库当中所有的表结构作为逻辑表。
而仅仅配置好了writeHost以及readHost还不能完成读写分离还需要配置一个非常重要的负责均衡的参数 balance默认是0取值有4种具体含义如下配置1或者3都可以实现读写分离
参数值含义0不开启读写分离机制 , 所有读操作都发送到当前可用的writeHost上也就是说即使你配置了readHost也不生效1全部的readHost 与 备用的writeHost 都参与select 语句的负载均衡主要针对于双主双从模式2所有的读写操作都随机在writeHost , readHost上分发并不会读写分离3所有的读请求随机分发到writeHost对应的readHost上执行, writeHost不负担读压力 只负担写压力
所以在一主一从模式的读写分离中balance配置1或3都是可以完成读写分离的。
4.3.2 server.xml配置
配置root用户可以访问SHOPPING、ITCAST 以及 ITCAST_RW逻辑库。 user nameroot defaultAccounttrueproperty namepassword123456/property!--root用户访问的逻辑库是哪个--property nameschemasSHOPPING,ITCAST,ITCAST_RW/property!--没有配置说明既能读又能写--!-- 表级 DML 权限设置 --!--privileges checktrue schema nameDB01 dml1110 table nameTB_ORDER dml1110/table /schema/privileges -- /useruser nameuserproperty namepassword123456/property!--user用户访问的逻辑库是哪个--property nameschemasSHOPPING/property!--配置只能够读--property namereadOnlytrue/property/user4.3.3 测试
1配置完毕MyCat后重新启动MyCat。
#注意不能到bin目录下
cd /usr/local/src/MyCat/mycat/#先停止
bin/mycat stop#在启动
bin/mycat start#在mycat目录下查看日志
tail -f logs/wrapper.log2登录mycat并切换到ITCAST_RW数据库
mysql -h 192.168.10.210 -P 8066 -uroot -p123456show databases;use ITCAST_RW;#显示tb_user逻辑表我们并没有在schema.xml中配置逻辑表那么这个逻辑表是哪来的呢
# 它是dn7这个dataNode数据节点对应的itcast数据库这个数据库下面有那些表
# 这个地方就会展示出来。
show tables;3然后观察在执行增删改操作时对应的主库及从库的数据变化。 在执行查询操作时检查主库及从库对应的数据变化。
在mycat中执行#执行查询操作
select * from tb_user;#执行插入操作
insert into tb_user(id,name,sex) values (4,aaaaa,0);#再次查询那么这个时候有没有实现读写分离呢
# 单纯的通过数据我们是没有办法判断的因为当我们在进行查询的时候由于主库和从库当中的数据是
# 一致的所以查询出来的数据你无法判断查的是主库还是从库当中的数据。
select * from tb_user;---------------------------------------------------------------------------------
在mysql从库中执行#解决因为主库的数据会同步到从库而从库的数据不会同步到主库所以我们可以更新从库当中的一个
# 数据比如name值为Tom的字段修改为Tom1此时从库当中的数据是Tom1主库当中的数据依然是Tom
# 这样在查询的时候就知道到底查询的是哪个节点数据库了。
mysql -uroot -p1234use itcast;show tables;select * from tb_user;update tb_user set nameTom1 where id1;---------------------------------------------------------------------------------在mycat中接着执行
#这个时候查询的结果为Tom1说明查询的是从库实现读写分离了。
select * from tb_user;#执行插入操作发现主库和从库都有这条数据说明走的是主节点
# 原因因为主节点有数据所以它走的就是主节点如果他插入的是从节点
# 从节点的数据是不会同步到主数据库的主数据库也就没有这条数据
# 所以插入操作走的是主节点实现了读写分离。
insert into tb_user(id,name,sex) values (5,bbbb,1);在mycat中直接查询无法区分查询的是主库还是从库当中的数据。 在mysql从库中修改Tom为Tom1。 在mycat中再次执行查询操作这个时候查询的结果为Tom1说明查询的是从库实现读写分离了。 主库和从库当中都有这条数据如果他插入的是从节点从节点的数据是不会同步到主数据库的主数据库也就没有这条数据所以插入操作走的是主节点实现了读写分离。 4在测试中我们可以发现当主节点Master宕机之后业务系统就只能够读而不能写入数据了。
在主库中停止mysql服务模拟主节点Master宕机
systemctl stop mysqldsystemctl status mysqld此时在mycat中只能做查询操作不能做增删改操作了。 我自己测试在从库中关闭了mysql服务之后在mycat中查询和更新操作都报错了 那如何解决这个问题呢这个时候我们就得通过另外一种主从复制结构来解决了也就是我们接下来讲解的双主双从。
4.4 双主双从的搭建
4.4.1 介绍
一个主机 Master1 用于处理所有写请求它的从机 Slave1 和另一台主机 Master2 还有它的从机 Slave2 负责所有读请求。当 Master1 主机宕机后Master2 主机负责写请求Master1 、Master2 互为备机。架构图如下:
m1主库1 s1主库1的从库 m2主库2 s2主库2的从库 为了保证这2个主从结构有关系双主双从的结构指的是m1和m2会相互复制。也就是说m1中的数据变更会同步到m2m2中的数据变更也会同步给m1这样就可以保证m1、s1、m2、s2这4台数据库服务器里面的数据是一致的。 当写入数据到m1之后那么其它的3个节点的数据会跟着变化。当写入数据到m2之后那么其它的3个节点的数据也会跟着变化。因为配置了主从复制2个主库之间又相互复制。 4.4.2 准备
我们需要准备5台服务器具体的服务器及软件安装情况如下
编号IP预装软件角色1192.168.10.210MyCat、MySQLMyCat中间件服务器2192.168.10.200MySQLM13192.168.10.201MySQLS14192.168.10.202MySQLM25192.168.10.203MySQLS2
其中MyCat中间件服务器在学习分库分表时候已经准备过了准备其它的4台虚拟机都安装了mysql并且关闭了防火墙。 关闭以上所有服务器的防火墙 systemctl stop firewalldsystemctl disable firewalld 4.4.3 搭建
这个地方修改的是mysql中的配置文件
4.4.3.1 主库配置
1). Master1(192.168.10.200)
A.修改配置文件 vim /etc/my.cnf
#mysql 服务ID保证整个集群环境中唯一取值范围1 – 2^32-1默认为1
server-id1#指定同步的数据库也就是说指定的这几个数据库会进行主从复制别的数据库不会进行主从复制的。
binlog-do-dbdb01
binlog-do-dbdb02
binlog-do-dbdb03# 当前节点在作为从数据库的时候有写入操作也要更新二进制日志文件
# 因为这个从库它需要从这个主库当中读取二进制日志文件然后完成主从复制所以也需要加上这个参数。
log-slave-updatesB.重启MySQL服务器
systemctl restart mysqldC.创建账户并授权
mysql -uroot -p1234#创建itcast用户并设置密码该用户可在任意主机连接该MySQL服务
CREATE USER itcast% IDENTIFIED WITH mysql_native_password BY Root123456;#为 itcast% 用户分配主从复制权限
GRANT REPLICATION SLAVE ON *.* TO itcast%;通过指令查看两台主库的二进制日志坐标
show master status ;2). Master2(192.168.10.202) A.修改配置文件 vim /etc/my.cnf
#mysql 服务ID保证整个集群环境中唯一取值范围1 – 2^32-1默认为1
server-id3#指定同步的数据库
binlog-do-dbdb01
binlog-do-dbdb02
binlog-do-dbdb03# 在作为从数据库的时候有写入操作也要更新二进制日志文件
log-slave-updatesB.重启MySQL服务器
systemctl restart mysqldC.创建账户并授权
这个地方因为是直接复制的一主一从的虚拟机所以账户和授权已经配置过了创建重复的账号会报错。
mysql -uroot -p1234#创建itcast用户并设置密码该用户可在任意主机连接该MySQL服务
CREATE USER itcast% IDENTIFIED WITH mysql_native_password BY Root123456;#为 itcast% 用户分配主从复制权限
GRANT REPLICATION SLAVE ON *.* TO itcast%;通过指令查看两台主库的二进制日志坐标
show master status ;4.4.3.2 从库配置
1). Slave1(192.168.10.201) A.修改配置文件 vim /etc/my.cnf
#mysql 服务ID保证整个集群环境中唯一取值范围1 – 232-1默认为1
server-id2B.重新启动MySQL服务器
systemctl restart mysqld2). Slave2(192.168.10.203) A.修改配置文件 vim /etc/my.cnf
#mysql 服务ID保证整个集群环境中唯一取值范围1 – 232-1默认为1
server-id4B.重新启动MySQL服务器
systemctl restart mysqld 4.4.3.3 从库关联主库
1).两台从库配置关联的主库 需要注意slave1对应的是master1slave2对应的是master2。 A. 在 slave1(192.168.10.201)上执行
mysql -uroot -p1234# 指定主库1的信息
CHANGE MASTER TO MASTER_HOST192.168.10.200, MASTER_USERitcast,MASTER_PASSWORDRoot123456, MASTER_LOG_FILEbinlog.000003,MASTER_LOG_POS663;#开启同步操作
start slave;#查看从库状态
show slave status \G;B. 在 slave2(192.168.10.203)上执行
mysql -uroot -p1234# 指定主库2的信息
CHANGE MASTER TO MASTER_HOST192.168.10.202, MASTER_USERitcast,MASTER_PASSWORDRoot123456, MASTER_LOG_FILEbinlog.000004,MASTER_LOG_POS663;#开启同步操作
start slave;#查看从库状态
show slave status \G;2).两台主库相互复制
Master2 复制 Master1Master1 复制 Master2。A. 在 Master1(192.168.10.200)上执行
mysql -uroot -p1234#指定Master2的连接信息
CHANGE MASTER TO MASTER_HOST192.168.10.202, MASTER_USERitcast,MASTER_PASSWORDRoot123456, MASTER_LOG_FILEbinlog.000005,MASTER_LOG_POS156;#开启同步操作
start slave;#查看从库状态
show slave status \G;B. 在 Master2(192.168.10.202)上执行
mysql -uroot -p1234#指定Master1的连接信息
CHANGE MASTER TO MASTER_HOST192.168.10.200, MASTER_USERitcast,MASTER_PASSWORDRoot123456, MASTER_LOG_FILEbinlog.000003,MASTER_LOG_POS663;#开启同步操作
start slave;#查看从库状态
show slave status \G;经过上述的三步配置之后双主双从的复制结构就已经搭建完成了。 接下来我们可以来测试验证一下。
4.4.4 测试
分别在两台主库Master1、Master2上执行DDL、DML语句查看涉及到的数据库服务器的数据同步情况。
在Master1中执行DML、DDL操作看看数据是否可以同步到另外的三台数据库中。在Master2中执行DML、DDL操作看看数据是否可以同步到另外的三台数据库中。
在主库Master1上执行
create database db01;use db01;create table tb_user(id int(11) not null primary key ,name varchar(50) not null,sex varchar(1)
)engineinnodb default charsetutf8mb4;insert into tb_user(id,name,sex) values(1,Tom,1);
insert into tb_user(id,name,sex) values(2,Trigger,0);
insert into tb_user(id,name,sex) values(3,Dawn,1);
insert into tb_user(id,name,sex) values(4,Jack Ma,1);
insert into tb_user(id,name,sex) values(5,Coco,0);
insert into tb_user(id,name,sex) values(6,Jerry,1);效果此时m1s1m2s2都有数据 在主库Master2上执行
create database db02;use db02;create table tb_user(id int(11) not null primary key ,name varchar(50) not null,sex varchar(1)
)engineinnodb default charsetutf8mb4;insert into tb_user(id,name,sex) values(1,Tom,1);
insert into tb_user(id,name,sex) values(2,Trigger,0);
insert into tb_user(id,name,sex) values(3,Dawn,1);
insert into tb_user(id,name,sex) values(4,Jack Ma,1);
insert into tb_user(id,name,sex) values(5,Coco,0);
insert into tb_user(id,name,sex) values(6,Jerry,1);效果此时m1s1m2s2同样都有数据 完成了上述双主双从的结构搭建之后接下来我们再来看看如何完成这种双主双从的读写分离。
4.5 双主双从读写分离
在mycat的配置文件中进行配置
#配置文件都是存放在mycat解压后的conf目录
cd /usr/local/src/MyCat/mycat/conf/4.5.1 配置
MyCat控制后台数据库的读写分离和负载均衡由schema.xml文件datahost标签的balance属性控制通过writeType及switchType来完成失败自动切换的。
1).schema.xml
配置逻辑库
schema nameITCAST_RW2 checkSQLschematrue sqlMaxLimit100 dataNodedn7
/schema配置数据节点
dataNode namedn7 dataHostdhost7 databasedb01 /配置节点主机 !--还需要配置balance属性--dataHost namedhost7 maxCon1000 minCon10 balance1writeType0 dbTypemysql dbDriverjdbc switchType1 slaveThreshold100heartbeatselect user()/heartbeat!--配置主库1从库1的数据库连接信息--writeHost hostmaster1 urljdbc:mysql://192.168.10.200:3306?useSSLfalseamp;serverTimezoneAsia/Shanghaiamp;characterEncodingutf8 userroot password1234readHost hostsalve1 urljdbc:mysql://192.168.10.201:3306?useSSLfalseamp;serverTimezoneAsia/Shanghaiamp;characterEncodingutf8 userroot password1234/readHost/writeHost!--配置主库2从库2的数据库连接信息--writeHost hostmaster2 urljdbc:mysql://192.168.10.202:3306?useSSLfalseamp;serverTimezoneAsia/Shanghaiamp;characterEncodingutf8 userroot password1234readHost hostsalve2 urljdbc:mysql://192.168.10.203:3306?useSSLfalseamp;serverTimezoneAsia/Shanghaiamp;characterEncodingutf8 userroot password1234/readHost/writeHost/dataHost具体的对应情况如下
属性说明
balance“1” 代表全部的 readHost 读主机s1、m2、s2与 stand by writeHost 备用写主机m1参与 select 语句的负载均衡简单的说当双主双从模式(M1-S1M2-S2并且 M1 与 M2 互为主备)正常情况下S1、M2、S2 都参与 select 语句的负载均衡而m1负责写入操作这样就完成了读写分离 ;解释balance为1代表的就是在双主双从的模式下进行负载均衡在双主双从的模式下m1负责写入操作而其它的s1、m2、s2负责读取操作。 writeType 0 : 写操作都转发到第1台writeHostwriteHost1挂了, 会切换到writeHost2上;1 : 所有的写操作都随机地发送到配置的writeHost上 ; writeHost用来配置主数据库的连接信息。 switchType -1 : 不自动切换1 : 自动切换 指的是writeHost1挂掉了之后会不会自动切换到writeHost2。
2).server.xml
配置root用户也可以访问到逻辑库 ITCAST_RW2。 user nameroot defaultAccounttrueproperty namepassword123456/property!--root用户访问的逻辑库是哪个--property nameschemasSHOPPING,ITCAST,ITCAST_RW2/property!--没有配置说明既能读又能写--!-- 表级 DML 权限设置 --!--privileges checktrue schema nameDB01 dml1110 table nameTB_ORDER dml1110/table /schema/privileges -- /useruser nameuserproperty namepassword123456/property!--user用户访问的逻辑库是哪个--property nameschemasSHOPPING/property!--配置只能够读--property namereadOnlytrue/property/user具体的对应情况如下
修改完成配置后重启mycat
#注意不能到bin目录下
cd /usr/local/src/MyCat/mycat/#先把之前启动的mycat 关闭掉
bin/mycat stop#启动
bin/mycat start#在mycat目录下查看日志是否启动成功
tail -f logs/wrapper.log 4.5.2 测试
登录MyCat测试查询及更新操作判定是否能够进行读写分离以及读写分离的策略是否正确。
1登录MyCat
mysql -h 192.168.10.210 -P 8066 -uroot -p123456show databases;use ITCAST_RW2;#显示tb_user同一主一从一样虽然没有配置逻辑表但是它会把dn7这个数据节点对应的数据库db01
# 下的所有表作为逻辑表显示。db01数据库此时只有tb_user一张表所以这个地方显示的是tb_user作为逻辑表。
show tables;#直接查询因为现在4个数据库m1 s1 m2 s2中的数据是一样的所以无无区分查询的是哪一个数据库#和之前学习一主一从一样同样可以通过修改从库进行测试
select * from tb_user; 2修改从库中的数据
因为m1主库1的数据会同步给s1从库1m2主库2的数据会同步给s2从库2。反过来s1从库1的数据不会同步给m1主库1s2从库2的数据不会同步给m2主库2。所以此时可以修改s1和s2的字段这样主库和从库的数据就不相同了再次执行查询就知道查询的是主库还是从库了。
在从库1上执行
mysql -uroot -p1234use db01;show tables;select * from tb_user;#此时从库1的字段值为TomS1
update tb_user set nameTomS1 where id1;-----------------------------------------------------在从库2上执行mysql -uroot -p1234use db01;show tables;select * from tb_user;#此时从库2的字段值为TomS2
update tb_user set nameTomS2 where id1;3在mycat中再次进行查询
如果查询到的字段是TomS1说明数据来自从库1如果字段是TomS2说明数据来自从库2如果查询到的字段是Tom说明数据来自主库1或者主库2。因为配置了双主双从模式实际上查询的Tom是来自于主库2的但是主库1和主库2的字段都是Tom所以无法区分也不能修改主库2的字段因为主库1和主库2会相互复制里面的数据是一样的。
select * from tb_user;4在mycat中进行插入操作
双主双从模式下m1是写入增删改操作s1、m2、s2都是读取查询操作。如果是在主节点1中插入数据的他会把数据同步给从库1、主库2、从库2中此时4个节点的数据库都会有这条数据。说明数据是在主库1或者主库2中插入的实现了读写分离。 因为在主库1或者主库2中插入数据这4个节点都会有数据所以只看数据无法区分插入的是主库1还是主库2只能区分是在主库上插入还是在从库中插入。 如果是在从库中插入数据的从库中的数据不会同步给主库所以此时主库中没有这条数据也就没有实现读写分离。
insert into tb_user(id,name,sex) values (7,AAAAA,0);5当主库挂掉一个之后是否能够自动切换。
在主库1中停止mysql服务模拟主节点Master1宕机
#在主库1中执行不需要登录mysql#停止mysql服务
systemctl stop mysqld#查看mysql状态
systemctl status mysqld 在mycat中执行查询和插入操作
#登录mycat后执行
mysql -h 192.168.10.210 -P 8066 -uroot -p123456use ITCAST_RW2;show tables;#可以进行查询
#正常情况主库1是写入操作从库2 主库2 从库2负责读取操作
#主库1挂掉之后主库2负责写入操作从库2负责读取操作
#当然查询操作走的是从库1 主库2 从库2主库1挂掉之后影响的是增删改所以主库1挂不挂掉都不影响查询操作
# 没办法区分是否实现了高可用。
SELECT * FROM tb_user;#可以进行插入
#主库1已经挂了所以此时插入是的主库2之后同步给从库2。
#这个时候主库2和从库2有这条记录主库1 和从库1没有这条记录
#主库1挂掉之后影响的是是增删改 也就是说不能在进行增删改操作了但是现在执行插入操作任然可以成功说明
# 他把主库2变为写入操作了增删改从库2进行读取操作也就实现了高可用。
insert into tb_user(id,name,sex) values (8,BBBBB,1);效果
主库1主库1挂了直接就连不上数据库里面当然没有这条数据了从库1可以看到没有这条记录主库2有这条记录从库2有这条记录当master1挂掉之后master会自动联系上来这样就保证了数据库的高可用。 4.6 读写分离总结 运维篇总结