天天看点

MyCat 之路 | 配置 Mysql 读写分离+强制走写节点+根据主从延时的读写分离

数据库读写分离对于大型系统或者访问量很高的互联网应用来说,是必不可少的一个重要功能。对于MySQL来说,标准的读写分离是主从模式,一个写节点Master后面跟着多个读节点,读节点的数量取决于系统的压力,通常是1-3个读节点的配置。

MyCat 之路 | 配置 Mysql 读写分离+强制走写节点+根据主从延时的读写分离

Mycat读写分离和自动切换机制,需要mysql的主从复制机制配合。

  • MyCat的安装请参考:Linux 下 Mycat 的安装配置
  • Mysql主从复制的配置请参考:MySql 主从复制的配置(GTID 方式)

一、MyCat 的配置

从 Mycat 1.4 开始支持MySQL主从复制状态绑定的读写分离机制,让读更加安全可靠,配置如下:

配置文件的意思是:

  • 逻辑库:small。逻辑表:tb_item;
  • Master服务器上创建了一个数据库:db1;
  • Slave服务器同步Master服务器的 db1 数据库;
  • 写请求都发送到Master服务器;
  • 读请求都发送到Slave服务器。
[[email protected] conf]# vim schema.xml

<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">

        <schema name="small" checkSQLschema="false" sqlMaxLimit="100">
                <table name="tb_item" dataNode="dn1" />
        </schema>
        <dataNode name="dn1" dataHost="localhost1" database="db1" />
        <dataHost name="localhost1" maxCon="1000" minCon="10" balance="1" writeType="0" dbType="mysql" dbDriver="native">
                <heartbeat>select user()</heartbeat>
                <writeHost host="hostM" url="mysql-server-01:3306" user="root" password="888888">
                        <readHost host="hostS" url="mysql-server-02:3306" user="root" password="888888" />
                </writeHost>
        </dataHost>

</mycat:schema>

           

二、测试

1、我们使用 Navicat 连接 MyCat 服务器
MyCat 之路 | 配置 Mysql 读写分离+强制走写节点+根据主从延时的读写分离
2、创建表

执行如下建表语句,执行之后可以看到Master服务器上的数据库 db1 中存在了 tb_item 表。再看看Slave服务器上的 db1 数据库中也存在了 tb_item 表。

-- ----------------------------
-- Table structure for tb_item
-- ----------------------------
DROP TABLE IF EXISTS `tb_item`;

CREATE TABLE `tb_item` (
  `id` bigint(20) NOT NULL COMMENT '商品id,同时也是商品编号',
  `title` varchar(100) NOT NULL COMMENT '商品标题',
  `sell_point` varchar(500) DEFAULT NULL COMMENT '商品卖点',
  `price` bigint(20) NOT NULL COMMENT '商品价格,单位为:分',
  `num` int(10) NOT NULL COMMENT '库存数量',
  `barcode` varchar(30) DEFAULT NULL COMMENT '商品条形码',
  `image` varchar(500) DEFAULT NULL COMMENT '商品图片',
  `cid` bigint(10) NOT NULL COMMENT '所属类目,叶子类目',
  `status` tinyint(4) NOT NULL DEFAULT '1' COMMENT '商品状态,1-正常,2-下架,3-删除',
  `created` datetime NOT NULL COMMENT '创建时间',
  `updated` datetime NOT NULL COMMENT '更新时间',
  PRIMARY KEY (`id`),
  KEY `cid` (`cid`),
  KEY `status` (`status`),
  KEY `updated` (`updated`)
) COMMENT='商品表';
                
3、从插入数据
INSERT INTO TB_ITEM (
	ID,
	TITLE,
	SELL_POINT,
	PRICE,
	NUM,
	BARCODE,
	IMAGE,
	CID,
	STATUS,
	CREATED,
	UPDATED
)
VALUES
	(
		'15000000',
		'夏普(SHARP)LCD-52DS51A 52英寸 日本原装液晶面板 内置WIFI智能全高清液晶电视',
		'要好屏,选夏普!日本原装面板,智能电视,高画质高音质!<a  target=\"blank\"  href=\"http://item.jd.com/1278664.html\">还有升级版安卓智能新机52DS52供您选择!</a>',
		'549900',
		'99999',
		NULL,
		'http://image.taotao.com/jd/63af01c37a18454ab2fef4670046272e.jpg',
		'76',
		'1',
		'2015-03-08 21:27:45',
		'2015-03-08 21:27:45'
	);
                
4、测试读写分离
MyCat 之路 | 配置 Mysql 读写分离+强制走写节点+根据主从延时的读写分离

附 1、读写分离的第二种配置方式

1、读写分离的第二种配置方式
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">

        <schema name="small" checkSQLschema="false" sqlMaxLimit="100">
                <table name="tb_item" dataNode="dn1" />
        </schema>
        
        <dataNode name="dn1" dataHost="localhost1" database="db1" />
        <dataHost name="localhost1" maxCon="1000" minCon="10" balance="1" writeType="0" dbType="mysql" dbDriver="native">
			<heartbeat>select user()</heartbeat>
			<writeHost host="hostM1" url="mysql-server-01:3306" user="root" password="888888"></writeHost>
			<writeHost host="hostS1" url="mysql-server-02:3306" user="root" password="888888"></writeHost>
		</dataHost>

</mycat:schema>
           

以上两种配置方式,第一种当写挂了读不可用,第二种可以继续使用。另外,事务内部的一切操作都会走写节点,所以读操作不要加事务。

2、强制走写或读节点

如果读延时较大,我们可以使用MyCat注解的方式强制走写节点。

继续上面测试部分的第四小节:测试读写分离。接下来测试MyCat的注解方式。

MyCat 之路 | 配置 Mysql 读写分离+强制走写节点+根据主从延时的读写分离

图中可能看不清楚,强制走写节点的语句如下:

/*#mycat:db_type=master*/ SELECT * FROM tb_item ;
                

另外,测试时发现强制走读节点失败,不知道为什么,也没有深究(实在没有多少时间):

/*#mycat:db_type=slave*/ SELECT * FROM tb_item ;
                

附 2、根据主从延时切换

1、根据主从延时切换的配置

1.4 开始支持 MySQL 主从复制状态绑定的读写分离机制,让读更加安全可靠,配置如下:

  1. MyCAT 心跳检查语句配置为 show slave status ;
  2. 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 时则表示主从同步,可以安全切换,否则不会切换。

<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">

        <schema name="small" checkSQLschema="false" sqlMaxLimit="100">
                <table name="tb_item" dataNode="dn1" />
        </schema>
        <dataNode name="dn1" dataHost="localhost1" database="db1" />
        
		<dataHost name="localhost1" maxCon="1000" minCon="10" balance="0" writeType="0" 
							dbType="mysql" dbDriver="native" switchType="2" slaveThreshold="100">
			<heartbeat>show slave status </heartbeat>
			<writeHost host="hostM1" url="mysql-server-01:3306" user="root" password="888888"></writeHost>
			<writeHost host="hostS1" url="mysql-server-02:3306" user="root" password="888888"></writeHost>
		</dataHost>

</mycat:schema>
           
2、测试

将主节点(写节点)停止,再插入一条数据,可以看到是可以插入的,此时写节点已经关闭,读节点出现了俩条数据:

MyCat 之路 | 配置 Mysql 读写分离+强制走写节点+根据主从延时的读写分离
MyCat 之路 | 配置 Mysql 读写分离+强制走写节点+根据主从延时的读写分离

另外,注意:将主节点重新启动,MyCat 不会重新将其加入进来。(已亲自试验)

官方文档中有这么一段:

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

继续阅读