Mycat 高可用数据库架构搭建及读写分离,主从切换测试案例

Mycat 简介

系统开发中,数据库是非常重要的一个点。除了程序的本身的优化,如:SQL 语句优化、代
码优化,数据库的处理本身优化也是非常重要的。主从、热备、分表分库等都是系统发展迟
早会遇到的技术问题问题。Mycat 是一个广受好评的数据库中间件,已经在很多产品上进行
使用了。希望通过这篇文章的介绍,能学会 Mycat 的使用。

什么是 Mycat

• 一个彻底开源的,面向企业应用开发的大数据库集群
• 支持事务、ACID、可以替代 MySQL 的加强版数据库
• 一个可以视为 MySQL 集群的企业级数据库,用来替代昂贵的 Oracle 集群
• 一个融合内存缓存技术、NoSQL 技术、HDFS 大数据的新型 SQL Server
• 结合传统数据库和新型分布式数据仓库的新一代企业级数据库产品
• 一个新颖的数据库中间件产品

常用功能

分库分表

一个系统的多张数据表,存储到多个数据库实例中;

对于一张多行(记录)多列(字段)的二维数据表,又分两种情形:

垂直分表: 竖向切分,不同分表存储不同的字段,可以把不常用或者大容量、或者不同
业务的字段拆分出去;

水平分表(最复杂): 横向切分,按照特定分片算法,不同分表存储不同的记录。

读写分离

不同的数据库,同步相同的数据,分别只负责数据的读和写;

主从切换

数据库宕机后自动切换到备机

安装

Mycat 官网下载地址:http://www.mycat.io/

根据不同的系统选择不同的版本。包括 linux、windows、mac,作者考虑还是非常周全的,当
然,也有源码版的。(ps:源码版的下载后,只要配置正确,就可以正常运行调试,这个赞一
下。)
Mycat 高可用数据库架构搭建及读写分离,主从切换测试案例_第1张图片
Mycat 的安装其实只要解压下载的目录就可以了,非常简单。
安装完成后,目录如下:

Mycat 高可用数据库架构搭建及读写分离,主从切换测试案例_第2张图片

配置文件

Mycat 的配置文件都在 conf 目录里面,这里介绍几个常用的文件:
Mycat 高可用数据库架构搭建及读写分离,主从切换测试案例_第3张图片
Mycat 的架构其实很好理解,Mycat 是代理,Mycat 后面就是物理数据库。和 Web 服务器的
Nginx 类似。对于使用者来说,访问的都是 Mycat,不会接触到后端的数据库。

指令

Mycat 的启动也很简单,启动命令在 Bin 目录:

启动

mycat start

停止

mycat stop

重启

mycat restart

如果在启动时发现异常,在 logs 目录中查看日志。

wrapper.log 为程序启动的日志,启动时的问题看这个

mycat.log 为脚本执行时的日志,SQL 脚本执行报错后的具体错误内容,查看这个文件。

mycat.log 是最新的错误日志,历史日志会根据时间生成目录保存。

mycat 启动后,执行命令不成功,可能实际上配置有错误,导致后面的命令没有很好的执行。

Mycat 带来的最大好处就是使用是完全不用修改原有代码的,在 mycat 通过命令启动后,你
只需要将数据库连接切换到 Mycat 的地址就可以了。
如下面就可以进行连接了:

mysql -h192.168.0.1 -P8806 -uroot -p123456

连接成功后可以执行 sql 脚本了。

Mycat 还有一个管理的连接,端口号是 9906.

mysql -h192.168.0.1 -P9906 -uroot -p123456

连接后可以根据管理命令查看 Mycat 的运行情况,当然,喜欢 UI 管理方式的人,可以安装
一个 Mycat-Web 来进行管理,有兴趣自行搜索。

简而言之,开发中使用 Mycat 和直接使用 Mysql 机会没有差别。

使用场景

以某个系统为例,有 6 台 mysql 物理库集群,划分了 4 个逻辑库,分别是订单库,商品库,
用户库和系统库,数据量较大的订单库和商品库下分别挂两个物理库 order1 和 order2,
goods1 和 goods2,用户库和系统库分别下挂一个物理库 user1 和 sys1
order1 和 order2 做读写分离,读操作发往 order1,写操作发往 order2;
order1 和 order2 做主从复制,主从切换,实时同步两边数据,宕机后切换备机,恢复后切
换回主机
goods1 和 goods2 做读写分离,读操作发往 goods1,写操作发往 goods2
goods1 和 goods2 做主从复制,主从切换,实时同步两边数据,宕机后切换备机,恢复后切
换回主机

高可用架构

Mycat 高可用数据库架构搭建及读写分离,主从切换测试案例_第4张图片

分库结构

Mycat 高可用数据库架构搭建及读写分离,主从切换测试案例_第5张图片

配置

server.xml

配置 mycat 的登陆用户名,密码和操作的数据库


	123456
	xxx
	false

schema.xml

配置分库分表信息,逻辑库节点
物理库名


物理表,逻辑节点

心跳 show slave status 写库信息 读库信息 同时读库也是写库的备份库 写库信息 读库信息 同时读库也是写库的备份库 写库信息 select user() 写库信息

