在MySQL中间件出现之前,对于MySQL主从集群,如果要实现其读写分离,一般是在程序端实现,这样就带来一个问题,即数据库和程序的耦合度太高,如果我数据库的地址发生改变了,那么我程序端也要进行相应的修改,如果数据库不小心挂掉了,则同时也意味着程序的不可用,而这对很多应用来说,并不能接受。

引入MySQL中间件能很好的对程序端和数据库进行解耦,这样,程序端只需关注数据库中间件的地址,而无需知晓底层数据库是如何提供服务。

作为当前炙手可热的MySQL中间件,MyCAT实现MySQL主从集群的读写分离自是应有之义,其配置也相当简单。

在这里,我用三个实例组成MySQL主从集群,来验证MyCAT的读写分离功能,其实,一主一从就可以满足,之所以用三个,是为了验证MyCAT的分片功能。

集群组成如下:

角色             主机名                      主机IP

master         mysql-server1          192.168.244.145

slave            mysql-server2          192.168.244.146

slave            mysql-server3          192.168.244.144

在这里,还是使用Travelrecord表进行测试。

首先编辑MyCAT的配置文件schema.xml,关于dataHost的配置信息如下:

<dataHost name="localhost1" maxCon="1000" minCon="10" balance="1"
writeType="0" dbType="mysql" dbDriver="native" switchType="-1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<!-- can have multi write hosts -->
<writeHost host="hostM1" url="localhost:3306" user="root"
password="123456">
</writeHost>
<writeHost host="hostS1" url="192.168.244.146:3306" user="root"
password="123456" />
<writeHost host="hostS2" url="192.168.244.144:3306" user="root"
password="123456" />
</dataHost>

这里面,有两个参数需要注意,balance和 switchType。

其中,balance指的负载均衡类型,目前的取值有4种:

1. balance="0", 不开启读写分离机制,所有读操作都发送到当前可用的writeHost上。

2. balance="1",全部的readHost与stand by writeHost参与select语句的负载均衡,简单的说,当双主双从模式(M1->S1,M2->S2,并且M1与 M2互为主备),正常情况下,M2,S1,S2都参与select语句的负载均衡。

3. balance="2",所有读操作都随机的在writeHost、readhost上分发。

4. balance="3",所有读请求随机的分发到wiriterHost对应的readhost执行,writerHost不负担读压力

switchType指的是切换的模式,目前的取值也有4种:

1. switchType='-1' 表示不自动切换

2. switchType='1' 默认值,表示自动切换

3. switchType='2' 基于MySQL主从同步的状态决定是否切换,心跳语句为 show slave status

4. switchType='3'基于MySQL galary cluster的切换机制(适合集群)(1.4.1),心跳语句为 show status like 'wsrep%'。

因此,该配置文件中的balance="1"意味着作为stand by writeHost的hostS1和hostS2将参与select语句的负载均衡,这就实现了主从的读写分离,switchType='-1'意味着当主挂掉的时候,不进行自动切换,即hostS1和hostS2并不会被提升为主,仍只提供读的功能。这就避免了将数据写进slave的可能性,毕竟,单纯的MySQL主从集群并不允许将数据读进slave中,除非配置的是双master。

验证读写分离

下面来验证一下,

创建Travelrecord表

create table travelrecord (id bigint not null primary key,user_id varchar(100),traveldate DATE, fee decimal,days int);

插入数据

mysql> insert into travelrecord(id,user_id,traveldate,fee,days)  values(1,@@hostname,20160101,100,10);
Query OK, 1 row affected, 1 warning (0.02 sec) mysql> insert into travelrecord(id,user_id,traveldate,fee,days) values(5000001,@@hostname,20160102,100,10);
Query OK, 1 row affected, 1 warning (0.01 sec)

在这里,用了一个取巧的方法,即对user_id插入了当前实例的主机名,这样可直观的观察读写是否分离以及MyCAT的分片功能。能这样做的原因在于我当前的MySQL版本-5.6.26默认是基于statement的复制,如果是基于row的复制,则这个方法将不可取。

查询数据

