下载Mycat

https://github.com/MyCATApache/Mycat-Server/releases

Mycat基础分库

基础配置

  1. 修改server.xml
<user name="root" defaultAccount="true">
<property name="password">123456</property>
<property name="schemas">TESTDB</property>
<property name="defaultSchema">TESTDB</property>
<!--No MyCAT Database selected 错误前会尝试使用该schema作为schema,不设置则为null,报错 --> <!-- 表级 DML 权限设置 -->
<!--
<privileges check="false">
<schema name="TESTDB" dml="0110" >
<table name="tb01" dml="0000"></table>
<table name="tb02" dml="1111"></table>
</schema>
</privileges>
-->
</user>

可以修改用户名和密码以及逻辑库名。另外将全局主键改为文件的方式,将下面的1改为0.

<property name="sequenceHandlerType">1</property>
  1. 修改schema.xml

修改了数据库名,数据库用户密码

<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/"> <schema name="TESTDB" checkSQLschema="true" sqlMaxLimit="100" randomDataNode="dn1">
<table name="position" primaryKey="id" dataNode="dn1,dn2" rule="sharding-by-intfile" autoIncrement="true" >
</table>
</schema> <dataNode name="dn1" dataHost="localhost1" database="ds_0" />
<dataNode name="dn2" dataHost="localhost1" database="ds_1" /> <dataHost name="localhost1" 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://localhost:3306" user="root"
password="0490218292">
</writeHost>
</dataHost> </mycat:schema>
  1. 配置rule.xml

rule.xml里定义了很多分片规则,我们选择最简单的取模分片mod-long,只需要将这个名称配置到schema.xml里就行了。另外因为我们只有2个节点,所以取余的数量需要将3改为2。

<function name="mod-long" class="io.mycat.route.function.PartitionByMod">
<!-- how many data nodes -->
<property name="count">3</property>
</function>

将mod-long配置到rule里。

<table name="position" primaryKey="id" dataNode="dn1,dn2" rule="mod-long" autoIncrement="true" >
</table>

启动

在mycat/bin目录下,用管理员身份启动cmd,执行如下命令:

mycat install
mycat start

启动完成后,就可以进行访问了。

命令行方式:

mysql -uroot -p123456 -h127.0.0.1 -P8066

测试

插入数据测试:

INSERT INTO POSITION (id,NAME,salary,city) VALUES(1,"lagou3","1222","sichuan");
INSERT INTO POSITION (id,NAME,salary,city) VALUES(2,"lagou3","1222","sichuan");
INSERT INTO POSITION (id,NAME,salary,city) VALUES(3,"lagou3","1222","sichuan");
INSERT INTO POSITION (id,NAME,salary,city) VALUES(4,"lagou3","1222","sichuan");

数据是否分布到了ds_0、ds_1两个库中。

查询:

select * from POSITION;

看能否查出两个库中的所有数据。

碰到的问题

问题1:因为我是mysql8,所以在mycat/lib中用mysql-connector-java-8.0.11.jar替换了原有的.

问题2:The server time zone value '???ú±ê×??±??' is unrecognized or represents more than one time zone

<writeHost host="hostM1" url="jdbc:mysql://localhost:3306?serverTimezone=UTC&amp;useSSL=false&amp;useUnicode=true&amp;characterEncoding=UTF-8" user="root"
password="0490218292">
</writeHost>

url配置里加上了时区。

此外mycat还有如下命令:

启动命令:./mycat start
停止命令:./mycat stop
重启命令:./mycat restart
查看状态:./mycat status

全局序列ID

全局序列id有5种方式可以选择。

在server.xml里有如下配置:

<property name="sequenceHandlerType">0</property>
  • 0 代表本地文件方式
  • 1 代表数据库方式生成
  • 2 代表使用本地时间戳方式
  • 3 表示基于ZK与本地配置的分布式ID生成器
  • 4 使用zookeeper递增方式生成

1. 本地文件方式

本地主键的配置文件是conf/sequence_conf.properties。

