MyCAT读写分离
更新日期:
MyCAT的一个典型应用是用于数据库的读写分离,本文以Mysql为例,展示读写分离的MyCAT应用场景。本次操作使用的是Ubuntu14.04。
安装Mysql主从复制
本文仅仅展示最简单的Mysql主从复制配置,实际使用中应该会更加复杂。
先配置主Mysql,先要修改/etc/mysql/my.cnf
文件,
然后重启主Mysql,并登陆,运行以下命令,
以上命令表示我们是用root用户镜像主从复制,实际使用中应该会使用其他用户。
主Mysql的配置比较简单,从Mysql的配置稍微麻烦一点。先修改/etc/mysql/my.cnf
文件,
注意,server-id一定不能与主Mysql相同,这是表示服务器的唯一id。然后重启从Mysql,登陆,运行如下命令,
注意,以上命令中的master_log_file='mysql-bin.000007',master_log_pos=429
要与主Mysql中的show master status
结果一致。另外,如果配置change master
的时候配置错了,需要先运行stop slave
停止slave,再运行reset slave
清空slave的配置,然后再从头开始配置。
配置完成之后,在主Mysql上进行create database可以同步到从Mysql。按MyCAT测试库的案例,创建db1、db2、db3三个数据库。
MyCAT配置主从复制
MyCAT主从复制的配置主要修改schema.xml
文件,修改如下,
对比原文件如下,
修改了以下几个地方,
- 删除了writehost hostS1;
- 增加了writehost hostM1下的一个readHost hostS;
- 修改了dataHost的几个参数,
balance="1" writeType="0" switchType="2" slaveThreshold="100"
; - 修改了检测心跳的方法为
show slave status
;
(1) 设置 balance="1"与writeType="0"
Balance参数设置:
- balance=“0”, 所有读操作都发送到当前可用的writeHost上。
- balance=“1”,所有读操作都随机的发送到readHost。
- balance=“2”,所有读操作都随机的在writeHost、readhost上分发
WriteType参数设置:
- writeType=“0”, 所有写操作都发送到可用的writeHost上。
- writeType=“1”,所有写操作都随机的发送到readHost。
- writeType=“2”,所有写操作都随机的在writeHost、readhost分上发。
“readHost是从属于writeHost的,即意味着它从那个writeHost获取同步数据,因此,当它所属的writeHost宕机了,则它也不会再参与到读写分离中来,即“不工作了”,这是因为此时,它的数据已经“不可靠”了。基于这个考虑,目前mycat 1.3和1.4版本中,若想支持MySQL一主一从的标准配置,并且在主节点宕机的情况下,从节点还能读取数据,则需要在Mycat里配置为两个writeHost并设置banlance=1。”
(2) 设置 switchType="2" 与slaveThreshold="100"
“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主从复制时延。“
配置好之后,即可运行mycat start
启动MyCAT。
测试MyCAT主从复制
在MyCAT上运行建表和插入语句,
分别在主从数据库上查看,
可以看到,数据已经在主从Mysql上都存在。
如果想看更多的MyCAT处理细节,需要打开debug级别的log,修改log4j.xml
,
修改后,重启mycat,然后运行sql,select * from company where id = 100;
,在mycat/logs/mycat.log
中可以看到以下结果,
可以发现mycat实际上是从hostS上读取数据,查看从Mysql的状态,如下,
上图最后一行显示,Seconds_Behind_Master是0,按MyCAT文档中的说法,此时的确是要去读hostS。
MyCAT自动切换
在主Mysql突然断线的时候,MyCAT会自动将连接转到从Mysql上,在从Mysql上读取数据。根据MyCAT文档中的说法,这种情况下不能设置一写一读两个主机,而要设置两个写主机。略微修改schema.xml
如下,
几乎与之前的配置相同,只是将readHost改为writeHost,与原先的hostM1并列。
重启MyCAT,再次运行select * from company where id = 100;
,发现log中,仍然是从hostS上查询,与之前相同;运行insert into company(id, name) values (200, 'xyz');
,发现log中,也仍然是从hostM1上插入,与之前相同。插入时的log如下,
因此,可以判断,在该配置下,在Mysql没有宕机的时候,与之前一写一读的配置情况一样。此时,模拟Mysql宕机,再次运行查询select * from company where id = 100;
,发现log如下,
与之前的查询完全相同,运行insert into company(id, name) values (300, 'def');
,log如下,
此时的插入语句已经自动转到hostS上,说明此时的从Mysql已经取代主Mysql。此时,恢复主Mysql,发现所有的查询和插入也仍然是从hostS上走,相当于主Mysql没有在集群中。这种配置虽然简单,但系统的可靠性很差,建议使用多个主Mysql的集群,如Galera。
关于分库和分表
MyCAT主要完成了Mysql集群的水平分库问题。其中水平分库是说,把一个大表按行进行拆分,放在多个数据库中,比如,id为1~100万的在A库,100w~200w的在B库,以此类推。将大表进行水平拆分还有一种方法是水平分表,指的是,仍然按行进行拆分,但是放在一个数据库的多个表中,比如,id为1~100万的在A表,100w~200w的在B表,以此类推。表的水平拆分大致是这两种方法。
水平分表拆分的优点是,仍然是一个数据库,管理成本较低,集群方案等都与单库无差异,而且事务特性支持好,没有跨库的分布式事务问题;缺点是,由于本质上仍然是单个数据库,无法突破单个数据库实例上的CPU、内存、IO等硬件资源限制,性能提升并不会很明显。虽然,Oracle可以通过设置多个表空间来达到突破IO瓶颈的问题,Mysql也逐渐开始支持表空间特性,但是,CPU、内存仍然局限在一台服务器上,无法获得扩展。
水平分库拆分的优点是,引入了多个数据库,这些数据库可以放在多台服务器上,硬件资源扩展性理论上是无限的,性能提升会比较显著。缺点是,由于引入了多个数据库,管理成本提高,需要引入自动化工具,而且,事务特性会比较受限,因为多个数据库之间必然会存在分布式事务问题,这个问题一般都很难解决,也很难做到与单库上完全一致的事务特性,或者限制开发中分布式事务的使用,这对业务实现也不利。