mysql> select * from travelrecord;
+---------+---------------+------------+------+------+
| id | user_id | traveldate | fee | days |
+---------+---------------+------------+------+------+
| 1 | mysql-server2 | 2016-01-01 | 100 | 10 |
| 5000001 | mysql-server3 | 2016-01-02 | 100 | 10 |
+---------+---------------+------------+------+------+
2 rows in set (0.01 sec) mysql> select * from travelrecord;
+---------+---------------+------------+------+------+
| id | user_id | traveldate | fee | days |
+---------+---------------+------------+------+------+
| 5000001 | mysql-server3 | 2016-01-02 | 100 | 10 |
| 1 | mysql-server2 | 2016-01-01 | 100 | 10 |
+---------+---------------+------------+------+------+
2 rows in set (0.02 sec) mysql> select * from travelrecord;
+---------+---------------+------------+------+------+
| id | user_id | traveldate | fee | days |
+---------+---------------+------------+------+------+
| 5000001 | mysql-server3 | 2016-01-02 | 100 | 10 |
| 1 | mysql-server3 | 2016-01-01 | 100 | 10 |
+---------+---------------+------------+------+------+
2 rows in set (0.01 sec) mysql> select * from travelrecord;
+---------+---------------+------------+------+------+
| id | user_id | traveldate | fee | days |
+---------+---------------+------------+------+------+
| 5000001 | mysql-server3 | 2016-01-02 | 100 | 10 |
| 1 | mysql-server3 | 2016-01-01 | 100 | 10 |
+---------+---------------+------------+------+------+
2 rows in set (0.01 sec) mysql> select * from travelrecord;
+---------+---------------+------------+------+------+
| id | user_id | traveldate | fee | days |
+---------+---------------+------------+------+------+
| 1 | mysql-server2 | 2016-01-01 | 100 | 10 |
| 5000001 | mysql-server2 | 2016-01-02 | 100 | 10 |
+---------+---------------+------------+------+------+

从上面的输出结果,可以得出以下两点:

一、该配置已实现读写分离,读出来的数据没有master节点的。

二、MyCAT的随机分发不是基于statement的,即一个select语句查询其中一个节点,另外一个select语句查询另外一个节点。它分发针对的是片的,同一个select语句的结果是有不同dataNode返回的。

不仅如此,从MyCAT日志中也可以获取读写分离的相关信息,当然,前提是MyCAT的日志级别是debug。日志相关信息如下:

验证mater挂了,slave还能提供读的功能

对于MySQL主从集群,我们的需求是master挂了,slave还能提供读的功能。

下面来测试一下

首先,人为的关闭主库

[root@mysql-server1 ~]# /etc/init.d/mysqld stop

登录MyCAT

[root@mysql-server1 ~]# mysql -utest -ptest -h127.0.0.1 -P8066 -DTESTDB

插入数据

mysql> insert into travelrecord(id,user_id,traveldate,fee,days)  values(10000001,@@hostname,20160103,100,10);
ERROR 1184 (HY000): Connection refused
mysql> select * from travelrecord;
+---------+---------------+------------+------+------+
| id | user_id | traveldate | fee | days |
+---------+---------------+------------+------+------+
| 1 | mysql-server2 | 2016-01-01 | 100 | 10 |
| 5000001 | mysql-server3 | 2016-01-02 | 100 | 10 |
+---------+---------------+------------+------+------+
2 rows in set (0.02 sec)

可见无法插入数据,但不影响读取数据。

至此,MyCAT实现MySQL的读写分离部署测试完毕。

总结:

1. 其实,刚开始配置的是readHost节点,配置如下:

 <dataHost name="localhost1" maxCon="1000" minCon="10" balance="1"
writeType="0" dbType="mysql" dbDriver="native" switchType="-1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<!-- can have multi write hosts -->
<writeHost host="hostM1" url="localhost:3306" user="root"
password="123456">
<!-- can have multi read hosts -->
<readHost host="hostS1" url="192.168.244.146:3306" user="root" password="123456" />
</writeHost>
</dataHost>

但这种方式有个问题,即master挂了以后,slave也不能提供服务,而这违反了MySQL主从集群的初衷。

2. 如果开启了事务模式,即set autocommit=0,则事务内的读走的是master节点,而不是从节点。