log4j2.xml

日志配置


测试用例

分库

登陆 mycat
从任意一台 mysql 主机访问

mysql -h172.16.23.126 -P8066 -uroot -p123456

查询表分片:

mysql> use xxx;
mysql> explain select * from tb_order;
±----------±---------------------------------+
| DATA_NODE | SQL |
±----------±---------------------------------+
| order | SELECT * FROM tb_order LIMIT 100 |
±----------±---------------------------------+
1 row in set (0.00 sec)
mysql> explain select * from tb_item;
±----------±--------------------------------+
| DATA_NODE | SQL |
±----------±--------------------------------+
| goods | SELECT * FROM tb_item LIMIT 100 |
±----------±--------------------------------+
1 row in set (0.03 sec)
mysql> explain select * from tb_member;
±----------±----------------------------------+
| DATA_NODE | SQL |
±----------±----------------------------------+
| user | SELECT * FROM tb_member LIMIT 100 |
±----------±----------------------------------+
1 row in set (0.00 sec)
mysql> explain select * from tb_express;
±----------±-----------------------------------+
| DATA_NODE | SQL |
±----------±-----------------------------------+
| sys | SELECT * FROM tb_express LIMIT 100 |
±----------±-----------------------------------+
1 row in set (0.08 sec)

读写分离

监控日志
/root/mycat/logs/mycat.log

指令:

SELECT * FROM tb_order;

Orderhost 读操作走的是 3302 库

**2019-04-01 10:01:49.271 DEBUG [$_NIOREACTOR-1-RW]
(io.mycat.server.NonBlockingSession.releaseConnection(NonBlockingSession.java:341)) -
release connection MySQLConnection [id=41, lastTime=1554112909262, user=root,
schema=zmall, old shema=zmall, borrowed=true, fromSlaveDB=true, threadId=30,
charset=latin1, txIsolation=3, autocommit=true, attachment=order{SELECT *
FROM tb_order
LIMIT 100}, respHandler=SingleNodeHandler [node=order{SELECT *
FROM tb_order
LIMIT 100}, packetId=20], host=172.16.22.119, port=3302, statusSync=null, writeQueue=0,
modifiedSQLExecuted=false]

指令:

insert into tb_order(order_id,payment) values (1,200) ;

Orderhost 写操作走的是 3301 库

2019-04-01 10:04:21.311 DEBUG [$_NIOREACTOR-1-RW]
(io.mycat.server.NonBlockingSession.releaseConnection(NonBlockingSession.java:341)) -
release connection MySQLConnection [id=15, lastTime=1554113061162, user=root,
schema=zmall, old shema=zmall, borrowed=true, fromSlaveDB=false, threadId=38,
charset=latin1, txIsolation=3, autocommit=true, attachment=order{insert into
tb_order(order_id,payment) values (1,200)}, respHandler=SingleNodeHandler
[node=order{insert into tb_order(order_id,payment) values (1,200)}, packetId=1],
host=172.16.22.119, port=3301, statusSync=null, writeQueue=0,
modifiedSQLExecuted=true]

主从复制

前提互备的两台 mysql 需要配置主从复制功能,

在 3302 上查询 mysql 的 order 表,发现也有这条数据,复制成功

主从切换

关闭主库

Orderhost 读操作走的是 3302 库

2019-04-01 10:08:43.845 DEBUG [$_NIOREACTOR-0-RW]
(io.mycat.server.NonBlockingSession.releaseConnection(NonBlockingSession.java:341)) -
release connection MySQLConnection [id=48, lastTime=1554113323822, user=root,
schema=zmall, old shema=zmall, borrowed=true, fromSlaveDB=false, threadId=33,
charset=latin1, txIsolation=3, autocommit=true, attachment=order{SELECT *
FROM tb_order
LIMIT 100}, respHandler=SingleNodeHandler [node=order{SELECT *
FROM tb_order
LIMIT 100}, packetId=21], host=172.16.22.119, port=3302, statusSync=null, writeQueue=0,
modifiedSQLExecuted=false]

Orderhost 写操作走的是 3302 库

2019-04-01 10:10:09.876 DEBUG [$_NIOREACTOR-0-RW]
(io.mycat.server.NonBlockingSession.releaseConnection(NonBlockingSession.java:341)) -
release connection MySQLConnection [id=48, lastTime=1554113409862, user=root,
schema=zmall, old shema=zmall, borrowed=true, fromSlaveDB=false, threadId=33,
charset=latin1, txIsolation=3, autocommit=true, attachment=order{insert into
tb_order(order_id,payment) values (6,800)}, respHandler=SingleNodeHandler
[node=order{insert into tb_order(order_id,payment) values (2,300)}, packetId=1],
host=172.16.22.119, port=3302, statusSync=null, writeQueue=0,
modifiedSQLExecuted=true]

查询 3302 order 表中存在这条记录
Mycat 高可用数据库架构搭建及读写分离,主从切换测试案例_第6张图片
恢复主库

