Mycat实现mysql读写分离及故障切换

1.1 相关参数介绍

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

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

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

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

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

注意:balance=3只在1.4及其以后版本有,1.3没有。 

writeType属性:

1.writeType=”0”,所有写操作发送到配置的第一个writeHost,第一个挂了切到还生存的第二个writeHost,重新启动后以切换后的为准,切换记录在配置文件中:dnindex.properties.

2.writeType=”1”,所有写操作都随机地发送到配置的writeHost,1.5以后废弃不推荐。 

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

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

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

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

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

注意:估计Mycat 1.4才开始支持switchType。1.3版本配置该属性的话,日志里会报错:org.xml.sax.SAXParseException;lineNumber: 61; columnNumber: 86; Attribute "switchType" must bedeclared for element type "dataHost"。

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时则表示主仅同步,可安全切换,否则不会切换。

1.2 实验环境

双主复制:

10.192.203.201(hostname:PC)

10.192.203.202(hostname:slave2)

Mycat安装在10.192.203.202上。

1.3 实验步骤

本实验打算实现的功能:

只往10.192.203.201写,在10.192.203.202上读。且当10.192.203.201宕机时,自动切换到10.192.203.202上。

1.3.1 修改配置文件

cd /usr/local/mycat/conf

vi schema.xml

这里选择:balance="1",writeType=”0”,switchType='1'

dataHost处之前配置了只连接10.192.203.201mysql的用户名密码等信息:

现在配置读写分离相关设置。

修改后:

登录9066端口,使得配置生效:reload @@config_all;

1.3.2 验证读写分离

#验证是否写入到第一个配置的writeHost

连接mycat:

mysql -utest -ptest -h127.0.0.1 -P8066 -DUSERDB

操作之前配置过的一个表customer。

插入三条数据:
mysql> insert into customer(id,name) values(1,@@hostname),(1005,@@hostname),(2004,@@hostname);
Query OK, 3 rows affected (0.03 sec)
mysql> select * from customer where id in(1,1005,2004);
+------+------+
| ID  | NAME |
+------+------+
| 2004 | PC   |
| 1005 | PC   |
|   1 | PC   |
+------+------+
3 rows in set (0.03 sec)
说明数据插入到了10.192.203.201上了。
现在,主从都能查看到新插入的数据:
mysql> select * from db10.customer;
+------+------+
| ID  | NAME |
+------+------+
|   1 | PC   |
| 999 | dan  |
| 1000 | jiao |
+------+------+
3 rows in set (0.00 sec)
 
mysql> select * from db11.customer;
+------+------+
| ID  | NAME |
+------+------+
| 1003 | song |
| 1005 | PC   |
+------+------+
2 rows in set (0.01 sec)
 
mysql> select * from db12.customer;
+------+------+
| ID  | NAME |
+------+------+
| 2002 | yang |
| 2004 | PC   |
+------+------+
2 rows in set (0.00 sec)

#验证读自哪台机器

这里通过模拟主从数据不一致(停止slave,更新一些数据),来验证是从哪个节点读的。

停止10.192.203.201上的从库,在10.192.203.202上更新其中一条数据

10.192.203.201:
mysql> stop slave;
Query OK, 0 rows affected (0.02 sec)
10.192.203.202:
mysql> update db12.customer setname='slave2' where id= 2004;
Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1 Warnings: 0
mysql> update db11.customer setname='slave2' where id= 1005;
Query OK, 1 row affected (0.02 sec)
Rows matched: 1  Changed: 1 Warnings: 0
mysql> update db10.customer setname='slave2' where id= 1;
Query OK, 1 row affected (0.02 sec)
Rows matched: 1  Changed: 1 Warnings: 0
mysql> select * from db12.customer;
+------+--------+
| ID   | NAME  |
+------+--------+
| 2002 | yang   |
| 2004 | slave2 |
+------+--------+
2 rows in set (0.00 sec)
 
再在mycat上查询:
mysql> select * from customer where id in(1,1005,2004);
+------+--------+
| ID  | NAME   |
+------+--------+
| 2004 | slave2 |
| 1005 | slave2 |
|   1 | slave2 |
+------+--------+
3 rows in set (0.19 sec)