#default global sequence
GLOBAL.HISIDS=
GLOBAL.MINID=10001
GLOBAL.MAXID=20000
GLOBAL.CURID=10000 # self define sequence
COMPANY.HISIDS=
COMPANY.MINID=1001
COMPANY.MAXID=2000
COMPANY.CURID=1000 CUSTOMER.HISIDS=
CUSTOMER.MINID=1001
CUSTOMER.MAXID=2000
CUSTOMER.CURID=1000 ORDER.HISIDS=
ORDER.MINID=1001
ORDER.MAXID=2000
ORDER.CURID=1000 HOTNEWS.HISIDS=
HOTNEWS.MINID=1001
HOTNEWS.MAXID=2000
HOTNEWS.CURID=1000

我们默认在进行插入的时候就会使用mycat的全局主键生成,那么上面有那么多的配置项,具体取哪一个配置项呢?

这个配置的前缀是跟表名对应的。举例说明:

<table name="position" primaryKey="id" dataNode="dn1,dn2" rule="mod-long" autoIncrement="true" >
</table>

比如这个表,就需要配置如下:

POSITION.HISIDS=
POSITION.MINID=1
POSITION.MAXID=20000
POSITION.CURID=0

这样,在我们不指定id进行插入时就可以取我们配置的序列号了。

INSERT INTO POSITION (NAME,salary,city) VALUES("lagou3","1222","sichuan");

当然也可以显示指定取哪一个序列号配置:

INSERT INTO POSITION (id,NAME,salary,city) VALUES('next value for MYCATSEQ_GLOBAL',"lagou3","1222","sichuan");

MYCATSEQ_ 后面连接的就是配置前缀名称。

2. 数据库方式

配置文件是conf/sequence_db_conf.properties,里面需要配置db的id相关的配置信息存在哪个库中。

#sequence stored in datanode
GLOBAL=dn1
COMPANY=dn1
CUSTOMER=dn1
ORDERS=dn1

此处的dn1是逻辑库名。

我们需要在dn1对应的数据库中新建表,并且插入数据。Mycat给我们提供了建表等语句(conf/dbseq.sql)。我们执行即可。

increment字段表示一次从数据库取几个值。比如设置为10的话,就是一次取10个id供应用端使用。

3. 时间戳方式

配置文件是conf/sequence_time_conf.properties。

#sequence depend on TIME
WORKID=01
DATAACENTERID=01

全局表配置

只需要在schema.xml的配置中加上type=global就行了

<schema name="TESTDB" checkSQLschema="true" sqlMaxLimit="100" randomDataNode="dn1">
<table name="city" primaryKey="id" dataNode="dn1,dn2" autoIncrement="true" type="global" >
</table>
</schema>

读写分离

通过writeHost 和readHost 实现

<dataHost name="localhost2" maxCon="1000" minCon="10" balance="1"
writeType="0" dbType="mysql" dbDriver="jdbc" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<writeHost host="hostM1" url="jdbc:mysql://localhost:3306?serverTimezone=UTC&amp;useSSL=false&amp;useUnicode=true&amp;characterEncoding=UTF-8" user="root"
password="0490218292">
<readHost host="hostS1" url="jdbc:mysql://192.168.56.115:3306?serverTimezone=UTC&amp;useSSL=false&amp;useUnicode=true&amp;characterEncoding=UTF-8" user="root"
password="123456"> </readHost>
</writeHost>
</dataHost>

或者

<dataHost name="localhost2" maxCon="1000" minCon="10" balance="1"
writeType="0" dbType="mysql" dbDriver="jdbc" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<writeHost host="hostM1" url="jdbc:mysql://localhost:3306?serverTimezone=UTC&amp;useSSL=false&amp;useUnicode=true&amp;characterEncoding=UTF-8" user="root"
password="0490218292"> </writeHost> <writeHost host="hostS1" url="jdbc:mysql://192.168.56.115:3306?serverTimezone=UTC&amp;useSSL=false&amp;useUnicode=true&amp;characterEncoding=UTF-8" user="root"
password="123456"> </writeHost>
</dataHost>