检查主库,数据和从库保持一致
Mycat 高可用数据库架构搭建及读写分离,主从切换测试案例_第7张图片
登陆 mycat 管理端口 index 切换回原来的主库

mysql -h172.16.23.126 -P9066 -uroot -p123456

switch @@datasource host_order:0;
switch @@datasource host_goods:0;

Orderhost 读操作走的是 3302 库

69326688, user=root, schema=zmall, old shema=zmall, borrowed=true, fromSlaveDB=true,
threadId=63, charset=latin1, txIsolation=3, autocommit=true, attachment=order{SELECT *
FROM tb_order
LIMIT 100}, respHandler=SingleNodeHandler [node=order{SELECT *
FROM tb_order
LIMIT 100}, packetId=24], host=172.16.22.119, port=3302, statusSync=null, writeQueue=0,
modifiedSQLExecuted=false]

Orderhost 写操作走的是 3301 库

2019-04-02 01:40:06.835 DEBUG [$_NIOREACTOR-0-RW]
(io.mycat.server.NonBlockingSession.releaseConnection(NonBlockingSession.java:341)) -
release connection MySQLConnection [id=69, lastTime=1554169206828, user=root,
schema=zmall, old shema=zmall, borrowed=true, fromSlaveDB=false, threadId=6,
charset=latin1, txIsolation=3, autocommit=true, attachment=order{insert into
tb_order(order_id,payment) values (4,800)}, respHandler=SingleNodeHandler
[node=order{insert into tb_order(order_id,payment) values (4,800)}, packetId=1],
host=172.16.22.119, port=3301, statusSync=null, writeQueue=0,
modifiedSQLExecuted=true]

主从库都存在该条数据:
Mycat 高可用数据库架构搭建及读写分离,主从切换测试案例_第8张图片
关闭从库

2019-04-02 01:43:58.001 DEBUG [$_NIOREACTOR-0-RW]
(io.mycat.server.NonBlockingSession.releaseConnection(NonBlockingSession.java:341)) -
release connection MySQLConnection [id=69, lastTime=1554169437988, user=root,
schema=zmall, old shema=zmall, borrowed=true, fromSlaveDB=false, threadId=6,
charset=latin1, txIsolation=3, autocommit=true, attachment=order{SELECT *
FROM tb_order
LIMIT 100}, respHandler=SingleNodeHandler [node=order{SELECT *
FROM tb_order
LIMIT 100}, packetId=24], host=172.16.22.119, port=3301, statusSync=null, writeQueue=0,
modifiedSQLExecuted=false]

2019-04-02 01:44:53.628 DEBUG [$_NIOREACTOR-0-RW]
(io.mycat.server.NonBlockingSession.releaseConnection(NonBlockingSession.java:341)) -
release connection MySQLConnection [id=73, lastTime=1554169493608, user=root,
schema=zmall, old shema=zmall, borrowed=true, fromSlaveDB=false, threadId=9,
charset=latin1, txIsolation=3, autocommit=true, attachment=order{insert into
tb_order(order_id,payment) values (5,800)}, respHandler=SingleNodeHandler
[node=order{insert into tb_order(order_id,payment) values (5,800)}, packetId=1],
host=172.16.22.119, port=3301, statusSync=null, writeQueue=0,
modifiedSQLExecuted=true]

查看 3301 库的 order 表:
Mycat 高可用数据库架构搭建及读写分离,主从切换测试案例_第9张图片
恢复从库

检查从库,和主库保持一致:
Mycat 高可用数据库架构搭建及读写分离,主从切换测试案例_第10张图片

2019-04-02 01:48:16.833 DEBUG [$_NIOREACTOR-1-RW]
(io.mycat.server.NonBlockingSession.releaseConnection(NonBlockingSession.java:341)) -
release connection MySQLConnection [id=76, lastTime=1554169696828, user=root,
schema=zmall, old shema=zmall, borrowed=true, fromSlaveDB=true, threadId=5,
charset=latin1, txIsolation=3, autocommit=true, attachment=order{SELECT *
FROM tb_order
LIMIT 100}, respHandler=SingleNodeHandler [node=order{SELECT *
FROM tb_order
LIMIT 100}, packetId=25], host=172.16.22.119, port=3302, statusSync=null, writeQueue=0,
modifiedSQLExecuted=false]

2019-04-02 01:48:56.714 DEBUG [$_NIOREACTOR-1-RW]
(io.mycat.server.NonBlockingSession.releaseConnection(NonBlockingSession.java:341)) -
release connection MySQLConnection [id=74, lastTime=1554169736708, user=root,
schema=zmall, old shema=zmall, borrowed=true, fromSlaveDB=false, threadId=8,
charset=latin1, txIsolation=3, autocommit=true, attachment=order{insert into
tb_order(order_id,payment) values (7,800)}, respHandler=SingleNodeHandler
[node=order{insert into tb_order(order_id,payment) values (7,800)}, packetId=1],
host=172.16.22.119, port=3301, statusSync=null, writeQueue=0,
modifiedSQLExecuted=true]

主从库数据一致:
Mycat 高可用数据库架构搭建及读写分离,主从切换测试案例_第11张图片

你可能感兴趣的:(中间件)