MyCAT实现MySQL的读写分离的更多相关文章

  1. 通过mycat实现mysql的读写分离

    mysql的主从配置沿用上一篇博客的配置:https://www.cnblogs.com/MasterSword/p/9434169.html mycat下载地址:http://www.mycat.i ...

  2. 利用mycat实现mysql数据库读写分离

    1.这里是在mysql主从复制实现的基础上,利用mycat做读写分离,架构图如下: 2.Demo 2.1 在mysql master上创建数据库创建db1 2.2 在数据库db1创建表student ...

  3. Mycat实现Mysql主从读写分离

    一.概述 关于Mycat的原理网上有很多,这里不再详述,对于我来说Mycat的功能主要有如下几种: 1.Mysql主从的读写分离 2.Mysql大表分片 3.其他数据库例如Oracle,MSSQL,D ...

  4. Mycat实现mysql主从复制(读写分离)

    数据库性能瓶颈主要原因: 随着用户数的增多,带来的是数据库连接的大幅度增长 随着业务体量的增长,表数据量(空间存储的问题)的大幅增长,其中涉及到索引的优化,mysql默认的索引是硬盘级别的,BTREE ...

  5. Mycat实现Mysql数据库读写分离

    Linux和Windows环境下搭建Mycat数据读写分离 前提需要:1.服务器装有JVM虚拟机,就是JDK.2.两个Mysql数据库已经实现主从复制,参考:https://www.cnblogs.c ...

  6. mycat配置MySQL主从读写分离

    1.安装java 1.8 mycat 1.6要求的Java需要Java 1.8或1.8以上,安装Java参考以下链接: https://blog.csdn.net/weixin_43893397/ar ...

  7. MyCAT部署及实现读写分离(转)

    MyCAT是mysql中间件,前身是阿里大名鼎鼎的Cobar,Cobar在开源了一段时间后,不了了之.于是MyCAT扛起了这面大旗,在大数据时代,其重要性愈发彰显.这篇文章主要是MyCAT的入门部署. ...

  8. Mycat - 实现数据库的读写分离与高可用

    前言 开心一刻 上语文课,不小心睡着了,坐在边上的同桌突然叫醒了我,并小声说道:“读课文第三段”.我立马起身大声读了起来.正在黑板写字的老师吓了一跳,老师郁闷的看着我,问道:“同学有什么问题吗?”,我 ...

  9. 应用集成mycat,实现mycat的高可用与mysql的读写分离

    前言 开心一刻 一个女人自朋友圈写道:我家老公昨天和别人家的老婆出去旅游,迄今未归,我则被别人家的老公折腾了一天,好累哦! 圈子下面,评论无数,老公在下面评论到:能不能好好说话,我只不过陪女儿去毕业旅 ...

随机推荐

  1. python中__init__问题

    python中安装目录中的Lib文件夹模块中的__init__.py文件(文件内容可以为空),用于标识此文件夹是一个模块 python编程中的__init__表示初始化

  2. Javascript初学篇章_8(事件)

    事件 HTML 事件是发生在 HTML 元素上的事情.例如用户点击按钮时,点击也是一个事件.事件可以用于处理表单验证,用户输入,用户行为及浏览器动作,如: 页面加载时触发事件 页面关闭时触发事件 用户 ...

  3. 学习JavaScript闭包

    作者: 阮一峰 日期: 2009年8月30日 闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现. 下面就是我的学习笔记,对于Javascript初 ...

  4. checkbox选中状态不被改变

    让它的状态只能看不能改变,加上onclick="return false;". 也可以disabled="true";但是这个颜色变淡了; <input ...

  5. Oracle EBS - Doc

    Oracle EBS spec.: http://vianet/IT/IT%20Dept/IT%20Project%20Update2/Active%20Projects%20%20Manufactu ...

  6. Third Day(上班第四天):Android开发环境配置问题相关

    换公司新电脑了,重新安装Android开发环境,并配置,具体流程如下:1.百度JDK,访问Oracle官网:http://www.oracle.com/technetwork/java/javase/ ...

  7. iOS开发点滴:iPhone屏幕适配

    最近开始做iOS开发,遇到一些小问题和解决方法,记录下.   今天是iPhone屏幕适配 iPhone5出来之后屏幕就有iPhone就有了2种尺寸:3.5寸和4寸,xcode 5 的IB设计器里面界面 ...

  8. .NET垃圾回收 – 原理浅析

    在开发.NET程序过程中,由于CLR中的垃圾回收(garbage collection)机制会管理已分配的对象,所以程序员就可以不用关注对象什么时候释放内存空间了.但是,了解垃圾回收机制还是很有必要的 ...

  9. 将nuget与VS直接集成,实现一键上传等功能

    nuget是一个非常方便的包管理工具,很多团队为了开发的方便也建立了自己的包源网站(nuget.server),本篇文章是笔者在配置nuget上面的一点小体,其最终目标是要达到能够在VS里一键打包上传 ...

  10. Java批处理ExecutorService/CompletionService

    服务端接收一个请求,常常需要同时进行几个计算或者向其他服务发送请求,最后拼装结果返回上游.本文就来看下JDK提供几个并行处理方案,牵涉到ExcecutorService/CompletionServi ...