两种方式对比:

  • 第一种配置方式,如果写节点挂了,读节点不可用。
  • 第二种配置方式(查询的时候取第二个writeHost),如果其中一个写节点挂了,另一个不受影响。

如果设置全库的读写分离,schema.xml配置如下:

<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/"> <schema name="TESTDB" checkSQLschema="true" sqlMaxLimit="100" dataNode="dn3"> </schema> <dataNode name="dn3" dataHost="localhost2" database="crm" /> <dataHost name="localhost2" maxCon="1000" minCon="10" balance="1"
writeType="0" dbType="mysql" dbDriver="jdbc" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<writeHost host="hostM1" url="jdbc:mysql://localhost:3306?serverTimezone=UTC&amp;useSSL=false&amp;useUnicode=true&amp;characterEncoding=UTF-8" user="root"
password="0490218292">
<readHost host="hostS1" url="jdbc:mysql://192.168.56.115:3306?serverTimezone=UTC&amp;useSSL=false&amp;useUnicode=true&amp;characterEncoding=UTF-8" user="root"
password="123456"> </readHost>
</writeHost>
</dataHost> </mycat:schema>

此时里不能配置表的一些配置数据。

如果设置某些表(示例中是dept)读写分离,配置如下:

<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/"> <schema name="TESTDB" checkSQLschema="true" sqlMaxLimit="100" randomDataNode="dn1">
<table name="position" primaryKey="id" dataNode="dn1,dn2" rule="mod-long" autoIncrement="true" >
</table>
<table name="city" primaryKey="id" dataNode="dn1,dn2" autoIncrement="true" type="global" >
</table>
<table name="dept" primaryKey="id" dataNode="dn3" autoIncrement="true" ruleRequired="false">
</table>
</schema> <dataNode name="dn1" dataHost="localhost1" database="ds_0" />
<dataNode name="dn2" dataHost="localhost1" database="ds_1" />
<dataNode name="dn3" dataHost="localhost2" database="crm" /> <dataHost name="localhost1" 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://localhost:3306?serverTimezone=UTC&amp;useSSL=false&amp;useUnicode=true&amp;characterEncoding=UTF-8" user="root"
password="0490218292">
</writeHost>
</dataHost> <dataHost name="localhost2" maxCon="1000" minCon="10" balance="1"
writeType="0" dbType="mysql" dbDriver="jdbc" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<writeHost host="hostM1" url="jdbc:mysql://localhost:3306?serverTimezone=UTC&amp;useSSL=false&amp;useUnicode=true&amp;characterEncoding=UTF-8" user="root"
password="0490218292">
<readHost host="hostS1" url="jdbc:mysql://192.168.56.115:3306?serverTimezone=UTC&amp;useSSL=false&amp;useUnicode=true&amp;characterEncoding=UTF-8" user="root"
password="123456"> </readHost>
</writeHost>
</dataHost> </mycat:schema>

强制路由

通过mycat的注释实现:

/*#mycat:db_type=slave*/ SELECT * FROM dept;
/*#mycat:db_type=master*/ SELECT * FROM dept;

1.6版本后,还有如下注释:

/*!mycat:sql=sql */    指定真正执行的SQL
/*!mycat:schema=schema1 */ 指定走那个schema
/*!mycat:datanode=dn1 */  指定sql要运行的节点
/*!mycat:catlet=io.mycat.catlets.ShareJoin */ 通过catlet支持跨分片复杂SQL实现以及存
储过程支持等

主从延时切换

switchType参数:

  • -1:表示不自动切换
  • 1:表示自动切换
  • 2:表示基于Mysql主从同步状态决定是否切换
  • 3:基于Mysql cluster集群切换机制

1.4版本后开始支持MySQL主从复制状态绑定的读写分离机制,让读操作更加安全可靠。需要配置内容如下:

MyCAT心跳检查语句配置为 show slave status,dataHost上定义两个新属性:switchType="2"与slaveThreshold="100"

此时意味着开启 MySQL 主从复制状态绑定的读写分离与切换机制,Mycat心

跳机制通过检测 show slave status 中的 "Seconds_Behind_Master", "Slave_IO_Running",