说明是从10.192.203.202上读的。因为我们配置的balance为1,所以会在全部的readHost与stand by writeHost上读。

1.3.3 验证mycat是否自动切换

模拟10.192.203.201库宕机
[root@PC ~]# service mysql stop
Shutting down MySQL.... SUCCESS!
在mycat上插入几条数据,验证是否切换到了在10.192.203.202上插入。
mysql> insert into customer(id,name)values(2,@@hostname);
Query OK, 1 row affected (0.05 sec)
mysql> select * from customer where id =2;
+----+--------+
| ID | NAME   |
+----+--------+
|  2| slave2 |
+----+--------+
1 row in set (0.03 sec)
说明切换成功。
主宕机后,读写都在从上进行。
切换后,Mycat会标记新的主从状态,主从状态保存在/conf/dnindex.properties文件
[root@slave2 conf]# cat dnindex.properties
#update
#Wed Aug 31 19:11:27 CST 2016
localhost1=1
现在localhost1值为1,切换前值为0. 

#当原来的主10.192.203.201启动后,验证读写是在哪台机器上

#验证写
[root@PC ~]# service mysql start
Starting MySQL... SUCCESS!
在mycat上插入塑胶:
mysql> insert into customer(id,name) values(3,@@hostname);
Query OK, 1 row affected (0.02 sec) 
mysql> select * from customer where id =3;
+----+--------+
| ID | NAME   |
+----+--------+
|  3| slave2 |
+----+--------+
1 row in set (0.02 sec)
看来原来的主再启动时,默认写还是在之前的从,即后来的主上面。
#验证读
关闭10.192.203.201上的从库,在10.192.203.202上做更新,看下是在哪台机器上读的:
10.192.203.201:
mysql> stop slave;
Query OK, 0 rows affected (0.01 sec)
10.192.203.202:
mysql> update db10.customer setname='PC' where id=3;
Query OK, 1 row affected (0.02 sec)
Rows matched: 1  Changed: 1 Warnings: 0
mysql> select * from db10.customer where id = 3;
+----+------+
| ID | NAME |
+----+------+
|  3| PC   |
+----+------+
1 row in set (0.00 sec)
在10.192.203.201上查询,还是原来的‘slave2’:
mysql> select * from db10.customer where id = 3;
+----+--------+
| ID | NAME   |
+----+--------+
|  3| slave2 |
+----+--------+
1 row in set (0.00 sec)
在mycat上查询:
mysql> select * from customer where id =3;
+----+--------+
| ID | NAME   |
+----+--------+
|  3| slave2 |
+----+--------+
1 row in set (0.02 sec)
在10.192.203.201上启动slave,再在mycat上查询,name又变成了PC(因为10.192.203.202上的更新同步到了10.192.203.201上)
mysql> select * from customer where id =3;
+----+------+
| ID | NAME |
+----+------+
|  3| PC   |
+----+------+
1 row in set (0.02 sec)

说明主从切换后,写在10.192.203.202上写,读在10.192.203.201上读。

怎样再切换回来呢?关闭10.192.203.202库即可(确保10.192.203.201已启动)

[root@slave2 conf]# cat dnindex.properties
#update
#Wed Aug 31 19:56:08 CST 2016
localhost1=0
mysql> insert into customer(id,name)values(4,@@hostname);
Query OK, 1 row affected (0.03 sec) 
mysql> select * from customer where id =4;
+----+------+
| ID | NAME |
+----+------+
|  4| PC   |
+----+------+
1 row in set (0.02 sec)

说明现在已经切换到了原来的主。 

对于mycat自身的高可用,官方建议是采用基于硬件的负载均衡器或者软件形式的HAproxy

注意:

我发现当switchType为2时,不能实现读写分离,读写都是在主节点上,即使设置了balance=1.

writeHost里面配置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也不能提供服务

本篇文章参考了:

http://www.myexception.cn/mysql/2031976.html

http://www.linuxidc.com/Linux/2016-01/127555.htm

展开阅读全文

没有更多推荐了,返回首页