"Slave_SQL_Running" 三个字段来确定当前主从同步的状态以及 Seconds_Behind_Master 主从复制时延, 当Seconds_Behind_Master > slaveThreshold时,读写分离筛选器会过滤掉此Slave机器,防止读到很久之前的旧数据,而当主节点宕机后,切换逻辑会检查Slave上的Seconds_Behind_Master是否为0,为0时则表示主从同步,可以安全切换,否则不会切换

<dataHost name="localhost1" maxCon="1000" minCon="10" balance="0" writeType="0"
dbType="mysql" dbDriver="native" switchType="2" slaveThreshold="100">
<heartbeat>show slave status </heartbeat>
<!-- can have multi write hosts -->
<writeHost host="M1" url="localhost:3306" user="root" password="123456">
</writeHost>
<writeHost host="S1" url="localhost:3316" user="root"
</dataHost>

1.4.1开始支持MySQL集群模式:

<dataHost name="localhost1" maxCon="1000" minCon="10" balance="0" writeType="0"
dbType="mysql" dbDriver="native" switchType="3" >
<heartbeat> show status like ‘wsrep%’</heartbeat>
  <writeHost host="M1" url="localhost:3306" user="root"password="123456">
</writeHost>
<writeHost host="S1"url="localhost:3316"user="root"password="123456" >
</writeHost>
</dataHost>

XA事务使用

Mycat 从 1.6.5 版本开始支持标准XA分布式事务,考虑到MySQL5.7之前版本XA有bug,所以推荐最佳搭配XA功能使用 MySQL 5.7 版本。

Mycat实现XA标准分布式事务,Mycat作为XA事务协调者角色,即使事务过程中Mycat宕机挂掉,由于Mycat会记录事务日志,所以Mycat恢复后会进行事务的恢复善后处理工作。考虑到分布式事务的性能开销比较大,所以只推荐在全局表的事务以及其他一些对一致性要求比较高的场景。

使用示例:

  • XA事务需要设置手动提交
set autocommit=0;
  • 开启XA事务
set xa=on;
  • 执行相应的SQL语句部分
insert into city(id,name,province) values(200,'chengdu','sichuan');
update position set salary='300000' where id<5;
  • 提交或回滚事务
commit;
rollback;

如果其中一个sql语句失败,整体都会回滚。

保证Repeatable Read

mycat 有一个特性,就是开事务之后,如果不运行 update/delete/select for update 等更新类语句SQL 的话,不会将当前连接与当前 session 绑定。如下图所示:

这样做的好处是可以保证连接可以最大限度的复用,提升性能。但是回导致两次查询的结果不一致。违背了MySQL可重复读的特性。Mycat给我们提供了一个配置来解决这个问题。

server.xml 的 system 配置了 strictTxIsolation=true)(默认是false) 的时候,就会严格遵守隔离级别。配置后的连接如下图所示:

MyCat应用实战的更多相关文章

  1. 一步一步在Windows中使用MyCat负载均衡

    一步一步在Windows中使用MyCat负载均衡 http://www.cnblogs.com/zhangs1986/p/6408981.html   mycat+sqlServer简单demo配置 ...

  2. MyCAT+MySQL搭建高可用企业级数据库集群视频课程

    原文地址:https://www.guangboyuan.cn/mycatmysql%E6%90%AD%E5%BB%BA%E9%AB%98%E5%8F%AF%E7%94%A8%E4%BC%81%E4% ...

  3. 【无私分享:ASP.NET CORE 项目实战(第十三章)】Asp.net Core 使用MyCat分布式数据库,实现读写分离

    目录索引 [无私分享:ASP.NET CORE 项目实战]目录索引 简介 MyCat2.0版本很快就发布了,关于MyCat的动态和一些问题,大家可以加一下MyCat的官方QQ群:106088787.我 ...

  4. 15套java架构师、集群、高可用、高可扩展、高性能、高并发、性能优化、Spring boot、Redis、ActiveMQ、Nginx、Mycat、Netty、Jvm大型分布式项目实战视频教程

    * { font-family: "Microsoft YaHei" !important } h1 { color: #FF0 } 15套java架构师.集群.高可用.高可扩展. ...

  5. 15套java架构师、集群、高可用、高可扩 展、高性能、高并发、性能优化Redis、ActiveMQ、Nginx、Mycat、Netty、Jvm大型分布式项目实战视频教程

    * { font-family: "Microsoft YaHei" !important } h1 { color: #FF0 } 15套java架构师.集群.高可用.高可扩 展 ...

  6. [Big Data - Codis, Mycat(cobar)] 企业互联网+转型实战:如何进行PB级别数据的架构变迁

    随着DT时代的来临,数据对于企业经营决策的价值日益凸显,而企业在进行互联网+转型的过程中,如何让数据架构平滑迁移到大数据平台,对于传统业务的转型升级至关重要.企业IT部门该如何进行PB级别大数据平台的 ...

  7. mycat实战之性能测试

    1.安装性能监控工具 1.1 nmon 安装nmon de >#下载地址 http://nmon.sourceforge.net/pmwiki.php?n=Site.Download nmon1 ...

  8. Mycat实战之数据迁移(oracle -- mysql)

    1.案例场景: Mycat 后面接一个 Oracle 实例与一个 MySQL 实例,假设用户表,订单表,转账记录表, Oracle 字符集为 GBK 的,MySQL 字符集则要求 UTF8的 完成用户 ...

  9. MYCAT实战之分片迁移

    实践扩容 1.要求: travelrecord 表定义为10个分片,尝试将10个分片中的 2 个分片转移到第二台MySQL上, 并完成记录要求,最快的数据迁移做法,中断业务时间最短 2.针对分片以及迁 ...

随机推荐

  1. css3种不知道宽高的情况下水平垂直居中的方法

    第一种:display:table-cell 组合使用display:table-cell和vertical-align.text-align,使父元素内的所有行内元素水平垂直居中(内部div设置di ...

  2. Blazor组件自做八 : 使用JS隔离封装屏幕键盘kioskboard.js组件

    1. 运行截图 演示地址 2. 在文件夹wwwroot/lib,添加kioskboard子文件夹,添加kioskboards.js文件 2.1 常规操作,懒加载js库, export function ...

  3. coolshell-初见

    首页:https://coolshell.cn/tag/programmer 我是怎么招聘程序员的 https://coolshell.cn/articles/1870.html 程序员需要具备的基本 ...

  4. LC-数组-二分查找-704

    二分查找 [left, right] 方式 [left, mid -1] [mid + 1, right] int left = 0, right = nums.length - 1; while ( ...

  5. 各系统升级openssh

    修订号: [V1.0] 修订人: [陈土锋] 修订日期: [2019.06.04] 前言 该文档只适用用于服务器Redhat,centos,Ubuntu和suse系统的openssh升级.需要注意必须 ...

  6. window升级Nginx1.10到1.12.2

    window升级Nginx较为简单,只需要修改配置文件,然后启动即可. 环境:window系统 服务器:10.123.98.92 Nginx目录:e:\hgeagle\nginx-1.10.1 旧版N ...

  7. Linux系统安装后IP能通端口不通的问题处理方法

    网上大部分都是针对防火墙的问题,这里首先排除防火防火墙导致端口不通的问题! 1.排除防火墙问题(防火墙的排查方式网上一搜全是,这里不再赘述) 2.查看检查端口有没有监听,发现端口未监听(比如8080端 ...

  8. Python 速通爆肝、列表推导式、生成器、装饰器、生命游戏

    列表推导式.赋值.切片(替换.插入).字符串处理与判断.enumerate().格式化字符串.读写文件.global 关键字.字符串startswith().类与对象.生成器.装饰器.Self.*ar ...

  9. Restful API和传统的API的区别

    一.功能区别 Restful API是当作资源的唯一标识符,而传统是实现某某功能 如:/api/getList/1 and /api/getList?page=1 二.methods多样性 Restf ...

  10. python基础练习题(题目 模仿静态变量的用法)

    day27 --------------------------------------------------------------- 实例041:类的方法与变量 题目 模仿静态变量的用法. 程序 ...